ng-prime-tools 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +28 -16
  2. package/esm2022/lib/models/card-config.model.mjs +1 -1
  3. package/esm2022/lib/models/login-page-config.model.mjs +1 -1
  4. package/esm2022/lib/models/table-column.model.mjs +1 -1
  5. package/esm2022/lib/ng-prime-tools.module.mjs +8 -8
  6. package/esm2022/lib/{ng-advanced-prime-table → pt-advanced-prime-table}/index.mjs +1 -1
  7. package/esm2022/lib/pt-advanced-prime-table/pt-advanced-prime-table.component.mjs +353 -0
  8. package/esm2022/lib/{ng-advanced-prime-table/ng-advanced-prime-table.module.mjs → pt-advanced-prime-table/pt-advanced-prime-table.module.mjs} +10 -10
  9. package/esm2022/lib/{ng-advanced-prime-table → pt-advanced-prime-table}/public-api.mjs +3 -3
  10. package/esm2022/lib/pt-card/pt-card.component.mjs +44 -3
  11. package/esm2022/lib/pt-login-page/pt-login-card/pt-login-card.component.mjs +147 -0
  12. package/esm2022/lib/pt-login-page/pt-login-page.component.mjs +35 -126
  13. package/esm2022/lib/pt-login-page/pt-login-page.module.mjs +7 -3
  14. package/esm2022/lib/pt-menu-fancy/pt-menu-fancy.component.mjs +8 -4
  15. package/esm2022/public-api.mjs +2 -2
  16. package/fesm2022/ng-prime-tools.mjs +155 -58
  17. package/fesm2022/ng-prime-tools.mjs.map +1 -1
  18. package/lib/models/card-config.model.d.ts +4 -0
  19. package/lib/models/card-config.model.d.ts.map +1 -1
  20. package/lib/models/login-page-config.model.d.ts +5 -1
  21. package/lib/models/login-page-config.model.d.ts.map +1 -1
  22. package/lib/models/table-column.model.d.ts +1 -0
  23. package/lib/models/table-column.model.d.ts.map +1 -1
  24. package/lib/ng-prime-tools.module.d.ts +2 -2
  25. package/lib/pt-advanced-prime-table/index.d.ts.map +1 -0
  26. package/lib/{ng-advanced-prime-table/ng-advanced-prime-table.component.d.ts → pt-advanced-prime-table/pt-advanced-prime-table.component.d.ts} +5 -4
  27. package/lib/{ng-advanced-prime-table/ng-advanced-prime-table.component.d.ts.map → pt-advanced-prime-table/pt-advanced-prime-table.component.d.ts.map} +1 -1
  28. package/lib/{ng-advanced-prime-table/ng-advanced-prime-table.module.d.ts → pt-advanced-prime-table/pt-advanced-prime-table.module.d.ts} +6 -6
  29. package/lib/pt-advanced-prime-table/pt-advanced-prime-table.module.d.ts.map +1 -0
  30. package/lib/pt-advanced-prime-table/public-api.d.ts +3 -0
  31. package/lib/{ng-advanced-prime-table → pt-advanced-prime-table}/public-api.d.ts.map +1 -1
  32. package/lib/pt-card/pt-card.component.d.ts +25 -0
  33. package/lib/pt-card/pt-card.component.d.ts.map +1 -1
  34. package/lib/pt-login-page/pt-login-card/pt-login-card.component.d.ts +18 -0
  35. package/lib/pt-login-page/pt-login-card/pt-login-card.component.d.ts.map +1 -0
  36. package/lib/pt-login-page/pt-login-page.component.d.ts +5 -10
  37. package/lib/pt-login-page/pt-login-page.component.d.ts.map +1 -1
  38. package/lib/pt-login-page/pt-login-page.module.d.ts +2 -1
  39. package/lib/pt-login-page/pt-login-page.module.d.ts.map +1 -1
  40. package/lib/pt-menu-fancy/pt-menu-fancy.component.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/public-api.d.ts +1 -1
  43. package/esm2022/lib/ng-advanced-prime-table/ng-advanced-prime-table.component.mjs +0 -351
  44. package/lib/ng-advanced-prime-table/index.d.ts.map +0 -1
  45. package/lib/ng-advanced-prime-table/ng-advanced-prime-table.module.d.ts.map +0 -1
  46. package/lib/ng-advanced-prime-table/public-api.d.ts +0 -3
  47. /package/lib/{ng-advanced-prime-table → pt-advanced-prime-table}/index.d.ts +0 -0
@@ -0,0 +1,353 @@
1
+ import { Component, Input, Output, ViewChild } from '@angular/core';
2
+ import { EventEmitter } from '@angular/core';
3
+ import { TableTypeEnum } from '../../public-api';
4
+ import { calculateTextWidth } from '../utils/text.util';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/common";
7
+ import * as i2 from "primeng/table";
8
+ import * as i3 from "primeng/api";
9
+ import * as i4 from "primeng/inputtext";
10
+ import * as i5 from "primeng/button";
11
+ import * as i6 from "primeng/calendar";
12
+ import * as i7 from "@angular/forms";
13
+ import * as i8 from "primeng/multiselect";
14
+ import * as i9 from "primeng/tag";
15
+ import * as i10 from "primeng/iconfield";
16
+ import * as i11 from "primeng/inputicon";
17
+ import * as i12 from "../pipes/custom-currency";
18
+ import * as i13 from "../pipes/custom-date.pipe";
19
+ export class PTAdvancedPrimeTableComponent {
20
+ constructor() {
21
+ // Inputs
22
+ this.data = [];
23
+ this.columns = [];
24
+ this.totalRecords = 0;
25
+ this.rowsPerPage = [];
26
+ this.hasSearchFilter = false;
27
+ this.hasExportExcel = false;
28
+ this.hasExportPDF = false;
29
+ this.hasColumnFilter = false;
30
+ this.isPaginated = false;
31
+ this.actions = [];
32
+ this.isSortable = false;
33
+ this.loading = false;
34
+ this.maxHeight = null;
35
+ // Outputs: Events emitted to the parent component
36
+ this.filter = new EventEmitter();
37
+ this.search = new EventEmitter();
38
+ this.exportExcelEvent = new EventEmitter();
39
+ this.exportPdfEvent = new EventEmitter();
40
+ this.searchValue = '';
41
+ this.validCurrencyCodes = ['USD', 'EUR', 'MAD'];
42
+ this.iconWidth = 77;
43
+ // Component state properties
44
+ this.isDelete = false;
45
+ this.isEdit = false;
46
+ this.rows = 0;
47
+ // Data management properties
48
+ this.dataMap = new Map();
49
+ this.map = new Map();
50
+ this.optionEntries = new Map();
51
+ this.optionValues = [];
52
+ this.globalFilterFields = [];
53
+ // CRUD operation handlers
54
+ this.Delete = () => { };
55
+ this.initEditableRow = () => { };
56
+ this.saveEditableRow = () => { };
57
+ this.cancelEditableRow = () => { };
58
+ this.hasGroupedColumns = false;
59
+ }
60
+ ngOnInit() {
61
+ this.hasGroupedColumns = this.columns.some((col) => col.children && col.children.length > 0);
62
+ // Transform the date fields based on column metadata
63
+ this.data = this.formatingDateFields();
64
+ this.globalFilterFields = this.columns
65
+ .filter((col) => col.code !== undefined && col.isFilter !== false)
66
+ .map((col) => col.code);
67
+ this.initializePagination();
68
+ this.initializeActions();
69
+ // Set default value for isSortable
70
+ this.columns.forEach((col) => {
71
+ if (col.type === TableTypeEnum.ACTION) {
72
+ col.isEditable = false;
73
+ col.isFilter = false;
74
+ col.isSortable = false;
75
+ }
76
+ if (col.isSortable === undefined) {
77
+ col.isSortable = true;
78
+ }
79
+ if (col.isEditable === undefined) {
80
+ col.isEditable = true;
81
+ }
82
+ if (col.isFilter !== false && col.code !== undefined) {
83
+ this.globalFilterFields.push(col.code);
84
+ }
85
+ if (!col.width) {
86
+ col.width = this.calculateColumnWidth(col);
87
+ }
88
+ });
89
+ }
90
+ // Function to calculate column width based on text in header and data
91
+ calculateColumnWidth(col) {
92
+ const calculatedWidth = calculateTextWidth(col, col.title);
93
+ const totalWidth = calculatedWidth + this.iconWidth + 20;
94
+ return `${totalWidth}px`;
95
+ }
96
+ getHeaderWidth(col) {
97
+ // Remove 'px' from col.width and convert it to a number
98
+ const widthWithoutPx = parseInt(col.width?.replace('px', '') || '0', 10);
99
+ // Add 20 to the calculated width
100
+ const headerWidth = widthWithoutPx + 20;
101
+ // Return the new width in 'px'
102
+ return `${headerWidth}px`;
103
+ }
104
+ // Initialization Methods
105
+ formatingDateFields() {
106
+ return this.data.map((item) => {
107
+ const transformedItem = { ...item };
108
+ this.columns.forEach((column) => {
109
+ if (column.type === TableTypeEnum.DATE &&
110
+ column.code !== undefined &&
111
+ transformedItem[column.code] !== undefined) {
112
+ const dateValue = this.parseDate(transformedItem[column.code]);
113
+ transformedItem[column.code] = dateValue ? dateValue : null;
114
+ }
115
+ });
116
+ return transformedItem;
117
+ });
118
+ }
119
+ clear(table) {
120
+ table.clear();
121
+ this.searchValue = '';
122
+ }
123
+ parseDate(dateString) {
124
+ const parts = dateString.split('/');
125
+ if (parts.length === 3) {
126
+ // Assuming date format is DD/MM/YYYY
127
+ const day = parseInt(parts[0], 10);
128
+ const month = parseInt(parts[1], 10) - 1;
129
+ const year = parseInt(parts[2], 10);
130
+ const date = new Date(year, month, day);
131
+ return isNaN(date.getTime()) ? null : date;
132
+ }
133
+ return null;
134
+ }
135
+ initializePagination() {
136
+ if (this.isPaginated) {
137
+ // Check if rowsPerPage is undefined or an empty array
138
+ if (!this.rowsPerPage || this.rowsPerPage.length === 0) {
139
+ this.rowsPerPage = [20, 30, 40];
140
+ }
141
+ this.rows = this.rowsPerPage[0];
142
+ }
143
+ }
144
+ initializeActions() {
145
+ if (this.actions) {
146
+ this.actions.forEach((action) => {
147
+ switch (action.code) {
148
+ case 'delete':
149
+ this.isDelete = true;
150
+ this.Delete = (value) => action.action(value);
151
+ break;
152
+ case 'edit':
153
+ this.initializeEditActions(action);
154
+ break;
155
+ default:
156
+ this.isDelete = false;
157
+ this.isEdit = false;
158
+ }
159
+ });
160
+ }
161
+ }
162
+ initializeEditActions(action) {
163
+ this.isEdit = true;
164
+ this.initEditableRow = (data) => action.action.init(data);
165
+ this.saveEditableRow = (data) => {
166
+ const record = this.map.get(data.id);
167
+ action.action.save(data, record);
168
+ this.dataMap.clear();
169
+ };
170
+ this.cancelEditableRow = (item) => console.log(item);
171
+ }
172
+ onChange(event, id, key) {
173
+ const target = event.target;
174
+ this.changeHandler(id, key, target.value);
175
+ }
176
+ changeHandler(id, key, value) {
177
+ let column = this.columns.find((item) => item.code === key);
178
+ if (!this.map.get(id)) {
179
+ if (column?.type === TableTypeEnum.DATE) {
180
+ let date = this.parseDate(value);
181
+ this.dataMap.set(key, date);
182
+ }
183
+ else {
184
+ this.dataMap.set(key, value);
185
+ }
186
+ this.map.set(id, new Map(this.dataMap));
187
+ }
188
+ else {
189
+ let mapItem = this.map.get(id);
190
+ if (column?.type === TableTypeEnum.DATE) {
191
+ let date = this.parseDate(value);
192
+ mapItem.set(key, date);
193
+ }
194
+ else {
195
+ mapItem.set(key, value);
196
+ }
197
+ }
198
+ }
199
+ getColumnFilterType(column) {
200
+ switch (column.type) {
201
+ case TableTypeEnum.STRING:
202
+ return 'text';
203
+ case TableTypeEnum.AMOUNT:
204
+ return 'numeric';
205
+ case TableTypeEnum.NUMBER:
206
+ return 'numeric';
207
+ case TableTypeEnum.DATE:
208
+ return 'date';
209
+ case TableTypeEnum.MULTISELECT:
210
+ return 'multiSelect';
211
+ case TableTypeEnum.BOOLEAN:
212
+ return 'boolean';
213
+ default:
214
+ return 'text';
215
+ }
216
+ }
217
+ // State Check Methods
218
+ isEditable(key) {
219
+ let column = this.columns.find((item) => item.code === key);
220
+ return column?.isEditable !== false;
221
+ }
222
+ isMultiSelect(key) {
223
+ let column = this.columns.find((item) => item.code === key);
224
+ if (column?.type === TableTypeEnum.MULTISELECT &&
225
+ column.options &&
226
+ column.code !== undefined) {
227
+ this.optionEntries = new Map([
228
+ [column.code, Object.values(column.options)],
229
+ ]);
230
+ this.optionValues = this.optionEntries.get(key) || [];
231
+ return true;
232
+ }
233
+ return false;
234
+ }
235
+ isDatePicker(key) {
236
+ return (this.columns.find((item) => item.code === key)?.type ===
237
+ TableTypeEnum.DATE);
238
+ }
239
+ // Utility Methods
240
+ dateConverter(value) {
241
+ return new Date(value).toLocaleDateString('en-US');
242
+ }
243
+ getCurrencySymbol(column) {
244
+ return column.type === TableTypeEnum.AMOUNT &&
245
+ column.currency &&
246
+ this.isValidCurrencyCode(column.currency)
247
+ ? column.currency
248
+ : undefined;
249
+ }
250
+ isValidCurrencyCode(currencyCode) {
251
+ return this.validCurrencyCodes.includes(currencyCode);
252
+ }
253
+ filterGlobal(event) {
254
+ const target = event.target;
255
+ const value = target.value.toLowerCase();
256
+ // Create a new filtered dataset
257
+ const filteredData = this.data.filter((item) => {
258
+ return this.globalFilterFields.some((field) => {
259
+ const column = this.columns.find((col) => col.code === field);
260
+ if (!column) {
261
+ return false;
262
+ }
263
+ // Handle different column types
264
+ if (column.type === TableTypeEnum.DATE) {
265
+ const itemDate = this.formatDate(item[field]);
266
+ return itemDate && itemDate.includes(value);
267
+ }
268
+ else if (column.type === TableTypeEnum.AMOUNT ||
269
+ column.type === TableTypeEnum.NUMBER) {
270
+ return (item[field] && item[field].toString().toLowerCase().includes(value));
271
+ }
272
+ else {
273
+ return (item[field] && item[field].toString().toLowerCase().includes(value));
274
+ }
275
+ });
276
+ });
277
+ // Update the table's value
278
+ this.dt.value = filteredData;
279
+ }
280
+ formatDate(date) {
281
+ if (!date)
282
+ return '';
283
+ if (date instanceof Date) {
284
+ // Handle Date object
285
+ const day = date.getDate().toString().padStart(2, '0');
286
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
287
+ const year = date.getFullYear().toString();
288
+ return `${day}/${month}/${year}`;
289
+ }
290
+ else if (typeof date === 'string') {
291
+ // Handle string date
292
+ const parts = date.split('/');
293
+ if (parts.length === 3) {
294
+ return `${parts[0]}/${parts[1]}/${parts[2]}`;
295
+ }
296
+ else {
297
+ // Handle partial dates
298
+ return date;
299
+ }
300
+ }
301
+ return '';
302
+ }
303
+ exportExcel() {
304
+ this.exportExcelEvent.emit();
305
+ }
306
+ exportPdf() {
307
+ this.exportPdfEvent.emit();
308
+ }
309
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
310
+ 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 >\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 *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 display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\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 </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 <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=\"col.type === 'AMOUNT'; else normalOutput\"\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 <ng-container *ngIf=\"col.type === 'AMOUNT'; else normalText\">\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 #normalText>\n {{ data[col.code] }}\n </ng-template>\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}\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: "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.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" }] }); }
311
+ }
312
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTAdvancedPrimeTableComponent, decorators: [{
313
+ type: Component,
314
+ 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 >\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 *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 display=\"menu\"\n [type]=\"getColumnFilterType(col)\"\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 </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 <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=\"col.type === 'AMOUNT'; else normalOutput\"\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 <ng-container *ngIf=\"col.type === 'AMOUNT'; else normalText\">\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 #normalText>\n {{ data[col.code] }}\n </ng-template>\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}\n"] }]
315
+ }], ctorParameters: () => [], propDecorators: { data: [{
316
+ type: Input
317
+ }], columns: [{
318
+ type: Input
319
+ }], totalRecords: [{
320
+ type: Input
321
+ }], rowsPerPage: [{
322
+ type: Input
323
+ }], hasSearchFilter: [{
324
+ type: Input
325
+ }], hasExportExcel: [{
326
+ type: Input
327
+ }], hasExportPDF: [{
328
+ type: Input
329
+ }], hasColumnFilter: [{
330
+ type: Input
331
+ }], isPaginated: [{
332
+ type: Input
333
+ }], actions: [{
334
+ type: Input
335
+ }], isSortable: [{
336
+ type: Input
337
+ }], loading: [{
338
+ type: Input
339
+ }], maxHeight: [{
340
+ type: Input
341
+ }], filter: [{
342
+ type: Output
343
+ }], search: [{
344
+ type: Output
345
+ }], exportExcelEvent: [{
346
+ type: Output
347
+ }], exportPdfEvent: [{
348
+ type: Output
349
+ }], dt: [{
350
+ type: ViewChild,
351
+ args: ['dt', { static: false }]
352
+ }] } });
353
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHQtYWR2YW5jZWQtcHJpbWUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctcHJpbWUtdG9vbHMvc3JjL2xpYi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlL3B0LWFkdmFuY2VkLXByaW1lLXRhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3QyxPQUFPLEVBQWUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7OztBQU94RCxNQUFNLE9BQU8sNkJBQTZCO0lBK0N4QztRQTlDQSxTQUFTO1FBQ0EsU0FBSSxHQUFVLEVBQUUsQ0FBQztRQUNqQixZQUFPLEdBQWtCLEVBQUUsQ0FBQztRQUM1QixpQkFBWSxHQUFXLENBQUMsQ0FBQztRQUN6QixnQkFBVyxHQUFhLEVBQUUsQ0FBQztRQUMzQixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQUNoQyxpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUM5QixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUM3QixZQUFPLEdBQVUsRUFBRSxDQUFDO1FBQ3BCLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFDNUIsWUFBTyxHQUFZLEtBQUssQ0FBQztRQUN6QixjQUFTLEdBQWtCLElBQUksQ0FBQztRQUV6QyxrREFBa0Q7UUFDeEMsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDNUIsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDakMscUJBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUM1QyxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFJcEQsZ0JBQVcsR0FBVyxFQUFFLENBQUM7UUFFakIsdUJBQWtCLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ25ELGNBQVMsR0FBRyxFQUFFLENBQUM7UUFFZiw2QkFBNkI7UUFDN0IsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUMxQixXQUFNLEdBQVksS0FBSyxDQUFDO1FBQ3hCLFNBQUksR0FBVyxDQUFDLENBQUM7UUFFakIsNkJBQTZCO1FBQzdCLFlBQU8sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLFFBQUcsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQWlCLENBQUM7UUFDekMsaUJBQVksR0FBVSxFQUFFLENBQUM7UUFDekIsdUJBQWtCLEdBQWEsRUFBRSxDQUFDO1FBRWxDLDBCQUEwQjtRQUMxQixXQUFNLEdBQXlCLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztRQUN4QyxvQkFBZSxHQUF3QixHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFDaEQsb0JBQWUsR0FBd0IsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDO1FBQ2hELHNCQUFpQixHQUF3QixHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFDbEQsc0JBQWlCLEdBQVksS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFFaEIsUUFBUTtRQUNOLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FDeEMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUNqRCxDQUFDO1FBQ0YscURBQXFEO1FBQ3JELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxPQUFPO2FBQ25DLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksR0FBRyxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUM7YUFDakUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBYyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFekIsbUNBQW1DO1FBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDM0IsSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdEMsR0FBRyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7Z0JBQ3ZCLEdBQUcsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO2dCQUNyQixHQUFHLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUN6QixDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNqQyxHQUFHLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztZQUN4QixDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNqQyxHQUFHLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztZQUN4QixDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLEtBQUssSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNyRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QyxDQUFDO1lBRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDZixHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM3QyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsc0VBQXNFO0lBQzlELG9CQUFvQixDQUFDLEdBQWdCO1FBQzNDLE1BQU0sZUFBZSxHQUFHLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0QsTUFBTSxVQUFVLEdBQUcsZUFBZSxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ3pELE9BQU8sR0FBRyxVQUFVLElBQUksQ0FBQztJQUMzQixDQUFDO0lBRUQsY0FBYyxDQUFDLEdBQWdCO1FBQzdCLHdEQUF3RDtRQUN4RCxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUV6RSxpQ0FBaUM7UUFDakMsTUFBTSxXQUFXLEdBQUcsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUV4QywrQkFBK0I7UUFDL0IsT0FBTyxHQUFHLFdBQVcsSUFBSSxDQUFDO0lBQzVCLENBQUM7SUFFRCx5QkFBeUI7SUFDakIsbUJBQW1CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUM1QixNQUFNLGVBQWUsR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDOUIsSUFDRSxNQUFNLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxJQUFJO29CQUNsQyxNQUFNLENBQUMsSUFBSSxLQUFLLFNBQVM7b0JBQ3pCLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssU0FBUyxFQUMxQyxDQUFDO29CQUNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO29CQUMvRCxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQzlELENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUNILE9BQU8sZUFBZSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFZO1FBQ2hCLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFTyxTQUFTLENBQUMsVUFBa0I7UUFDbEMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkIscUNBQXFDO1lBQ3JDLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbkMsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDekMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNwQyxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3hDLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUM3QyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLHNEQUFzRDtZQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDdkQsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEMsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO2dCQUM5QixRQUFRLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDcEIsS0FBSyxRQUFRO3dCQUNYLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO3dCQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUNuRCxNQUFNO29CQUNSLEtBQUssTUFBTTt3QkFDVCxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7d0JBQ25DLE1BQU07b0JBQ1I7d0JBQ0UsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7d0JBQ3RCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO2dCQUN4QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVPLHFCQUFxQixDQUFDLE1BQVc7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLElBQVMsRUFBRSxFQUFFO1lBQ25DLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNyQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2QixDQUFDLENBQUM7UUFDRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELFFBQVEsQ0FBQyxLQUFZLEVBQUUsRUFBVSxFQUFFLEdBQVE7UUFDekMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQTBCLENBQUM7UUFDaEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsYUFBYSxDQUFDLEVBQVUsRUFBRSxHQUFRLEVBQUUsS0FBVTtRQUM1QyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUN0QixJQUFJLE1BQU0sRUFBRSxJQUFJLEtBQUssYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN4QyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNqQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDOUIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvQixDQUFDO1lBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzFDLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDL0IsSUFBSSxNQUFNLEVBQUUsSUFBSSxLQUFLLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzFCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELG1CQUFtQixDQUFDLE1BQW1CO1FBQ3JDLFFBQVEsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BCLEtBQUssYUFBYSxDQUFDLE1BQU07Z0JBQ3ZCLE9BQU8sTUFBTSxDQUFDO1lBQ2hCLEtBQUssYUFBYSxDQUFDLE1BQU07Z0JBQ3ZCLE9BQU8sU0FBUyxDQUFDO1lBQ25CLEtBQUssYUFBYSxDQUFDLE1BQU07Z0JBQ3ZCLE9BQU8sU0FBUyxDQUFDO1lBQ25CLEtBQUssYUFBYSxDQUFDLElBQUk7Z0JBQ3JCLE9BQU8sTUFBTSxDQUFDO1lBQ2hCLEtBQUssYUFBYSxDQUFDLFdBQVc7Z0JBQzVCLE9BQU8sYUFBYSxDQUFDO1lBQ3ZCLEtBQUssYUFBYSxDQUFDLE9BQU87Z0JBQ3hCLE9BQU8sU0FBUyxDQUFDO1lBQ25CO2dCQUNFLE9BQU8sTUFBTSxDQUFDO1FBQ2xCLENBQUM7SUFDSCxDQUFDO0lBRUQsc0JBQXNCO0lBQ3RCLFVBQVUsQ0FBQyxHQUFXO1FBQ3BCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQzVELE9BQU8sTUFBTSxFQUFFLFVBQVUsS0FBSyxLQUFLLENBQUM7SUFDdEMsQ0FBQztJQUVELGFBQWEsQ0FBQyxHQUFRO1FBQ3BCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQzVELElBQ0UsTUFBTSxFQUFFLElBQUksS0FBSyxhQUFhLENBQUMsV0FBVztZQUMxQyxNQUFNLENBQUMsT0FBTztZQUNkLE1BQU0sQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUN6QixDQUFDO1lBQ0QsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLEdBQUcsQ0FBQztnQkFDM0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQzdDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3RELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELFlBQVksQ0FBQyxHQUFRO1FBQ25CLE9BQU8sQ0FDTCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxJQUFJO1lBQ3BELGFBQWEsQ0FBQyxJQUFJLENBQ25CLENBQUM7SUFDSixDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGFBQWEsQ0FBQyxLQUFVO1FBQ3RCLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVELGlCQUFpQixDQUFDLE1BQW1CO1FBQ25DLE9BQU8sTUFBTSxDQUFDLElBQUksS0FBSyxhQUFhLENBQUMsTUFBTTtZQUN6QyxNQUFNLENBQUMsUUFBUTtZQUNmLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1lBQ3pDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUTtZQUNqQixDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2hCLENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxZQUFvQjtRQUM5QyxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFZO1FBQ3ZCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUEwQixDQUFDO1FBQ2hELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFekMsZ0NBQWdDO1FBQ2hDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDN0MsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQzVDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDO2dCQUM5RCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ1osT0FBTyxLQUFLLENBQUM7Z0JBQ2YsQ0FBQztnQkFFRCxnQ0FBZ0M7Z0JBQ2hDLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ3ZDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQzlDLE9BQU8sUUFBUSxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzlDLENBQUM7cUJBQU0sSUFDTCxNQUFNLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxNQUFNO29CQUNwQyxNQUFNLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxNQUFNLEVBQ3BDLENBQUM7b0JBQ0QsT0FBTyxDQUNMLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUNwRSxDQUFDO2dCQUNKLENBQUM7cUJBQU0sQ0FBQztvQkFDTixPQUFPLENBQ0wsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQ3BFLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCwyQkFBMkI7UUFDM0IsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsWUFBWSxDQUFDO0lBQy9CLENBQUM7SUFFTyxVQUFVLENBQUMsSUFBUztRQUMxQixJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLElBQUksSUFBSSxZQUFZLElBQUksRUFBRSxDQUFDO1lBQ3pCLHFCQUFxQjtZQUNyQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN2RCxNQUFNLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUMzQyxPQUFPLEdBQUcsR0FBRyxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNuQyxDQUFDO2FBQU0sSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNwQyxxQkFBcUI7WUFDckIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM5QixJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLE9BQU8sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQy9DLENBQUM7aUJBQU0sQ0FBQztnQkFDTix1QkFBdUI7Z0JBQ3ZCLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM3QixDQUFDOytHQTlVVSw2QkFBNkI7bUdBQTdCLDZCQUE2Qix3bkJDWDFDLHkyaEJBNGJBOzs0RkRqYmEsNkJBQTZCO2tCQUx6QyxTQUFTOytCQUNFLHlCQUF5Qjt3REFNMUIsSUFBSTtzQkFBWixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUdJLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBRTZCLEVBQUU7c0JBQXJDLFNBQVM7dUJBQUMsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVGFibGUgfSBmcm9tICdwcmltZW5nL3RhYmxlJztcbmltcG9ydCB7IFRhYmxlQ29sdW1uLCBUYWJsZVR5cGVFbnVtIH0gZnJvbSAnLi4vLi4vcHVibGljLWFwaSc7XG5pbXBvcnQgeyBjYWxjdWxhdGVUZXh0V2lkdGggfSBmcm9tICcuLi91dGlscy90ZXh0LnV0aWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdwdC1hZHZhbmNlZC1wcmltZS10YWJsZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9wdC1hZHZhbmNlZC1wcmltZS10YWJsZS5jb21wb25lbnQuY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgUFRBZHZhbmNlZFByaW1lVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvLyBJbnB1dHNcbiAgQElucHV0KCkgZGF0YTogYW55W10gPSBbXTtcbiAgQElucHV0KCkgY29sdW1uczogVGFibGVDb2x1bW5bXSA9IFtdO1xuICBASW5wdXQoKSB0b3RhbFJlY29yZHM6IG51bWJlciA9IDA7XG4gIEBJbnB1dCgpIHJvd3NQZXJQYWdlOiBudW1iZXJbXSA9IFtdO1xuICBASW5wdXQoKSBoYXNTZWFyY2hGaWx0ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaGFzRXhwb3J0RXhjZWw6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgaGFzRXhwb3J0UERGOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGhhc0NvbHVtbkZpbHRlcjogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBpc1BhZ2luYXRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBhY3Rpb25zOiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBpc1NvcnRhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGxvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWF4SGVpZ2h0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvLyBPdXRwdXRzOiBFdmVudHMgZW1pdHRlZCB0byB0aGUgcGFyZW50IGNvbXBvbmVudFxuICBAT3V0cHV0KCkgZmlsdGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgc2VhcmNoID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBleHBvcnRFeGNlbEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgZXhwb3J0UGRmRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZHQnLCB7IHN0YXRpYzogZmFsc2UgfSkgZHQhOiBUYWJsZTtcblxuICBzZWFyY2hWYWx1ZTogc3RyaW5nID0gJyc7XG5cbiAgcHJpdmF0ZSB2YWxpZEN1cnJlbmN5Q29kZXMgPSBbJ1VTRCcsICdFVVInLCAnTUFEJ107XG4gIGljb25XaWR0aCA9IDc3O1xuXG4gIC8vIENvbXBvbmVudCBzdGF0ZSBwcm9wZXJ0aWVzXG4gIGlzRGVsZXRlOiBib29sZWFuID0gZmFsc2U7XG4gIGlzRWRpdDogYm9vbGVhbiA9IGZhbHNlO1xuICByb3dzOiBudW1iZXIgPSAwO1xuXG4gIC8vIERhdGEgbWFuYWdlbWVudCBwcm9wZXJ0aWVzXG4gIGRhdGFNYXAgPSBuZXcgTWFwKCk7XG4gIG1hcCA9IG5ldyBNYXAoKTtcbiAgb3B0aW9uRW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBhbnlbXT4oKTtcbiAgb3B0aW9uVmFsdWVzOiBhbnlbXSA9IFtdO1xuICBnbG9iYWxGaWx0ZXJGaWVsZHM6IHN0cmluZ1tdID0gW107XG5cbiAgLy8gQ1JVRCBvcGVyYXRpb24gaGFuZGxlcnNcbiAgRGVsZXRlOiAodmFsdWU6IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBpbml0RWRpdGFibGVSb3c6IChkYXRhOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgc2F2ZUVkaXRhYmxlUm93OiAoZGF0YTogYW55KSA9PiB2b2lkID0gKCkgPT4ge307XG4gIGNhbmNlbEVkaXRhYmxlUm93OiAoaXRlbTogYW55KSA9PiB2b2lkID0gKCkgPT4ge307XG4gIGhhc0dyb3VwZWRDb2x1bW5zOiBib29sZWFuID0gZmFsc2U7XG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmhhc0dyb3VwZWRDb2x1bW5zID0gdGhpcy5jb2x1bW5zLnNvbWUoXG4gICAgICAoY29sKSA9PiBjb2wuY2hpbGRyZW4gJiYgY29sLmNoaWxkcmVuLmxlbmd0aCA+IDBcbiAgICApO1xuICAgIC8vIFRyYW5zZm9ybSB0aGUgZGF0ZSBmaWVsZHMgYmFzZWQgb24gY29sdW1uIG1ldGFkYXRhXG4gICAgdGhpcy5kYXRhID0gdGhpcy5mb3JtYXRpbmdEYXRlRmllbGRzKCk7XG4gICAgdGhpcy5nbG9iYWxGaWx0ZXJGaWVsZHMgPSB0aGlzLmNvbHVtbnNcbiAgICAgIC5maWx0ZXIoKGNvbCkgPT4gY29sLmNvZGUgIT09IHVuZGVmaW5lZCAmJiBjb2wuaXNGaWx0ZXIgIT09IGZhbHNlKVxuICAgICAgLm1hcCgoY29sKSA9PiBjb2wuY29kZSBhcyBzdHJpbmcpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZVBhZ2luYXRpb24oKTtcbiAgICB0aGlzLmluaXRpYWxpemVBY3Rpb25zKCk7XG5cbiAgICAvLyBTZXQgZGVmYXVsdCB2YWx1ZSBmb3IgaXNTb3J0YWJsZVxuICAgIHRoaXMuY29sdW1ucy5mb3JFYWNoKChjb2wpID0+IHtcbiAgICAgIGlmIChjb2wudHlwZSA9PT0gVGFibGVUeXBlRW51bS5BQ1RJT04pIHtcbiAgICAgICAgY29sLmlzRWRpdGFibGUgPSBmYWxzZTtcbiAgICAgICAgY29sLmlzRmlsdGVyID0gZmFsc2U7XG4gICAgICAgIGNvbC5pc1NvcnRhYmxlID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb2wuaXNTb3J0YWJsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbC5pc1NvcnRhYmxlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbC5pc0VkaXRhYmxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sLmlzRWRpdGFibGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sLmlzRmlsdGVyICE9PSBmYWxzZSAmJiBjb2wuY29kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuZ2xvYmFsRmlsdGVyRmllbGRzLnB1c2goY29sLmNvZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbC53aWR0aCkge1xuICAgICAgICBjb2wud2lkdGggPSB0aGlzLmNhbGN1bGF0ZUNvbHVtbldpZHRoKGNvbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgY29sdW1uIHdpZHRoIGJhc2VkIG9uIHRleHQgaW4gaGVhZGVyIGFuZCBkYXRhXG4gIHByaXZhdGUgY2FsY3VsYXRlQ29sdW1uV2lkdGgoY29sOiBUYWJsZUNvbHVtbik6IHN0cmluZyB7XG4gICAgY29uc3QgY2FsY3VsYXRlZFdpZHRoID0gY2FsY3VsYXRlVGV4dFdpZHRoKGNvbCwgY29sLnRpdGxlKTtcbiAgICBjb25zdCB0b3RhbFdpZHRoID0gY2FsY3VsYXRlZFdpZHRoICsgdGhpcy5pY29uV2lkdGggKyAyMDtcbiAgICByZXR1cm4gYCR7dG90YWxXaWR0aH1weGA7XG4gIH1cblxuICBnZXRIZWFkZXJXaWR0aChjb2w6IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICAvLyBSZW1vdmUgJ3B4JyBmcm9tIGNvbC53aWR0aCBhbmQgY29udmVydCBpdCB0byBhIG51bWJlclxuICAgIGNvbnN0IHdpZHRoV2l0aG91dFB4ID0gcGFyc2VJbnQoY29sLndpZHRoPy5yZXBsYWNlKCdweCcsICcnKSB8fCAnMCcsIDEwKTtcblxuICAgIC8vIEFkZCAyMCB0byB0aGUgY2FsY3VsYXRlZCB3aWR0aFxuICAgIGNvbnN0IGhlYWRlcldpZHRoID0gd2lkdGhXaXRob3V0UHggKyAyMDtcblxuICAgIC8vIFJldHVybiB0aGUgbmV3IHdpZHRoIGluICdweCdcbiAgICByZXR1cm4gYCR7aGVhZGVyV2lkdGh9cHhgO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6YXRpb24gTWV0aG9kc1xuICBwcml2YXRlIGZvcm1hdGluZ0RhdGVGaWVsZHMoKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgdHJhbnNmb3JtZWRJdGVtID0geyAuLi5pdGVtIH07XG4gICAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaCgoY29sdW1uKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFICYmXG4gICAgICAgICAgY29sdW1uLmNvZGUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgIHRyYW5zZm9ybWVkSXRlbVtjb2x1bW4uY29kZV0gIT09IHVuZGVmaW5lZFxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBkYXRlVmFsdWUgPSB0aGlzLnBhcnNlRGF0ZSh0cmFuc2Zvcm1lZEl0ZW1bY29sdW1uLmNvZGVdKTtcbiAgICAgICAgICB0cmFuc2Zvcm1lZEl0ZW1bY29sdW1uLmNvZGVdID0gZGF0ZVZhbHVlID8gZGF0ZVZhbHVlIDogbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJhbnNmb3JtZWRJdGVtO1xuICAgIH0pO1xuICB9XG5cbiAgY2xlYXIodGFibGU6IFRhYmxlKSB7XG4gICAgdGFibGUuY2xlYXIoKTtcbiAgICB0aGlzLnNlYXJjaFZhbHVlID0gJyc7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRGF0ZShkYXRlU3RyaW5nOiBzdHJpbmcpOiBEYXRlIHwgbnVsbCB7XG4gICAgY29uc3QgcGFydHMgPSBkYXRlU3RyaW5nLnNwbGl0KCcvJyk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgLy8gQXNzdW1pbmcgZGF0ZSBmb3JtYXQgaXMgREQvTU0vWVlZWVxuICAgICAgY29uc3QgZGF5ID0gcGFyc2VJbnQocGFydHNbMF0sIDEwKTtcbiAgICAgIGNvbnN0IG1vbnRoID0gcGFyc2VJbnQocGFydHNbMV0sIDEwKSAtIDE7XG4gICAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQocGFydHNbMl0sIDEwKTtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KTtcbiAgICAgIHJldHVybiBpc05hTihkYXRlLmdldFRpbWUoKSkgPyBudWxsIDogZGF0ZTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVQYWdpbmF0aW9uKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzUGFnaW5hdGVkKSB7XG4gICAgICAvLyBDaGVjayBpZiByb3dzUGVyUGFnZSBpcyB1bmRlZmluZWQgb3IgYW4gZW1wdHkgYXJyYXlcbiAgICAgIGlmICghdGhpcy5yb3dzUGVyUGFnZSB8fCB0aGlzLnJvd3NQZXJQYWdlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnJvd3NQZXJQYWdlID0gWzIwLCAzMCwgNDBdO1xuICAgICAgfVxuICAgICAgdGhpcy5yb3dzID0gdGhpcy5yb3dzUGVyUGFnZVswXTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVBY3Rpb25zKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGlvbnMpIHtcbiAgICAgIHRoaXMuYWN0aW9ucy5mb3JFYWNoKChhY3Rpb24pID0+IHtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24uY29kZSkge1xuICAgICAgICAgIGNhc2UgJ2RlbGV0ZSc6XG4gICAgICAgICAgICB0aGlzLmlzRGVsZXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuRGVsZXRlID0gKHZhbHVlOiBhbnkpID0+IGFjdGlvbi5hY3Rpb24odmFsdWUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZWRpdCc6XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVFZGl0QWN0aW9ucyhhY3Rpb24pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRoaXMuaXNEZWxldGUgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuaXNFZGl0ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUVkaXRBY3Rpb25zKGFjdGlvbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5pc0VkaXQgPSB0cnVlO1xuICAgIHRoaXMuaW5pdEVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4gYWN0aW9uLmFjdGlvbi5pbml0KGRhdGEpO1xuICAgIHRoaXMuc2F2ZUVkaXRhYmxlUm93ID0gKGRhdGE6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkID0gdGhpcy5tYXAuZ2V0KGRhdGEuaWQpO1xuICAgICAgYWN0aW9uLmFjdGlvbi5zYXZlKGRhdGEsIHJlY29yZCk7XG4gICAgICB0aGlzLmRhdGFNYXAuY2xlYXIoKTtcbiAgICB9O1xuICAgIHRoaXMuY2FuY2VsRWRpdGFibGVSb3cgPSAoaXRlbTogYW55KSA9PiBjb25zb2xlLmxvZyhpdGVtKTtcbiAgfVxuXG4gIG9uQ2hhbmdlKGV2ZW50OiBFdmVudCwgaWQ6IG51bWJlciwga2V5OiBhbnkpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICB0aGlzLmNoYW5nZUhhbmRsZXIoaWQsIGtleSwgdGFyZ2V0LnZhbHVlKTtcbiAgfVxuXG4gIGNoYW5nZUhhbmRsZXIoaWQ6IG51bWJlciwga2V5OiBhbnksIHZhbHVlOiBhbnkpIHtcbiAgICBsZXQgY29sdW1uID0gdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KTtcbiAgICBpZiAoIXRoaXMubWFwLmdldChpZCkpIHtcbiAgICAgIGlmIChjb2x1bW4/LnR5cGUgPT09IFRhYmxlVHlwZUVudW0uREFURSkge1xuICAgICAgICBsZXQgZGF0ZSA9IHRoaXMucGFyc2VEYXRlKHZhbHVlKTtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kYXRhTWFwLnNldChrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWFwLnNldChpZCwgbmV3IE1hcCh0aGlzLmRhdGFNYXApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IG1hcEl0ZW0gPSB0aGlzLm1hcC5nZXQoaWQpO1xuICAgICAgaWYgKGNvbHVtbj8udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFKSB7XG4gICAgICAgIGxldCBkYXRlID0gdGhpcy5wYXJzZURhdGUodmFsdWUpO1xuICAgICAgICBtYXBJdGVtLnNldChrZXksIGRhdGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFwSXRlbS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2x1bW46IFRhYmxlQ29sdW1uKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKGNvbHVtbi50eXBlKSB7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgICAgY2FzZSBUYWJsZVR5cGVFbnVtLkFNT1VOVDpcbiAgICAgICAgcmV0dXJuICdudW1lcmljJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5OVU1CRVI6XG4gICAgICAgIHJldHVybiAnbnVtZXJpYyc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uREFURTpcbiAgICAgICAgcmV0dXJuICdkYXRlJztcbiAgICAgIGNhc2UgVGFibGVUeXBlRW51bS5NVUxUSVNFTEVDVDpcbiAgICAgICAgcmV0dXJuICdtdWx0aVNlbGVjdCc7XG4gICAgICBjYXNlIFRhYmxlVHlwZUVudW0uQk9PTEVBTjpcbiAgICAgICAgcmV0dXJuICdib29sZWFuJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAndGV4dCc7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RhdGUgQ2hlY2sgTWV0aG9kc1xuICBpc0VkaXRhYmxlKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgbGV0IGNvbHVtbiA9IHRoaXMuY29sdW1ucy5maW5kKChpdGVtKSA9PiBpdGVtLmNvZGUgPT09IGtleSk7XG4gICAgcmV0dXJuIGNvbHVtbj8uaXNFZGl0YWJsZSAhPT0gZmFsc2U7XG4gIH1cblxuICBpc011bHRpU2VsZWN0KGtleTogYW55KTogYm9vbGVhbiB7XG4gICAgbGV0IGNvbHVtbiA9IHRoaXMuY29sdW1ucy5maW5kKChpdGVtKSA9PiBpdGVtLmNvZGUgPT09IGtleSk7XG4gICAgaWYgKFxuICAgICAgY29sdW1uPy50eXBlID09PSBUYWJsZVR5cGVFbnVtLk1VTFRJU0VMRUNUICYmXG4gICAgICBjb2x1bW4ub3B0aW9ucyAmJlxuICAgICAgY29sdW1uLmNvZGUgIT09IHVuZGVmaW5lZFxuICAgICkge1xuICAgICAgdGhpcy5vcHRpb25FbnRyaWVzID0gbmV3IE1hcChbXG4gICAgICAgIFtjb2x1bW4uY29kZSwgT2JqZWN0LnZhbHVlcyhjb2x1bW4ub3B0aW9ucyldLFxuICAgICAgXSk7XG4gICAgICB0aGlzLm9wdGlvblZhbHVlcyA9IHRoaXMub3B0aW9uRW50cmllcy5nZXQoa2V5KSB8fCBbXTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpc0RhdGVQaWNrZXIoa2V5OiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jb2x1bW5zLmZpbmQoKGl0ZW0pID0+IGl0ZW0uY29kZSA9PT0ga2V5KT8udHlwZSA9PT1cbiAgICAgIFRhYmxlVHlwZUVudW0uREFURVxuICAgICk7XG4gIH1cblxuICAvLyBVdGlsaXR5IE1ldGhvZHNcbiAgZGF0ZUNvbnZlcnRlcih2YWx1ZTogYW55KTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmV3IERhdGUodmFsdWUpLnRvTG9jYWxlRGF0ZVN0cmluZygnZW4tVVMnKTtcbiAgfVxuXG4gIGdldEN1cnJlbmN5U3ltYm9sKGNvbHVtbjogVGFibGVDb2x1bW4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5BTU9VTlQgJiZcbiAgICAgIGNvbHVtbi5jdXJyZW5jeSAmJlxuICAgICAgdGhpcy5pc1ZhbGlkQ3VycmVuY3lDb2RlKGNvbHVtbi5jdXJyZW5jeSlcbiAgICAgID8gY29sdW1uLmN1cnJlbmN5XG4gICAgICA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgaXNWYWxpZEN1cnJlbmN5Q29kZShjdXJyZW5jeUNvZGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZhbGlkQ3VycmVuY3lDb2Rlcy5pbmNsdWRlcyhjdXJyZW5jeUNvZGUpO1xuICB9XG5cbiAgZmlsdGVyR2xvYmFsKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgIGNvbnN0IHZhbHVlID0gdGFyZ2V0LnZhbHVlLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgZmlsdGVyZWQgZGF0YXNldFxuICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IHRoaXMuZGF0YS5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmdsb2JhbEZpbHRlckZpZWxkcy5zb21lKChmaWVsZCkgPT4ge1xuICAgICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wuY29kZSA9PT0gZmllbGQpO1xuICAgICAgICBpZiAoIWNvbHVtbikge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSBkaWZmZXJlbnQgY29sdW1uIHR5cGVzXG4gICAgICAgIGlmIChjb2x1bW4udHlwZSA9PT0gVGFibGVUeXBlRW51bS5EQVRFKSB7XG4gICAgICAgICAgY29uc3QgaXRlbURhdGUgPSB0aGlzLmZvcm1hdERhdGUoaXRlbVtmaWVsZF0pO1xuICAgICAgICAgIHJldHVybiBpdGVtRGF0ZSAmJiBpdGVtRGF0ZS5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uQU1PVU5UIHx8XG4gICAgICAgICAgY29sdW1uLnR5cGUgPT09IFRhYmxlVHlwZUVudW0uTlVNQkVSXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBpdGVtW2ZpZWxkXSAmJiBpdGVtW2ZpZWxkXS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgaXRlbVtmaWVsZF0gJiYgaXRlbVtmaWVsZF0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gVXBkYXRlIHRoZSB0YWJsZSdzIHZhbHVlXG4gICAgdGhpcy5kdC52YWx1ZSA9IGZpbHRlcmVkRGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0RGF0ZShkYXRlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghZGF0ZSkgcmV0dXJuICcnO1xuICAgIGlmIChkYXRlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgLy8gSGFuZGxlIERhdGUgb2JqZWN0XG4gICAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICBjb25zdCBtb250aCA9IChkYXRlLmdldE1vbnRoKCkgKyAxKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpLnRvU3RyaW5nKCk7XG4gICAgICByZXR1cm4gYCR7ZGF5fS8ke21vbnRofS8ke3llYXJ9YDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gSGFuZGxlIHN0cmluZyBkYXRlXG4gICAgICBjb25zdCBwYXJ0cyA9IGRhdGUuc3BsaXQoJy8nKTtcbiAgICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgcmV0dXJuIGAke3BhcnRzWzBdfS8ke3BhcnRzWzFdfS8ke3BhcnRzWzJdfWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBIYW5kbGUgcGFydGlhbCBkYXRlc1xuICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgZXhwb3J0RXhjZWwoKSB7XG4gICAgdGhpcy5leHBvcnRFeGNlbEV2ZW50LmVtaXQoKTtcbiAgfVxuXG4gIGV4cG9ydFBkZigpIHtcbiAgICB0aGlzLmV4cG9ydFBkZkV2ZW50LmVtaXQoKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInB0LWFkdmFuY2VkLXByaW1lLXRhYmxlIHRhYmxlLWNvbnRhaW5lclwiPlxuICA8cC10YWJsZVxuICAgICNkdFxuICAgIFt2YWx1ZV09XCJkYXRhXCJcbiAgICBbbG9hZGluZ109XCJsb2FkaW5nXCJcbiAgICBbcm93c109XCJyb3dzXCJcbiAgICBbcGFnaW5hdG9yXT1cImlzUGFnaW5hdGVkXCJcbiAgICBbZ2xvYmFsRmlsdGVyRmllbGRzXT1cImdsb2JhbEZpbHRlckZpZWxkc1wiXG4gICAgW3Jvd3NQZXJQYWdlT3B0aW9uc109XCJyb3dzUGVyUGFnZVwiXG4gICAgZGF0YUtleT1cImlkXCJcbiAgICBzdHlsZUNsYXNzPVwicC1kYXRhdGFibGUtZ3JpZGxpbmVzXCJcbiAgICBzdHlsZUNsYXNzPVwicC1kYXRhdGFibGUtc3RyaXBlZFwiXG4gICAgZWRpdE1vZGU9XCJyb3dcIlxuICAgIFtzY3JvbGxhYmxlXT1cInRydWVcIlxuICAgIFtzY3JvbGxIZWlnaHRdPVwibWF4SGVpZ2h0ICE9PSBudWxsID8gbWF4SGVpZ2h0IDogdW5kZWZpbmVkXCJcbiAgPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjYXB0aW9uXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmxleFwiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxoMz5Ub3RhbDoge3sgdG90YWxSZWNvcmRzIH19PC9oMz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8IS0tIENsZWFyIGZpbHRlcnMgLS0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJoYXNTZWFyY2hGaWx0ZXJcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLWZpbHRlci1zbGFzaFwiXG4gICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2xlYXIoZHQpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgZmlsdGVyc1wiXG4gICAgICAgICAgPjwvYnV0dG9uPlxuXG4gICAgICAgICAgPCEtLSBFeHBvcnQgdG8gRXhjZWwgQnV0dG9uIC0tPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzRXhwb3J0RXhjZWxcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLWZpbGUtZXhjZWxcIlxuICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImV4cG9ydEV4Y2VsKClcIlxuICAgICAgICAgICAgdGl0bGU9XCJFeHBvcnQgdG8gRXhjZWxcIlxuICAgICAgICAgID48L2J1dHRvbj5cblxuICAgICAgICAgIDwhLS0gRXhwb3J0IHRvIFBERiBCdXR0b24gLS0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJoYXNFeHBvcnRQREZcIlxuICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLWZpbGUtcGRmXCJcbiAgICAgICAgICAgIGNsYXNzPVwicC1idXR0b24tcm91bmRlZCBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRQZGYoKVwiXG4gICAgICAgICAgICB0aXRsZT1cIkV4cG9ydCB0byBQREZcIlxuICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtbC1hdXRvXCIgKm5nSWY9XCJoYXNTZWFyY2hGaWx0ZXJcIj5cbiAgICAgICAgICA8IS0tIEFkZCB0aGlzIHdyYXBwZXIgZGl2IHdpdGggbWwtYXV0byBjbGFzcyAtLT5cbiAgICAgICAgICA8cC1pY29uRmllbGQgaWNvblBvc2l0aW9uPVwibGVmdFwiIGNsYXNzPVwibWwtYXV0b1wiPlxuICAgICAgICAgICAgPHAtaW5wdXRJY29uPlxuICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXNlYXJjaFwiPjwvaT5cbiAgICAgICAgICAgIDwvcC1pbnB1dEljb24+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgcElucHV0VGV4dFxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VhcmNoVmFsdWVcIlxuICAgICAgICAgICAgICAoaW5wdXQpPVwiZmlsdGVyR2xvYmFsKCRldmVudClcIlxuICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlYXJjaCBrZXl3b3JkXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9wLWljb25GaWVsZD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImhlYWRlclwiPlxuICAgICAgPHRyIGNsYXNzPVwic3RpY2t5LWhlYWRlclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sdW1uc1wiPlxuICAgICAgICAgIDx0aFxuICAgICAgICAgICAgKm5nSWY9XCIhY29sLmNoaWxkcmVuOyBlbHNlIGdyb3VwSGVhZGVyXCJcbiAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgIFtzdHlsZS5wYWRkaW5nXT1cIicwcHgnXCJcbiAgICAgICAgICAgIGNvbHNwYW49XCIxXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICpuZ0lmPVwiaXNTb3J0YWJsZSAmJiBjb2wuaXNTb3J0YWJsZSAhPT0gZmFsc2U7IGVsc2Ugbm9Tb3J0SGVhZGVyXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgcFNvcnRhYmxlQ29sdW1uPVwie3sgY29sLmNvZGUgfX1cIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJnZXRIZWFkZXJXaWR0aChjb2wpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaGVhZGVyLWNvbnRhaW5lciBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLnBhZGRpbmddPVwiJzBweCdcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLm1hcmdpbl09XCInMTBweCdcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGNvbC50aXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpY29ucyBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cIic3N3B4J1wiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxwLXNvcnRJY29uIGZpZWxkPVwie3sgY29sLmNvZGUgfX1cIiAvPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sLmlzRmlsdGVyICE9PSBmYWxzZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxwLWNvbHVtbkZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSA9PT0gJ0FNT1VOVCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2ZpZWxkXT1cImNvbC5jb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY3VycmVuY3ldPVwiZ2V0Q3VycmVuY3lTeW1ib2woY29sKVwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1jb2x1bW5GaWx0ZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8cC1jb2x1bW5GaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29sLnR5cGUgIT09ICdBTU9VTlQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF09XCJjb2wuY29kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5PVwibWVudVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcFRlbXBsYXRlPVwiZmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0LXZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJDYWxsYmFjaz1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbCkgPT09ICdkYXRlJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNhbGxiYWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRlRm9ybWF0XT1cIidkZC9tbS95eSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9wLWNhbGVuZGFyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtZmlsdGVyQ2FsbGJhY2s9XCJmaWx0ZXJDYWxsYmFja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpID09PSAnbXVsdGlTZWxlY3QnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtbXVsdGlTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJjb2wuZmlsdGVyT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNhbGxiYWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5XT1cIidjaGlwJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY3VzdG9tLW11bHRpc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9wLWNvbHVtbkZpbHRlcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub1NvcnRIZWFkZXI+XG4gICAgICAgICAgICAgIDx0aD5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgY29sLnRpdGxlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC5pc0ZpbHRlciAhPT0gZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgPHAtY29sdW1uRmlsdGVyXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb2wudHlwZSA9PT0gJ0FNT1VOVCdcIlxuICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk9XCJtZW51XCJcbiAgICAgICAgICAgICAgICAgICAgICBbZmllbGRdPVwiY29sLmNvZGVcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImdldENvbHVtbkZpbHRlclR5cGUoY29sKVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2N1cnJlbmN5XT1cImdldEN1cnJlbmN5U3ltYm9sKGNvbClcIlxuICAgICAgICAgICAgICAgICAgICA+PC9wLWNvbHVtbkZpbHRlcj5cblxuICAgICAgICAgICAgICAgICAgICA8cC1jb2x1bW5GaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlICE9PSAnQU1PVU5UJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgZGlzcGxheT1cIm1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAgIFtmaWVsZF09XCJjb2wuY29kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3R5cGVdPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgcFRlbXBsYXRlPVwiZmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC12YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0LWZpbHRlckNhbGxiYWNrPVwiZmlsdGVyQ2FsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJnZXRDb2x1bW5GaWx0ZXJUeXBlKGNvbCkgPT09ICdkYXRlJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAtY2FsZW5kYXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDYWxsYmFjaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGVGb3JtYXRdPVwiJ2RkL21tL3l5J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICA+PC9wLWNhbGVuZGFyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHBUZW1wbGF0ZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQtdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldC1maWx0ZXJDYWxsYmFjaz1cImZpbHRlckNhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ2V0Q29sdW1uRmlsdGVyVHlwZShjb2wpID09PSAnbXVsdGlTZWxlY3QnXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJjb2wuZmlsdGVyT3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiZmlsdGVyQ2FsbGJhY2soJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNwbGF5XT1cIidjaGlwJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjdXN0b20tbXVsdGlzZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L3AtY29sdW1uRmlsdGVyPlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPCEtLSBHcm91cGVkIGhlYWRlcnMgLS0+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNncm91cEhlYWRlcj5cbiAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICBbYXR0ci5jb2xzcGFuXT1cImNvbC5jaGlsZHJlbj8ubGVuZ3RoXCJcbiAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImdldEhlYWRlcldpZHRoKGNvbClcIlxuICAgICAgICAgICAgICBbc3R5bGUudGV4dC1hbGlnbl09XCInY2VudGVyJ1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IGNvbC50aXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3RyPlxuICAgICAgPCEtLSBDaGlsZCBoZWFkZXJzIChTZWNvbmQgUm93KSAtLT5cbiAgICAgIDx0ciAqbmdJZj1cImhhc0dyb3VwZWRDb2x1bW5zXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbC5jaGlsZHJlblwiPlxuICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBjaGlsZCBvZiBjb2wuY2hpbGRyZW5cIlxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY2hpbGQpXCJcbiAgICAgICAgICAgICAgW3N0eWxlLnBhZGRpbmddPVwiJzBweCdcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8IS0tIFNvcnRhYmxlL0ZpbHRlcmFibGUgaGVhZGVyIGxvZ2ljIGZvciBjaGlsZCBjb2x1bW5zIC0tPlxuICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3RyPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8IS0tIEVtcHR5IG1lc3NhZ2UgdGVtcGxhdGUgLS0+XG4gICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImVtcHR5bWVzc2FnZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LW1lc3NhZ2VcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgPHA+Tm8gcmVjb3JkcyBhdmFpbGFibGUgdG8gZGlzcGxheS48L3A+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPG5nLXRlbXBsYXRlXG4gICAgICBwVGVtcGxhdGU9XCJib2R5XCJcbiAgICAgIGxldC1kYXRhXG4gICAgICBsZXQtZWRpdGluZz1cImVkaXRpbmdcIlxuICAgICAgbGV0LXJpPVwicm93SW5kZXhcIlxuICAgID5cbiAgICAgIDwhLS0gUmVuZGVyIGEgdGFibGUgcm93IGFuZCBtYWtlIGl0IGVkaXRhYmxlIGlmIGBpc0VkaXRgIGlzIHRydWUgLS0+XG4gICAgICA8dHIgKm5nSWY9XCIhbG9hZGluZ1wiIFtwRWRpdGFibGVSb3ddPVwiaXNFZGl0ID8gZGF0YSA6IG51bGxcIj5cbiAgICAgICAgPCEtLSBMb29wIHRocm91Z2ggZWFjaCBjb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCI+XG4gICAgICAgICAgPCEtLSBDaGVjayBpZiB0aGUgY29sdW1uIGhhcyBjaGlsZHJlbiAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNvbC5jaGlsZHJlbjsgZWxzZSBjaGlsZENvbHVtbnNcIj5cbiAgICAgICAgICAgIDwhLS0gUmVuZGVyIGEgc2luZ2xlIGNlbGwgZm9yIGNvbHVtbnMgd2l0aG91dCBjaGlsZHJlbiAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgKm5nSWY9XCJjb2wuY29kZSAhPT0gdW5kZWZpbmVkICYmIGRhdGFbY29sLmNvZGVdICE9PSB1bmRlZmluZWRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cImlzRWRpdGFibGUoY29sLmNvZGUpOyBlbHNlIG5vcm1hbFREXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0SGVhZGVyV2lkdGgoY29sKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8IS0tIEVkaXRhYmxlIGlucHV0IGZvciB0aGUgY29sdW1uIC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc011bHRpU2VsZWN0KGNvbC5jb2RlKTsgZWxzZSBkYXRlUGlja2VyXCI+XG4gICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cC1tdWx0aVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImRhdGFbY29sLmNvZGVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZV09XCJ7IHdpZHRoOiAnMTAwJScgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlSGFuZGxlcihkYXRhLmlkLCBjb2wuY29kZSwgJGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cIm9wdGlvblZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvcC1tdWx0aVNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cIm91dHB1dFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdWx0aS1zZWxlY3QtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByZWMgb2YgZGF0YVtjb2wuY29kZV1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtdGFnIFt2YWx1ZV09XCJyZWNcIj48L3AtdGFnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8L3AtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGF0ZVBpY2tlcj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc0RhdGVQaWNrZXIoY29sLmNvZGUpOyBlbHNlIG5vcm1hbElucHV0XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHAtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwLWNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtpbnB1dElkXT1cImRhdGFbY29sLmNvZGVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZGF0YVtjb2wuY29kZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VIYW5kbGVyKGRhdGEuaWQsIGNvbC5jb2RlLCAkZXZlbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRlRm9ybWF0XT1cIidkZC9tbS95eSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY29sLmNvZGVdIHwgY3VzdG9tRGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9ybWFsSW5wdXQ+XG4gICAgICAgICAgICAgICAgICA8cC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImRhdGFbY29sLmNvZGVdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25DaGFuZ2UoJGV2ZW50LCBkYXRhLmlkLCBjb2wuY29kZSlcIlxuICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbC50eXBlID09PSAnQU1PVU5UJzsgZWxzZSBub3JtYWxPdXRwdXRcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFbY29sLmNvZGVdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBjdXN0b21DdXJyZW5jeVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBnZXRDdXJyZW5jeVN5bWJvbChjb2wpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsUGxhY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC50aG91c2FuZFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjb2wuZGVjaW1hbFNlcGFyYXRvclxuICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vcm1hbE91dHB1dD5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY29sLmNvZGVdIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvcC1jZWxsRWRpdG9yPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvdGQ+XG5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxURD5cbiAgICAgICAgICAgICAgICA8dGQgW3N0eWxlLndpZHRoXT1cImdldEhlYWRlcldpZHRoKGNvbClcIj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2wudHlwZSA9PT0gJ0FNT1VOVCc7IGVsc2Ugbm9ybWFsVGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgICAgICAgIGRhdGFbY29sLmNvZGVdXG4gICAgICAgICAgICAgICAgICAgICAgICB8IGN1c3RvbUN1cnJlbmN5XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogZ2V0Q3VycmVuY3lTeW1ib2woY29sKVxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNvbC5kZWNpbWFsUGxhY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLnRob3VzYW5kU2VwYXJhdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogY29sLmRlY2ltYWxTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3JtYWxUZXh0PlxuICAgICAgICAgICAgICAgICAgICB7eyBkYXRhW2NvbC5jb2RlXSB9fVxuICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8IS0tIFJlbmRlciBjaGlsZCBjb2x1bW5zIGlmIHRoZSBjb2x1bW4gaGFzIGNoaWxkcmVuIC0tPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjY2hpbGRDb2x1bW5zPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY2hpbGQgb2YgY29sLmNoaWxkcmVuXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgY2hpbGQuY29kZSAhPT0gdW5kZWZpbmVkICYmIGRhdGFbY2hpbGQuY29kZV0gIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8dGQgW3N0eWxlLndpZHRoXT1cImdldEhlYWRlcldpZHRoKGNoaWxkKVwiPlxuICAgICAgICAgICAgICAgICAgPCEtLSBSZW5kZXIgZWRpdGFibGUgb3Igbm9ybWFsIGNlbGxzIGZvciBjaGlsZCBjb2x1bW5zIC0tPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImlzRWRpdGFibGUoY2hpbGQuY29kZSk7IGVsc2UgY2hpbGROb3JtYWxURFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxwLWNlbGxFZGl0b3I+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcElucHV0VGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImRhdGFbY2hpbGQuY29kZV1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hhbmdlKCRldmVudCwgZGF0YS5pZCwgY2hpbGQuY29kZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJvdXRwdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY2hpbGQuY29kZV0gfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L3AtY2VsbEVkaXRvcj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2NoaWxkTm9ybWFsVEQ+XG4gICAgICAgICAgICAgICAgICAgIHt7IGRhdGFbY2hpbGQuY29kZV0gfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIFJlbmRlciBhY3Rpb24gYnV0dG9ucyBpZiB0aGVyZSBhcmUgYW55IGFjdGlvbnMgZGVmaW5lZCAtLT5cbiAgICAgICAgPHRkICpuZ0lmPVwiYWN0aW9ucz8ubGVuZ3RoXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1idXR0b25zLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzRGVsZXRlXCI+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgICAgICAgcFJpcHBsZVxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGljb249XCJwaSBwaS10cmFzaFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIkRlbGV0ZShkYXRhLmlkKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBwSW5pdEVkaXRhYmxlUm93XG4gICAgICAgICAgICAgICAgKm5nSWY9XCIhZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgIHBSaXBwbGVcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktcGVuY2lsXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiaW5pdEVkaXRhYmxlUm93KGRhdGEpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICpuZ0lmPVwiZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgcFNhdmVFZGl0YWJsZVJvd1xuICAgICAgICAgICAgICAgIHBCdXR0b25cbiAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgaWNvbj1cInBpIHBpLWNoZWNrXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2F2ZUVkaXRhYmxlUm93KGRhdGEpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXJvdW5kZWQgcC1idXR0b24tdGV4dFwiXG4gICAgICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICpuZ0lmPVwiZWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgcENhbmNlbEVkaXRhYmxlUm93XG4gICAgICAgICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgICAgICAgIHBSaXBwbGVcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBpY29uPVwicGkgcGktdGltZXNcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJjYW5jZWxFZGl0YWJsZVJvdyhkYXRhKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1yb3VuZGVkIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvdHI+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9wLXRhYmxlPlxuPC9kaXY+XG4iXX0=