mat-table-ext 0.0.0 → 0.0.2

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 (88) hide show
  1. package/README.md +48 -27
  2. package/{projects/mat-table-ext/assets → assets}/pinIcon.svg +0 -0
  3. package/{projects/mat-table-ext/assets → assets}/pinLeft.svg +0 -0
  4. package/{projects/mat-table-ext/assets → assets}/pinNone.svg +0 -0
  5. package/{projects/mat-table-ext/assets → assets}/pinRight.svg +0 -0
  6. package/{projects/mat-table-ext/assets → assets}/pinned.svg +0 -0
  7. package/esm2020/lib/components/column-pinning/column-pinning.component.mjs +58 -0
  8. package/esm2020/lib/components/editing/editing.component.mjs +122 -0
  9. package/esm2020/lib/components/filter-columns-component/filter-columns-component.component.mjs +68 -0
  10. package/esm2020/lib/directives/resize-column.directive.mjs +99 -0
  11. package/esm2020/lib/mat-table-ext.component.mjs +1021 -0
  12. package/esm2020/lib/mat-table-ext.module.mjs +237 -0
  13. package/esm2020/lib/mat-table-ext.service.mjs +20 -0
  14. package/esm2020/lib/models/tableExtModels.mjs +2 -0
  15. package/esm2020/mat-table-ext.mjs +5 -0
  16. package/esm2020/public-api.mjs +11 -0
  17. package/fesm2015/mat-table-ext.mjs +1585 -0
  18. package/fesm2015/mat-table-ext.mjs.map +1 -0
  19. package/fesm2020/mat-table-ext.mjs +1582 -0
  20. package/fesm2020/mat-table-ext.mjs.map +1 -0
  21. package/index.d.ts +5 -0
  22. package/lib/components/column-pinning/column-pinning.component.d.ts +27 -0
  23. package/lib/components/editing/editing.component.d.ts +42 -0
  24. package/lib/components/filter-columns-component/filter-columns-component.component.d.ts +26 -0
  25. package/lib/directives/resize-column.directive.d.ts +27 -0
  26. package/lib/mat-table-ext.component.d.ts +348 -0
  27. package/lib/mat-table-ext.module.d.ts +58 -0
  28. package/lib/mat-table-ext.service.d.ts +11 -0
  29. package/lib/models/tableExtModels.d.ts +76 -0
  30. package/package.json +54 -45
  31. package/{projects/mat-table-ext/src/public-api.ts → public-api.d.ts} +1 -5
  32. package/.editorconfig +0 -16
  33. package/.vscode/extensions.json +0 -4
  34. package/.vscode/launch.json +0 -20
  35. package/.vscode/tasks.json +0 -42
  36. package/angular.json +0 -150
  37. package/projects/mat-table-ext/.browserslistrc +0 -16
  38. package/projects/mat-table-ext/README.md +0 -24
  39. package/projects/mat-table-ext/karma.conf.js +0 -44
  40. package/projects/mat-table-ext/ng-package.json +0 -9
  41. package/projects/mat-table-ext/package.json +0 -34
  42. package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.html +0 -7
  43. package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.scss +0 -9
  44. package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.spec.ts +0 -23
  45. package/projects/mat-table-ext/src/lib/components/column-pinning/column-pinning.component.ts +0 -48
  46. package/projects/mat-table-ext/src/lib/components/editing/editing.component.html +0 -55
  47. package/projects/mat-table-ext/src/lib/components/editing/editing.component.scss +0 -19
  48. package/projects/mat-table-ext/src/lib/components/editing/editing.component.spec.ts +0 -23
  49. package/projects/mat-table-ext/src/lib/components/editing/editing.component.ts +0 -110
  50. package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.html +0 -26
  51. package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.scss +0 -0
  52. package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.spec.ts +0 -23
  53. package/projects/mat-table-ext/src/lib/components/filter-columns-component/filter-columns-component.component.ts +0 -54
  54. package/projects/mat-table-ext/src/lib/directives/resize-column.directive.ts +0 -103
  55. package/projects/mat-table-ext/src/lib/mat-table-ext.component.html +0 -285
  56. package/projects/mat-table-ext/src/lib/mat-table-ext.component.spec.ts +0 -25
  57. package/projects/mat-table-ext/src/lib/mat-table-ext.component.ts +0 -985
  58. package/projects/mat-table-ext/src/lib/mat-table-ext.module.ts +0 -127
  59. package/projects/mat-table-ext/src/lib/mat-table-ext.scss +0 -189
  60. package/projects/mat-table-ext/src/lib/mat-table-ext.service.spec.ts +0 -16
  61. package/projects/mat-table-ext/src/lib/mat-table-ext.service.ts +0 -12
  62. package/projects/mat-table-ext/src/lib/models/tableExtModels.ts +0 -85
  63. package/projects/mat-table-ext/src/test.ts +0 -27
  64. package/projects/mat-table-ext/tsconfig.lib.json +0 -15
  65. package/projects/mat-table-ext/tsconfig.lib.prod.json +0 -10
  66. package/projects/mat-table-ext/tsconfig.spec.json +0 -17
  67. package/projects/mat-table-ext-example/.browserslistrc +0 -16
  68. package/projects/mat-table-ext-example/karma.conf.js +0 -44
  69. package/projects/mat-table-ext-example/src/app/app.component.html +0 -577
  70. package/projects/mat-table-ext-example/src/app/app.component.scss +0 -0
  71. package/projects/mat-table-ext-example/src/app/app.component.spec.ts +0 -31
  72. package/projects/mat-table-ext-example/src/app/app.component.ts +0 -173
  73. package/projects/mat-table-ext-example/src/app/app.module.ts +0 -40
  74. package/projects/mat-table-ext-example/src/app/service/custom-table.service.spec.ts +0 -16
  75. package/projects/mat-table-ext-example/src/app/service/custom-table.service.ts +0 -18
  76. package/projects/mat-table-ext-example/src/assets/.gitkeep +0 -0
  77. package/projects/mat-table-ext-example/src/assets/data.json +0 -100003
  78. package/projects/mat-table-ext-example/src/environments/environment.prod.ts +0 -3
  79. package/projects/mat-table-ext-example/src/environments/environment.ts +0 -16
  80. package/projects/mat-table-ext-example/src/favicon.ico +0 -0
  81. package/projects/mat-table-ext-example/src/index.html +0 -14
  82. package/projects/mat-table-ext-example/src/main.ts +0 -12
  83. package/projects/mat-table-ext-example/src/polyfills.ts +0 -53
  84. package/projects/mat-table-ext-example/src/styles.scss +0 -1
  85. package/projects/mat-table-ext-example/src/test.ts +0 -26
  86. package/projects/mat-table-ext-example/tsconfig.app.json +0 -15
  87. package/projects/mat-table-ext-example/tsconfig.spec.json +0 -18
  88. package/tsconfig.json +0 -38
@@ -0,0 +1,1021 @@
1
+ import { animate, state, style, transition, trigger, } from '@angular/animations';
2
+ import { SelectionModel } from '@angular/cdk/collections';
3
+ import { moveItemInArray } from '@angular/cdk/drag-drop';
4
+ import { EventEmitter, Output, } from '@angular/core';
5
+ import { Component, Input, ViewChild, ViewEncapsulation, } from '@angular/core';
6
+ import { MatDialogConfig } from '@angular/material/dialog';
7
+ import { MatMenuTrigger } from '@angular/material/menu';
8
+ import { MatPaginator } from '@angular/material/paginator';
9
+ import { MatSort } from '@angular/material/sort';
10
+ import { MatTableDataSource } from '@angular/material/table';
11
+ import { EditingComponent } from '../lib/components/editing/editing.component';
12
+ import * as XLSX from 'xlsx';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "@angular/material/dialog";
15
+ import * as i2 from "../lib/mat-table-ext.service";
16
+ import * as i3 from "@angular/forms";
17
+ import * as i4 from "@angular/platform-browser";
18
+ import * as i5 from "@angular/material/icon";
19
+ import * as i6 from "@angular/common";
20
+ import * as i7 from "@angular/material/table";
21
+ import * as i8 from "@angular/cdk/drag-drop";
22
+ import * as i9 from "@angular/material/core";
23
+ import * as i10 from "@angular/material/button";
24
+ import * as i11 from "@angular/material/card";
25
+ import * as i12 from "@angular/material/checkbox";
26
+ import * as i13 from "@angular/material/form-field";
27
+ import * as i14 from "@angular/material/input";
28
+ import * as i15 from "@angular/material/menu";
29
+ import * as i16 from "@angular/material/paginator";
30
+ import * as i17 from "@angular/material/progress-bar";
31
+ import * as i18 from "@angular/material/select";
32
+ import * as i19 from "@angular/material/sort";
33
+ import * as i20 from "@angular/material/toolbar";
34
+ import * as i21 from "@angular/material/tooltip";
35
+ import * as i22 from "./directives/resize-column.directive";
36
+ import * as i23 from "./components/column-pinning/column-pinning.component";
37
+ import * as i24 from "./components/filter-columns-component/filter-columns-component.component";
38
+ export class MatTableExtComponent {
39
+ constructor(dialog, service, formBuildersService, domSanitizer, matIconRegistry, cdr) {
40
+ this.dialog = dialog;
41
+ this.service = service;
42
+ this.formBuildersService = formBuildersService;
43
+ this.domSanitizer = domSanitizer;
44
+ this.matIconRegistry = matIconRegistry;
45
+ this.cdr = cdr;
46
+ this.columns = [];
47
+ this.columnResizable = false;
48
+ this.stripedRows = false;
49
+ this.rowHover = false;
50
+ this.inlineRowEditing = false;
51
+ this.inCellEditing = false;
52
+ this.popupRowEditing = false;
53
+ this.enableDelete = false;
54
+ this.rowSelection = false;
55
+ this.multiRowSelection = false;
56
+ this.stickyFooter = false;
57
+ this.stickyHeader = false;
58
+ this.showFooterRow = false;
59
+ this.columnFilter = false;
60
+ this.loadingIndicator = false;
61
+ this.sorting = false;
62
+ this.showToolbar = false;
63
+ this.toolbarTitle = '';
64
+ this.tableHeight = '';
65
+ this.toolbarHeight = '50px';
66
+ this.tableWidth = '100%';
67
+ this.scrollbarH = false;
68
+ this.columnHidable = false;
69
+ this.columnPinnable = false;
70
+ this.globalSearch = false;
71
+ this.expandRows = false;
72
+ this.dndColumns = false;
73
+ this.showPaginator = true;
74
+ this.showFirstLastButtons = false;
75
+ this.exportButtonEnable = false;
76
+ this.pageSizeOptions = [10, 50, 100];
77
+ this.cellTemplateRefMap = {};
78
+ // Table outputs
79
+ this.inlineChange = new EventEmitter();
80
+ this.cellChange = new EventEmitter();
81
+ this.popupChange = new EventEmitter();
82
+ this.rowDeleted = new EventEmitter();
83
+ this.scroll = new EventEmitter();
84
+ this.selectionChanged = new EventEmitter();
85
+ this.expansionChange = new EventEmitter();
86
+ this.tableID = new Date().getTime();
87
+ this.columnPinningOptions = [];
88
+ this.exportMenuCtrl = false;
89
+ this.columnPinMenuCtrl = false;
90
+ this.hideShowMenuCtrl = false;
91
+ this.columnFilterBySelection = false;
92
+ this.rowDataTemp = {};
93
+ this.inlineEditingTemplateRefData = {};
94
+ this.displayedColumns = [];
95
+ this.showHideColumnsArray = [];
96
+ this.columnsList = [];
97
+ this.columnsArray = [];
98
+ this.headersFiltersIds = [];
99
+ this.columnsToDisplayWithExpand = [];
100
+ this.selection = new SelectionModel(false, []);
101
+ this.hiddenCtrl = new SelectionModel(true, []);
102
+ this.tableData = [];
103
+ this.filterValues = {};
104
+ this.globalFilter = '';
105
+ this.showHideFilter = '';
106
+ this.individualFilter = '';
107
+ this.toggleFilters = false;
108
+ this.hideRows = false;
109
+ this.currentRowIndex = -1;
110
+ this.currentRow = {};
111
+ this.cellEditing = {};
112
+ this.menuX = 0;
113
+ this.menuY = 0;
114
+ this.dynamicDisplayedColumns = [
115
+ { filter: false, name: 'select', show: false },
116
+ { filter: false, name: 'edit', show: false },
117
+ { filter: false, name: 'popup', show: false },
118
+ { filter: false, name: 'delete', show: false },
119
+ { filter: false, name: 'expand', show: false },
120
+ ];
121
+ this.inputPropertyKeys = [
122
+ 'dataSource',
123
+ 'columns',
124
+ 'inlineRowEditing',
125
+ 'popupRowEditing',
126
+ 'enableDelete',
127
+ 'rowSelection',
128
+ 'multiRowSelection',
129
+ 'stickyHeader',
130
+ 'stickyFooter',
131
+ 'columnFilter',
132
+ 'globalSearch',
133
+ 'expandRows',
134
+ 'sorting',
135
+ ];
136
+ /**
137
+ * @description This mapping is used to set and update changesin the table.
138
+ */
139
+ this.setPropertiesMap = {
140
+ dataSource: (value) => this.setTableDataSource(value),
141
+ columns: (value) => this.setColumnsData(value.currentValue),
142
+ inlineRowEditing: (value) => this.showHideColumn('edit', value.currentValue),
143
+ popupRowEditing: (value) => this.showHideColumn('popup', value.currentValue),
144
+ enableDelete: (value) => this.showHideColumn('delete', value.currentValue),
145
+ rowSelection: (value) => this.setRowSelection(value.currentValue),
146
+ multiRowSelection: (value) => {
147
+ this.selection = new SelectionModel(value.currentValue, []);
148
+ },
149
+ stickyHeader: (value) => {
150
+ this.stickyHeader = value.currentValue;
151
+ },
152
+ stickyFooter: (value) => {
153
+ this.stickyFooter = value.currentValue;
154
+ },
155
+ columnFilter: (value) => this.setColumnFilter(value.currentValue),
156
+ globalSearch: (value) => (this.dataSource.filterPredicate = this.createFilter()),
157
+ expandRows: (value) => {
158
+ this.loadingIndicator = true;
159
+ this.dataSource = new MatTableDataSource(this.tableData);
160
+ if (value.currentValue == true) {
161
+ if (!this.displayedColumns.includes('expand')) {
162
+ this.displayedColumns.push('expand');
163
+ this.columnsToDisplayWithExpand = [...this.displayedColumns];
164
+ }
165
+ }
166
+ else {
167
+ this.columnsToDisplayWithExpand = [...this.displayedColumns];
168
+ if (this.displayedColumns.includes('expand')) {
169
+ let index = this.displayedColumns.indexOf('expand');
170
+ this.displayedColumns.splice(index, 1);
171
+ }
172
+ this.expandedElement = null;
173
+ }
174
+ setTimeout(() => {
175
+ this.loadingIndicator = false;
176
+ }, 200);
177
+ },
178
+ sorting: (value) => (this.dataSource.sort = this.sort),
179
+ };
180
+ /**
181
+ * @description This method will take data from inline editing template and update in table data source.
182
+ * @param row updated row from inline editing template.
183
+ */
184
+ this.updateInlineTemplateData = (row) => {
185
+ this.service.selectedRow.next(row);
186
+ };
187
+ this.addIconsToRegistry();
188
+ if (this.dataSource) {
189
+ this.tableData = this.dataSource.data;
190
+ }
191
+ }
192
+ /**
193
+ *
194
+ * @param changes changes captured each time user changes property value.
195
+ */
196
+ ngOnChanges(changes) {
197
+ this.setPropertyValue(changes);
198
+ }
199
+ ngOnInit() {
200
+ if (this.dataSource) {
201
+ this.dataSource.filterPredicate = this.createFilter();
202
+ }
203
+ }
204
+ ngAfterViewInit() {
205
+ if (this.dataSource) {
206
+ this.dataSource.paginator = this.paginator;
207
+ this.dataSource.sort = this.sort;
208
+ }
209
+ }
210
+ /**
211
+ * @description checks and updates the the column's hide and show properties.
212
+ */
213
+ setColumnHideShow() {
214
+ if (this.hideShowMenuGroup !== undefined &&
215
+ this.hideShowMenuGroup !== null) {
216
+ this.updateColumnsHideShow(this.hideShowMenuGroup.value);
217
+ }
218
+ }
219
+ /**
220
+ * @description set the properties of the table.
221
+ * @param changes changes captured each time user changes property value.
222
+ */
223
+ setPropertyValue(changes) {
224
+ let keys = Object.keys(changes);
225
+ keys.forEach((property) => {
226
+ if (this.inputPropertyKeys.includes(property)) {
227
+ this.setPropertiesMap[property](changes[property]);
228
+ }
229
+ else if (property == 'showToolbar') {
230
+ if (changes['columns']) {
231
+ this.setToolbarMenuControls(changes['columns'].currentValue);
232
+ }
233
+ else {
234
+ this.setToolbarMenuControls(this.columnsArray);
235
+ }
236
+ }
237
+ });
238
+ }
239
+ /**
240
+ * @description used set data source for table.
241
+ * @param value data source value from user.
242
+ */
243
+ setTableDataSource(value) {
244
+ if (value.currentValue) {
245
+ this.tableData = value.currentValue.data;
246
+ this.dataSource = value.currentValue;
247
+ this.reCal();
248
+ }
249
+ else {
250
+ this.dataSource = new MatTableDataSource([{}]);
251
+ }
252
+ }
253
+ /**
254
+ * @description used create seletion model and set selection column visibility.
255
+ * @param value boolean value to show or hide selection Column from table.
256
+ */
257
+ setRowSelection(value) {
258
+ this.selection = new SelectionModel(true, []);
259
+ this.updateSelectionColumnVisibility(value);
260
+ }
261
+ /**
262
+ * @description create filter header row and assigns filter predicate to table data source.
263
+ * @param value boolean value to change visibility of column filter row.
264
+ */
265
+ setColumnFilter(value) {
266
+ if (value) {
267
+ let array = [];
268
+ this.columnsArray.forEach((column, i) => {
269
+ if (this.dynamicDisplayedColumns.filter((a) => a.name == column?.field)[0]
270
+ .show) {
271
+ array.push(column?.field + '_' + i);
272
+ }
273
+ });
274
+ this.headersFiltersIds = array;
275
+ this.dataSource.filterPredicate = this.createFilter();
276
+ }
277
+ else {
278
+ this.headersFiltersIds = [];
279
+ this.dataSource.filter = '';
280
+ }
281
+ this.toggleFilters = value;
282
+ }
283
+ /**
284
+ * @description This method returns the list of visible column names.
285
+ * @returns list of visible column names.
286
+ */
287
+ getDisplayedColumns() {
288
+ let list = this.dynamicDisplayedColumns
289
+ .filter((cd) => cd.show)
290
+ .map((cd) => cd.name);
291
+ return list;
292
+ }
293
+ /**
294
+ * @param menuType type of menu to open from toolbar.
295
+ * @param event mouse event to open menu on that location.
296
+ */
297
+ openMenu(menuType, event) {
298
+ this.menuX = event.clientX;
299
+ this.menuY = event.clientY;
300
+ switch (menuType) {
301
+ case 'export': {
302
+ this.exportMenuCtrl = true;
303
+ this.menuTrigger.openMenu();
304
+ break;
305
+ }
306
+ case 'hideShow': {
307
+ this.hideShowMenuCtrl = true;
308
+ this.openHideShowMenu(this.columnsArray);
309
+ break;
310
+ }
311
+ case 'columnPin': {
312
+ this.columnPinMenuCtrl = true;
313
+ this.openHideShowMenu(this.columnsArray);
314
+ break;
315
+ }
316
+ }
317
+ }
318
+ /**
319
+ * @description triggers when menu is closed and reset the required controls.
320
+ */
321
+ menuClosed() {
322
+ this.exportMenuCtrl = false;
323
+ }
324
+ /**
325
+ * @description set list of columns to display in table.
326
+ * @param columns columns array from user input.
327
+ */
328
+ setColumnsData(columns) {
329
+ if (columns.length) {
330
+ this.columnsArray = [...columns];
331
+ this.setColumnsList(columns);
332
+ }
333
+ }
334
+ /**
335
+ * @description set list of columns to display in table.
336
+ * @param columns columns array from user input with configurations.
337
+ */
338
+ setColumnsList(columns) {
339
+ this.columnsList = [];
340
+ this.displayedColumns = ['select', 'edit', 'popup', 'delete'];
341
+ let columnsArray = [];
342
+ columns.forEach((col) => {
343
+ if (typeof col?.header == 'string') {
344
+ this.columnsList.push(col?.header);
345
+ this.displayedColumns.push(col?.field);
346
+ columnsArray.push({ filter: true, name: col?.field, show: !col.hide });
347
+ }
348
+ });
349
+ this.dynamicDisplayedColumns = [
350
+ { filter: false, name: 'select', show: false },
351
+ { filter: false, name: 'edit', show: false },
352
+ { filter: false, name: 'popup', show: false },
353
+ { filter: false, name: 'delete', show: false },
354
+ ];
355
+ this.dynamicDisplayedColumns = columnsArray.concat(this.dynamicDisplayedColumns);
356
+ }
357
+ /**
358
+ * @description Take boolean value and name column and update its visibility status in table.
359
+ * @param name name of the column to set visibility.
360
+ * @param value boolean value to set visibility of the column.
361
+ */
362
+ showHideColumn(name, value) {
363
+ this.dynamicDisplayedColumns.filter((a) => a.name == name)[0].show = value;
364
+ if (this.columnFilter) {
365
+ this.setColumnFilter(true);
366
+ }
367
+ }
368
+ /**
369
+ * @description This method will position the selection column to first and also update its visibility.
370
+ * @param value value used to set visibility of the selection column.
371
+ */
372
+ updateSelectionColumnVisibility(value) {
373
+ let columnName = 'select';
374
+ let column = this.dynamicDisplayedColumns.filter((a) => a.name == columnName)[0];
375
+ let index = this.dynamicDisplayedColumns.findIndex((column) => column.name == columnName);
376
+ if (index > -1) {
377
+ this.dynamicDisplayedColumns.splice(index, 1);
378
+ this.dynamicDisplayedColumns.unshift(column);
379
+ this.dynamicDisplayedColumns.filter((column) => column.name == columnName)[0].show = value;
380
+ }
381
+ }
382
+ /**
383
+ * @description This method is used to update the position of column in columns array according to its dropped position.
384
+ * @param event CdkDragDrop used to update column position in columns array.
385
+ */
386
+ onDrop(event) {
387
+ if (this.dndColumns) {
388
+ let adjustedValue = 0;
389
+ if (this.dynamicDisplayedColumns[0].name == 'select' &&
390
+ this.dynamicDisplayedColumns[0].show == false) {
391
+ adjustedValue = 1;
392
+ }
393
+ moveItemInArray(this.dynamicDisplayedColumns, event.previousIndex + adjustedValue, event.currentIndex + adjustedValue);
394
+ }
395
+ }
396
+ /**
397
+ * @description This methohd create filter predicate function which will set search value to table filters
398
+ * for both global and individual colum filtering.
399
+ * @returns returns boolean value to filter rows in table.
400
+ */
401
+ createFilter() {
402
+ const tableFilterPredicate = (data, filter) => {
403
+ let result = true;
404
+ // search all column fields
405
+ if (this.globalFilter) {
406
+ let expression = '';
407
+ let keys = Object.keys(data);
408
+ keys.forEach((key) => {
409
+ expression =
410
+ expression +
411
+ `data.${key}.toString().trim().toLowerCase().indexOf(this.globalFilter.toLowerCase()) !== -1 ||`;
412
+ });
413
+ if (expression.charAt(expression.length - 2) +
414
+ expression.charAt(expression.length - 1) ==
415
+ '||') {
416
+ expression = expression.substring(0, expression.length - 2);
417
+ }
418
+ result = eval(expression);
419
+ }
420
+ if (!result) {
421
+ return false;
422
+ }
423
+ let searchString = JSON.parse(filter);
424
+ //search single column field
425
+ if (this.individualFilter) {
426
+ return (data[this.individualFilter]
427
+ .toString()
428
+ .trim()
429
+ .toLowerCase()
430
+ .indexOf(searchString[this.individualFilter].toString().toLowerCase()) !== -1);
431
+ }
432
+ return true;
433
+ };
434
+ return tableFilterPredicate;
435
+ }
436
+ /**
437
+ * @description assigns the search value to mat table data source to apply the filter.
438
+ * @param searchValue value to be searched from table rows.
439
+ */
440
+ applyGlobalFilter(searchValue) {
441
+ this.globalFilter = searchValue;
442
+ let columns = {};
443
+ this.columnsArray.forEach((column) => {
444
+ if (column.field)
445
+ columns[column.field] = searchValue;
446
+ });
447
+ this.dataSource.filter = JSON.stringify(columns);
448
+ }
449
+ /**
450
+ * @description This method is used to apply column based filtering
451
+ * @param searchValue value to be searched from table rows.
452
+ * @param column filter will be applied based on this column field.
453
+ */
454
+ applyColumnFilter(searchValue, column) {
455
+ this.individualFilter = column.field;
456
+ this.filterValues[column.field] = searchValue[column.field];
457
+ this.dataSource.filter = JSON.stringify(this.filterValues);
458
+ }
459
+ /**
460
+ * @description This method will take row and its index enable inline editing tools on that row.
461
+ * @param row row on which user wants to do edit.
462
+ * @param index index of the row where inline editing will be enabled.
463
+ */
464
+ enableInlineEditing(row, index) {
465
+ const rowData = {};
466
+ rowData['e' + index] = { ...row };
467
+ this.rowDataTemp = rowData;
468
+ setTimeout(() => {
469
+ this.tableData[index]['editable'] = !this.tableData[index]['editable'];
470
+ }, 0);
471
+ }
472
+ /**
473
+ * @description This method will create and return data to inline editing template.
474
+ * @param row row on which user wants to do edit.
475
+ * @param index index of the row where inline editing will be enabled.
476
+ * @param column current column of the table.
477
+ */
478
+ getInlineEditingData(row, index, column) {
479
+ this.inlineEditingTemplateRefData = {
480
+ row: { ...row },
481
+ column: { ...column },
482
+ index: index,
483
+ updateFunc: this.updateInlineTemplateData,
484
+ };
485
+ return this.inlineEditingTemplateRefData;
486
+ }
487
+ /**
488
+ * @description This method set data for in-cell editing.
489
+ * @param row row on which user wants to do edit.
490
+ * @param index index of the row where inline editing will be enabled.
491
+ */
492
+ setCellData(row, index) {
493
+ this.currentRow = { ...row };
494
+ this.currentRowIndex = index;
495
+ this.rowDataTemp['e' + index] = { ...row };
496
+ }
497
+ /**
498
+ * @description This will restore the data and cencel the inline editing.
499
+ * @param row row on which user wants to do edit.
500
+ * @param index index of the row where inline editing will be enabled.
501
+ */
502
+ cancelInlineEditing(row, index) {
503
+ this.tableData.filter((a, i) => i == index)[0]['editable'] =
504
+ !this.tableData.filter((a, i) => i == index)[0]['editable'];
505
+ this.dataSource = new MatTableDataSource(this.tableData);
506
+ this.rowDataTemp['e' + index] = {};
507
+ this.service.selectedRow.next(undefined);
508
+ }
509
+ /**
510
+ * @description This method will save and update the inline editing data and emit the update row and index.
511
+ * @param row row on which user wants to do edit.
512
+ * @param index index of the row where inline editing will be enabled.
513
+ */
514
+ saveInlineEditing(row, index) {
515
+ if (!this.inlineEditingTemplateRef) {
516
+ this.tableData[index] = { ...this.rowDataTemp['e' + index] };
517
+ row = { ...this.rowDataTemp['e' + index] };
518
+ }
519
+ else {
520
+ let changedData = this.service.selectedRow.value;
521
+ if (changedData) {
522
+ this.tableData[index] = { ...changedData };
523
+ }
524
+ }
525
+ this.dataSource = new MatTableDataSource(this.tableData);
526
+ this.rowDataTemp['e' + index] = {};
527
+ let data = {
528
+ row: row,
529
+ index: index,
530
+ };
531
+ this.inlineChange.emit(data);
532
+ this.tableData[index]['editable'] = false;
533
+ }
534
+ /**
535
+ * @description This method will save and update the cell editing data and emit the update row and index.
536
+ */
537
+ saveCellEditing() {
538
+ this.cellEditing = {};
539
+ let index = this.currentRowIndex;
540
+ if (index > -1) {
541
+ if (this.cellEditingTemplateRef) {
542
+ let changedData = this.service.selectedRow.value;
543
+ if (changedData) {
544
+ this.tableData[index] = { ...changedData };
545
+ }
546
+ }
547
+ else {
548
+ this.tableData[index] = { ...this.rowDataTemp['e' + index] };
549
+ }
550
+ this.dataSource = new MatTableDataSource(this.tableData);
551
+ this.rowDataTemp['e' + index] = {};
552
+ let data = {
553
+ row: { ...this.tableData[index] },
554
+ index: index,
555
+ };
556
+ this.currentRowIndex = -1;
557
+ this.cellChange.emit(data);
558
+ }
559
+ }
560
+ /**
561
+ * @description This method will delete the row from the given index and emit the deleted row and index.
562
+ * @param row row to be deleted.
563
+ * @param index index of the row to be deleted.
564
+ */
565
+ deleteRow(row, index) {
566
+ this.tableData.splice(index, 1);
567
+ this.dataSource = new MatTableDataSource(this.tableData);
568
+ this.dataSource.paginator = this.paginator;
569
+ this.dataSource.sort = this.sort;
570
+ this.rowDeleted.emit({ removedRow: row, fromIndex: index });
571
+ }
572
+ /**
573
+ * @description This method will expand or collapse the row and emit expand event.
574
+ * @param row row to be expanded or collapsed.
575
+ * @param expand value used to expand or collapse the row.
576
+ * @param index index of the row.
577
+ */
578
+ expandRow(row, expand, index) {
579
+ if (this.expandRows) {
580
+ this.expansionChange.emit({ data: row, expanded: expand, index: index });
581
+ this.expandedElement = this.expandedElement === row ? null : row;
582
+ }
583
+ }
584
+ /**
585
+ * @description This method is used to set data for popup component and open editing dialog.
586
+ * @param row row which used want to edit.
587
+ */
588
+ openEditingDialog(row) {
589
+ const dialogConfig = new MatDialogConfig();
590
+ dialogConfig.disableClose = true;
591
+ dialogConfig.width = '40%';
592
+ dialogConfig.height = '70%';
593
+ dialogConfig.maxWidth = '100%';
594
+ let rowData = { ...row };
595
+ dialogConfig.data = {
596
+ row: rowData,
597
+ columns: [...this.columnsArray],
598
+ templateRef: this.popupEditingTemplateRef,
599
+ };
600
+ this.dialog
601
+ .open(EditingComponent, dialogConfig)
602
+ .afterClosed()
603
+ .subscribe((data) => {
604
+ let index = this.tableData.indexOf(row);
605
+ if (data && index > -1) {
606
+ this.tableData[index] = data;
607
+ this.dataSource = new MatTableDataSource(this.tableData);
608
+ let dataChange = {
609
+ row: data,
610
+ index: index,
611
+ };
612
+ this.popupChange.emit(dataChange);
613
+ }
614
+ });
615
+ }
616
+ /**
617
+ * @description used to check whether all rows are selected.
618
+ */
619
+ isAllSelected() {
620
+ const numSelected = this.selection.selected.length;
621
+ const numRows = this.dataSource.data.length;
622
+ return numSelected === numRows;
623
+ }
624
+ /**
625
+ * @description this method is used to toggle the all and no rows selection.
626
+ */
627
+ toggleAllRows() {
628
+ if (this.isAllSelected()) {
629
+ this.selection.clear();
630
+ return;
631
+ }
632
+ this.selection.select(...this.dataSource.data);
633
+ }
634
+ /**
635
+ * @description This method is used return aria-label for selection column checkboxs.
636
+ * @param row row from table.
637
+ * @returns labels for selection column checkboxs.
638
+ */
639
+ checkboxLabel(row) {
640
+ if (!row) {
641
+ return `${this.isAllSelected() ? 'deselect' : 'select'} all`;
642
+ }
643
+ return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
644
+ }
645
+ /**
646
+ * @description create form control for columns for hiding and and pinning purpose
647
+ * @param columns list of columns to be displayed
648
+ */
649
+ setToolbarMenuControls(columns) {
650
+ if (columns.length > 0 && this.showToolbar) {
651
+ const group = this.formBuildersService.group({});
652
+ columns.forEach((column) => {
653
+ const control = this.formBuildersService.control(true);
654
+ group.addControl(column.field, control);
655
+ });
656
+ this.hideShowMenuGroup = group;
657
+ }
658
+ }
659
+ /**
660
+ * @param column current column
661
+ * @param event mouse event used to set the menu position
662
+ */
663
+ openPinnablePropertyMenu(column, event) {
664
+ this.menuX = event.clientX;
665
+ this.menuY = event.clientY;
666
+ let options = [
667
+ {
668
+ label: 'Pin Left',
669
+ value: 'left',
670
+ selected: false,
671
+ field: column.field,
672
+ },
673
+ {
674
+ label: 'Pin Right',
675
+ value: 'right',
676
+ selected: false,
677
+ field: column.field,
678
+ },
679
+ { label: 'No Pin', value: null, selected: false, field: column.field },
680
+ ];
681
+ if (column.pinned && column.pinned !== null) {
682
+ options.forEach((opt) => {
683
+ if (opt.value === column.pinned) {
684
+ opt.selected = true;
685
+ }
686
+ });
687
+ }
688
+ else if (column.pinned == null || column.pinned == 'null') {
689
+ options[2].selected = true;
690
+ }
691
+ this.columnPinningOptions = options;
692
+ this.columnMenuTrigger.openMenu();
693
+ }
694
+ /**
695
+ * @description This method is used to reset menu checks when required.
696
+ */
697
+ resetMenuChecks() {
698
+ this.hideShowMenuCtrl = false;
699
+ this.showHideColumnsArray = [];
700
+ this.columnPinMenuCtrl = false;
701
+ this.columnPinningOptions = [];
702
+ }
703
+ /**
704
+ * @description This method is used to filter columns for menus like pinning or hide show menu.
705
+ * @param value search value to filter colunms
706
+ */
707
+ filterColumns(value) {
708
+ if (value !== '') {
709
+ this.showHideColumnsArray = this.columnsArray.filter((col) => {
710
+ return col.header.toLowerCase().includes(value.toLowerCase());
711
+ });
712
+ }
713
+ else {
714
+ this.showHideColumnsArray = this.columnsArray;
715
+ }
716
+ }
717
+ /**
718
+ * @description This method is used to open hide show column menu.
719
+ * @param columns columns array to display in hide show menu.
720
+ */
721
+ openHideShowMenu(columns) {
722
+ this.showHideColumnsArray = [...columns];
723
+ this.columnMenuTrigger.openMenu();
724
+ }
725
+ /**
726
+ * @param values columns
727
+ */
728
+ updateColumnsHideShow(values) {
729
+ let keys = Object.keys(values);
730
+ keys.forEach((key) => {
731
+ this.showHideColumn(key, values[key]);
732
+ });
733
+ }
734
+ /**
735
+ * @description This method is called when the table rows are scrolled.
736
+ * @param event scroll event
737
+ */
738
+ onScroll(event) {
739
+ this.scroll.emit(event);
740
+ }
741
+ /**
742
+ * @param row row to be toggled
743
+ * @param index index of toggled row
744
+ */
745
+ setSelectedRows(row, index) {
746
+ this.selection.toggle(row);
747
+ if (this.selection.isSelected(row)) {
748
+ this.selectionChanged.emit({ row: row, index: index, isSelected: true });
749
+ }
750
+ else {
751
+ this.selectionChanged.emit({ row: row, index: index, isSelected: false });
752
+ }
753
+ }
754
+ /**
755
+ * @description This method is used to display all hidden rows.
756
+ */
757
+ showHiddenRows() {
758
+ this.hideRows = false;
759
+ this.selection.clear();
760
+ this.hiddenCtrl.clear();
761
+ }
762
+ /**
763
+ * @description This method is used to hide all selected rows.
764
+ */
765
+ hideSelectedRows() {
766
+ if (!this.selection.isEmpty()) {
767
+ let values = [...this.selection.selected];
768
+ values.forEach((value) => {
769
+ if (!this.hiddenCtrl.isSelected(value)) {
770
+ this.hiddenCtrl.toggle(value);
771
+ }
772
+ });
773
+ this.selection.clear();
774
+ this.hideRows = true;
775
+ }
776
+ }
777
+ /**
778
+ * @description This method is used to recalculate the required values for table.
779
+ */
780
+ reCal() {
781
+ if (this.showPaginator) {
782
+ this.dataSource.paginator = this.paginator;
783
+ }
784
+ if (this.sorting) {
785
+ this.dataSource.sort = this.sort;
786
+ }
787
+ if (this.columnFilter) {
788
+ this.dataSource.filterPredicate = this.createFilter();
789
+ }
790
+ }
791
+ /**
792
+ * @description This method is called in constructor method to add SVGs into icon registration.
793
+ */
794
+ addIconsToRegistry() {
795
+ let y = this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/pinRight.svg`);
796
+ let iconNames = ['pinLeft', 'pinRight', 'pinNone', 'pinned', 'pinIcon'];
797
+ iconNames.forEach((icon) => {
798
+ this.matIconRegistry.addSvgIcon(icon, this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/${icon}.svg`));
799
+ });
800
+ }
801
+ /**
802
+ * @description This method is used to export table data.
803
+ * @param type type of file to be exported.
804
+ */
805
+ exportTable(type) {
806
+ var element = document.getElementById('matTableExt' + this.tableID);
807
+ var ws = XLSX.utils.table_to_sheet(element);
808
+ ws = this.writeSheetData(ws);
809
+ const wb = XLSX.utils.book_new();
810
+ XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
811
+ XLSX.writeFile(wb, `tablesheets.${type}`);
812
+ }
813
+ /**
814
+ * @description This method is used to split name of filter row header to get index.
815
+ * @param value value to be splited for index.
816
+ * @returns Will return index of column from value.
817
+ */
818
+ returnIndex(value) {
819
+ return Number(value.split('_')[1]);
820
+ }
821
+ /**
822
+ * @description This method is used to manage column filtering, expanded data for exporting.
823
+ * @param ws work sheet
824
+ * @returns custom generated worksheet to be used in export.
825
+ */
826
+ writeSheetData(ws) {
827
+ let displayedColumns = this.getDisplayedColumns();
828
+ var nMerges = this.getMergeIndex(ws['!merges'] || []);
829
+ var merges = ws['!merges'] || [];
830
+ let data = {
831
+ '!cols': [],
832
+ '!rows': [],
833
+ '!merges': nMerges,
834
+ };
835
+ var range = XLSX.utils.decode_range(ws['!ref'] || '');
836
+ let extracolumns = ['popup', 'delete', 'select', 'edit'];
837
+ let keys = Object.keys(ws);
838
+ let nKey = 'A';
839
+ keys.forEach((key, i) => {
840
+ if (ws[key]?.v && typeof ws[key]?.v === 'string') {
841
+ if (!extracolumns.includes(ws[key].v.toLowerCase()) &&
842
+ displayedColumns.includes(ws[key].v.toLowerCase())) {
843
+ let lastRowIndex = range?.e?.r;
844
+ data[key] = ws[key];
845
+ let chr = key.charAt(0);
846
+ for (let j = 2; j <= lastRowIndex; j++) {
847
+ if (ws[chr + (j + 1)] !== undefined &&
848
+ (typeof ws[chr + (j + 1)].v === 'string' ||
849
+ typeof ws[chr + (j + 1)].v === 'number')) {
850
+ data[nKey + j] = ws[chr + (j + 1)];
851
+ }
852
+ }
853
+ nKey = String.fromCharCode(nKey.charCodeAt(0) + 1);
854
+ }
855
+ }
856
+ });
857
+ if (this.rowSelection) {
858
+ let chr = 'A';
859
+ for (let i = 1; i < range.e.c + 1; i++) {
860
+ data[chr + 1] = data[String.fromCharCode(chr.charCodeAt(0) + 1) + 1];
861
+ chr = String.fromCharCode(chr.charCodeAt(0) + 1);
862
+ if (i == range.e.c) {
863
+ data[chr + 1] = undefined;
864
+ }
865
+ }
866
+ }
867
+ if (this.rowSelection && this.expandRows) {
868
+ merges.forEach((merge) => {
869
+ data['A' + merge.s.r] = ws['A' + (merge.s.r + 1)];
870
+ });
871
+ }
872
+ range.e.r--;
873
+ let nRef = XLSX.utils.encode_range(range);
874
+ data['!ref'] = nRef;
875
+ data['!fullref'] = nRef;
876
+ return data;
877
+ }
878
+ getMergeIndex(merges) {
879
+ var arr = [];
880
+ merges.forEach((element) => {
881
+ arr.push({
882
+ e: {
883
+ r: element.e.r == 0 ? element.e.r : element.e.r - 1,
884
+ c: element.e.c,
885
+ },
886
+ s: {
887
+ r: element.s.r == 0 ? element.s.r : element.s.r - 1,
888
+ c: element.s.c,
889
+ },
890
+ });
891
+ });
892
+ return arr;
893
+ }
894
+ }
895
+ MatTableExtComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: MatTableExtComponent, deps: [{ token: i1.MatDialog }, { token: i2.MatTableExtService }, { token: i3.FormBuilder }, { token: i4.DomSanitizer }, { token: i5.MatIconRegistry }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
896
+ MatTableExtComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: MatTableExtComponent, selector: "mat-table-ext", inputs: { dataSource: "dataSource", columns: "columns", columnResizable: "columnResizable", stripedRows: "stripedRows", rowHover: "rowHover", inlineRowEditing: "inlineRowEditing", inCellEditing: "inCellEditing", popupRowEditing: "popupRowEditing", enableDelete: "enableDelete", rowSelection: "rowSelection", multiRowSelection: "multiRowSelection", stickyFooter: "stickyFooter", stickyHeader: "stickyHeader", showFooterRow: "showFooterRow", columnFilter: "columnFilter", loadingIndicator: "loadingIndicator", sorting: "sorting", showToolbar: "showToolbar", toolbarTitle: "toolbarTitle", tableHeight: "tableHeight", toolbarHeight: "toolbarHeight", tableWidth: "tableWidth", scrollbarH: "scrollbarH", toolbarTemplate: "toolbarTemplate", columnHidable: "columnHidable", columnPinnable: "columnPinnable", globalSearch: "globalSearch", expandRows: "expandRows", dndColumns: "dndColumns", showPaginator: "showPaginator", showFirstLastButtons: "showFirstLastButtons", exportButtonEnable: "exportButtonEnable", pageSizeOptions: "pageSizeOptions", toolbarTemplateRef: "toolbarTemplateRef", headerTemplateRef: "headerTemplateRef", cellTemplateRef: "cellTemplateRef", expansionTemplateRef: "expansionTemplateRef", popupEditingTemplateRef: "popupEditingTemplateRef", inlineEditingTemplateRef: "inlineEditingTemplateRef", cellEditingTemplateRef: "cellEditingTemplateRef", cellTemplateRefMap: "cellTemplateRefMap" }, outputs: { inlineChange: "inlineChange", cellChange: "cellChange", popupChange: "popupChange", rowDeleted: "rowDeleted", scroll: "scroll", selectionChanged: "selectionChanged", expansionChange: "expansionChange" }, viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: MatMenuTrigger, descendants: true }, { propertyName: "columnMenuTrigger", first: true, predicate: ["columnMenuTrigger"], descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mat-card class=\"main-table-ext-container mat-elevation-z8\" [style.width]=\"tableWidth\">\r\n <mat-form-field class=\"global-search-field\" appearance=\"fill\" *ngIf=\"globalSearch\">\r\n <mat-label>Search</mat-label>\r\n <input matInput [ngModel]=\"globalFilter\" (ngModelChange)=\"applyGlobalFilter($event)\" placeholder=\"Ex. Mia\" #input>\r\n </mat-form-field>\r\n <mat-toolbar class=\"toolbar-container\" *ngIf=\"showToolbar\" [style.height]=\"toolbarHeight?toolbarHeight:'50px'\">\r\n <span class=\"toolbar-title\" *ngIf=\"toolbarTitle\">{{toolbarTitle}}</span>\r\n <ng-container *ngIf=\"toolbarTemplateRef\" [ngTemplateOutlet]=\"toolbarTemplateRef\"></ng-container>\r\n <span class=\"example-spacer\"></span>\r\n <ng-container *ngIf=\"rowSelection || multiRowSelection\">\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"hideSelectedRows()\">\r\n Hide Rows\r\n </button>\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"showHiddenRows()\">\r\n Show All Rows\r\n </button>\r\n </ng-container>\r\n <button *ngIf=\"columnHidable\" class=\"hide-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('hideShow',$event)\" matTooltip=\"Column Visibility\" matTooltipPosition=\"above\">\r\n <mat-icon>visibility</mat-icon>\r\n </button>\r\n <button *ngIf=\"columnPinnable\" class=\"pin-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('columnPin',$event)\" matTooltip=\"Column Pinning\">\r\n <mat-icon svgIcon=\"pinIcon\"></mat-icon>\r\n </button>\r\n <button *ngIf=\"exportButtonEnable\" class=\"export-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('export',$event)\" matTooltip=\"Table Data Export\">\r\n <mat-icon>import_export</mat-icon> <span>Export</span>\r\n <mat-icon>expand_more</mat-icon>\r\n </button>\r\n <div style=\"visibility: hidden; position:fixed\" [matMenuTriggerFor]=\"menu\" [style.left.px]=\"menuX\"\r\n [style.top.px]=\"menuY\"></div>\r\n </mat-toolbar>\r\n <mat-menu #menu=\"matMenu\" (closed)=\"menuClosed()\" id=\"exportMenu\">\r\n <ng-container *ngIf=\"exportMenuCtrl\">\r\n <mat-option (click)=\"exportTable('xlsx')\">Export to Excel</mat-option>\r\n <mat-option (click)=\"exportTable('csv')\">Export to CSV</mat-option>\r\n </ng-container>\r\n </mat-menu>\r\n <div style=\"visibility: hidden; position:fixed\" #columnMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"columnMenu\"\r\n [style.left.px]=\"menuX\" [style.top.px]=\"menuY\">\r\n </div>\r\n <mat-menu #columnMenu=\"matMenu\" (closed)=\"resetMenuChecks()\">\r\n <div class=\"toolbar-menu-container\" *ngIf=\"hideShowMenuCtrl\" [formGroup]=\"hideShowMenuGroup\"\r\n (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Visible Columns</h4>\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <div class=\"showHide-menu-columns-list\">\r\n <div class=\"toolbar-menu-item\" *ngFor=\"let column of showHideColumnsArray\">\r\n <mat-checkbox color=\"primary\" class=\"toolbar-menu-checkbox\" style=\"width: max-content;\"\r\n [formControlName]=\"column.field\" (change)=\"setColumnHideShow()\">{{column.header}}</mat-checkbox>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"toolbar-menu-container\" *ngIf=\"columnPinMenuCtrl\" (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Pin Columns</h4>\r\n <form class=\"example-form\">\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n </form>\r\n <div class=\"showHide-menu-columns-list\">\r\n <app-column-pinning [columns]=\"showHideColumnsArray\"></app-column-pinning>\r\n </div>\r\n </div>\r\n </mat-menu>\r\n\r\n <mat-progress-bar *ngIf=\"loadingIndicator\" mode=\"indeterminate\"></mat-progress-bar>\r\n <section id=\"tableContainer\" class=\"mat-table-ext-container\" (scroll)=\"onScroll($event)\"\r\n [style.height]=\"tableHeight ? tableHeight :'max-content'\">\r\n <table mat-table [id]=\"'matTableExt'+tableID\" [dataSource]=\"dataSource\" matSort cdkDropList\r\n cdkDropListOrientation=\"horizontal\" multiTemplateDataRows (cdkDropListDropped)=\"onDrop($event)\"\r\n (click)=\"saveCellEditing()\" [style.width]=\"scrollbarH?'max-content':'100%'\">\r\n <!-- Row selection column -->\r\n <ng-container matColumnDef=\"select\">\r\n <th mat-header-cell *matHeaderCellDef cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\">\r\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\r\n [checked]=\"selection.hasValue() && isAllSelected()\"\r\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\" [aria-label]=\"checkboxLabel()\">\r\n </mat-checkbox>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i = dataIndex\">\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? setSelectedRows(row,i) : null\"\r\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\r\n </mat-checkbox>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n </ng-container>\r\n <!--dynamic columns are being generated here-->\r\n <div matColumnDef=\"{{column['field']}}\" [sticky]=\"column.pinned == 'left' ? true:false\"\r\n [stickyEnd]=\"column.pinned == 'right' ? true:false\" *ngFor=\"let column of columnsArray; let i = index\">\r\n <th mat-header-cell *matHeaderCellDef [style.width]=\"column.width\" [style.maxWidth]=\"column.maxWidth\"\r\n [style.minWidth]=\"column.minWidth\" cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\"\r\n [columnsResizable]=\"columnResizable\" [index]=\"i\">\r\n <span *ngIf=\"!headerTemplateRef\" matTooltip=\"{{column.headerTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.headerTooltip?.tooltipPosition!\" mat-sort-header\r\n [disabled]=\"!sorting || column.disabled === true\">{{column.header}}</span>\r\n <ng-container *ngIf=\"headerTemplateRef\" [ngTemplateOutlet]=\"headerTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n <ng-container *ngIf=\"column.headerTemplate\" [ngTemplateOutlet]=\"column.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row ;let i=dataIndex\">\r\n <div *ngIf=\"!row.editable && !cellEditing[i +'_'+column.field]\"\r\n (dblclick)=\"cellEditing[i +'_'+column.field] = inCellEditing;setCellData(row,i)\"\r\n matTooltip=\"{{column.cellTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.cellTooltip?.tooltipPosition!\">\r\n <span\r\n *ngIf=\"!cellTemplateRef && !column?.cellTemplate && !cellTemplateRefMap[column.field]\">{{row[column.field]}}</span>\r\n <ng-container *ngIf=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"!cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && !column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRef\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"row.editable || cellEditing[i +'_'+column.field]\" (click)=\"$event.stopPropagation()\">\r\n <ng-container *ngIf=\"inlineEditingTemplateRef && !cellEditing[i +'_'+column.field]\"\r\n [ngTemplateOutlet]=\"inlineEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"cellEditingTemplateRef && !(row.editable)\"\r\n [ngTemplateOutlet]=\"cellEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"!inlineEditingTemplateRef && (row.editable) && rowDataTemp['e'+i]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field style=\"width: 100%;\" *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cellEditingTemplateRef && cellEditing[i +'_'+column.field]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n </div>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef> {{column.footerText}} </td>\r\n </ng-container>\r\n </div>\r\n <ng-container matColumnDef=\"edit\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Edit </th>\r\n <td mat-cell *matCellDef=\"let row; let i = dataIndex\" class=\"inline-edit-column-cell\">\r\n <mat-icon class=\"edit-column-icons\" *ngIf=\"!row.editable && !row.editmodal\" aria-hidden=\"false\"\r\n (click)=\"enableInlineEditing(row,i)\" fontIcon=\"edit_note\">\r\n </mat-icon>\r\n <div class=\"inline-editing-controls\" *ngIf=\"row.editable && !row.editmodal\">\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"saveInlineEditing(row,i)\"\r\n fontIcon=\"done\"></mat-icon>\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"cancelInlineEditing(row,i)\"\r\n fontIcon=\"close\"></mat-icon>\r\n </div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef> edit </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"popup\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Popup\r\n </th>\r\n <td mat-cell *matCellDef=\"let row; let i = index\">\r\n <mat-icon aria-hidden=\"false\" (click)=\"openEditingDialog(row)\" fontIcon=\"edit\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"delete\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Delete\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i=dataIndex\">\r\n <mat-icon (click)=\"deleteRow(row,i)\" aria-hidden=\"false\" aria-label=\"Example home icon\"\r\n fontIcon=\"delete\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->\r\n <ng-container *ngIf=\"expandRows\" matColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let element;let i=dataIndex \"\r\n [attr.colspan]=\"columnsToDisplayWithExpand.length\">\r\n <div class=\"example-element-detail\"\r\n [@detailExpand]=\"element == expandedElement ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"expansionTemplateRef\" [ngTemplateOutlet]=\"expansionTemplateRef\"\r\n [ngTemplateOutletContext]=\"{$explicit:element,row:element,index:i}\">\r\n </ng-container>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let ids of headersFiltersIds; let i=index\" [matColumnDef]=\"ids\">\r\n <th mat-header-cell *matHeaderCellDef>\r\n <div class=\"filters-container\" [class.animate]=\"toggleFilters\">\r\n <app-filter-columns-component [obj]=\"columnsArray[returnIndex(ids)]\"\r\n (filterOutput)=\"applyColumnFilter($event,columnsArray[returnIndex(ids)])\"></app-filter-columns-component>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\" getDisplayedColumns(); sticky: stickyHeader\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns:getDisplayedColumns(); let i=dataIndex;\" class=\"data-row\"\r\n [ngClass]=\"{'data-row':expandRows,'stripedRows':(stripedRows && i % 2 == 1),'hoverClass':rowHover, 'hidden':hiddenCtrl.isSelected(row) && hideRows,'example-expanded-row':expandedElement === row}\"\r\n (click)=\"expandRow(row, row !== expandedElement,i)\">\r\n </tr>\r\n <tr style=\"height: 0px;\" mat-header-row class=\"no-default-height\" *matHeaderRowDef=\"headersFiltersIds\">\r\n </tr>\r\n <ng-container *ngIf=\"expandRows\">\r\n <tr style=\"height: 0px;\" mat-row *matRowDef=\"let row; columns: ['expandedDetail']\"\r\n [ngClass]=\"{'example-detail-row': (expandRows && row === expandedElement),'expand-row':row !== expandedElement}\">\r\n </tr>\r\n </ng-container>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <tr mat-footer-row *matFooterRowDef=\"getDisplayedColumns(); sticky: stickyFooter\"></tr>\r\n </ng-container>\r\n </table>\r\n </section>\r\n <mat-paginator *ngIf=\"showPaginator\" [pageSizeOptions]=\"pageSizeOptions\"\r\n [showFirstLastButtons]=\"showFirstLastButtons\">\r\n </mat-paginator>\r\n</mat-card>", styles: ["table{min-width:100%}.mat-table-sticky-border-elem-right{border-left:1px solid #e0e0e0}.mat-table-sticky-border-elem-left{border-right:1px solid #e0e0e0}tr.example-detail-row{display:table-row!important}.example-element-detail{overflow:hidden;display:flex}.hidden{display:none}.stripedRows{background:#eaeaea!important}.hoverClass:hover{background:#dbdbdb!important}.filters-container{overflow:hidden;max-height:0px;transition:max-height .5s ease-in-out}.animate{max-height:50px!important}.resize-handle{display:inline-block;border-right:2px solid rgb(140,140,140);position:absolute;top:0;right:0;height:100%;cursor:col-resize;opacity:0}.resize-handle:hover{width:20px}table th:hover .resize-handle{opacity:1;transition:.3s ease-in-out}.mat-table.resizing{-webkit-user-select:none;user-select:none;cursor:col-resize}.mat-table .mat-header-cell{position:relative}.mat-table .mat-header-cell:not(:last-child) .resize-holder{cursor:col-resize;width:20px;height:100%;position:absolute;right:-10px;top:0;z-index:1}.toolbar-container{display:flex;padding:0 15px;gap:1rem;grid-auto-rows:10px;justify-content:flex-end;align-items:center}.mat-table-ext-container{width:100%;max-width:100%;overflow:auto}.column-headers{font-family:Roboto,Helvetica Neue,sans-serif}.example-spacer{flex:1 1 auto}.export-button .mat-button-wrapper{display:flex!important;width:8em;justify-content:space-around;align-items:center}.toolbar-menu-container{display:flex;flex-direction:column;margin:auto .8em;width:15em;height:20em}.toolbar-menu-item{display:flex;height:3em}.toolbar-menu-checkbox{margin-left:8%}.toolbar-menu-checkbox.mat-checkbox{width:max-content;display:flex;align-items:center}.hide-button .mat-button-wrapper,.pin-button .mat-button-wrapper{display:flex!important;width:5em;justify-content:space-around;align-items:center}.hide-button,.pin-button,.export-button{height:3em;border:2px solid currentColor!important}.showHide-menu-columns-list{height:10em;max-height:10em;overflow-y:auto}mat-card.main-table-ext-container{padding:0}.main-table-ext-container{margin:10px}.mat-column-select{width:50px!important}.data-row td,.example-expanded-row td{border-bottom-width:0!important}.action-column-cells{width:40px;height:inherit}.inline-editing-controls{display:flex}.global-search-field{width:-webkit-fill-available}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i7.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i7.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i7.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i7.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i7.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i7.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i7.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i7.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i7.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i7.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i7.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i7.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i7.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i7.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i8.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i8.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i10.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i11.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i13.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i13.MatLabel, selector: "mat-label" }, { kind: "directive", type: i14.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i15.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "directive", type: i15.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i16.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i17.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i18.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "directive", type: i19.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i19.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i20.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i21.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i22.ResizeColumnDirective, selector: "[columnsResizable]", inputs: ["columnsResizable", "index"] }, { kind: "component", type: i23.ColumnPinningComponent, selector: "app-column-pinning", inputs: ["columns"], outputs: ["columnsChanged"] }, { kind: "component", type: i24.FilterColumnsComponentComponent, selector: "app-filter-columns-component", inputs: ["obj"], outputs: ["filterOutput"] }], animations: [
897
+ trigger('detailExpand', [
898
+ state('collapsed', style({ height: '0px', minHeight: '0' })),
899
+ state('expanded', style({ height: '*' })),
900
+ transition('expanded <=> collapsed', animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
901
+ ]),
902
+ ], encapsulation: i0.ViewEncapsulation.None });
903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: MatTableExtComponent, decorators: [{
904
+ type: Component,
905
+ args: [{ selector: 'mat-table-ext', encapsulation: ViewEncapsulation.None, animations: [
906
+ trigger('detailExpand', [
907
+ state('collapsed', style({ height: '0px', minHeight: '0' })),
908
+ state('expanded', style({ height: '*' })),
909
+ transition('expanded <=> collapsed', animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
910
+ ]),
911
+ ], template: "<mat-card class=\"main-table-ext-container mat-elevation-z8\" [style.width]=\"tableWidth\">\r\n <mat-form-field class=\"global-search-field\" appearance=\"fill\" *ngIf=\"globalSearch\">\r\n <mat-label>Search</mat-label>\r\n <input matInput [ngModel]=\"globalFilter\" (ngModelChange)=\"applyGlobalFilter($event)\" placeholder=\"Ex. Mia\" #input>\r\n </mat-form-field>\r\n <mat-toolbar class=\"toolbar-container\" *ngIf=\"showToolbar\" [style.height]=\"toolbarHeight?toolbarHeight:'50px'\">\r\n <span class=\"toolbar-title\" *ngIf=\"toolbarTitle\">{{toolbarTitle}}</span>\r\n <ng-container *ngIf=\"toolbarTemplateRef\" [ngTemplateOutlet]=\"toolbarTemplateRef\"></ng-container>\r\n <span class=\"example-spacer\"></span>\r\n <ng-container *ngIf=\"rowSelection || multiRowSelection\">\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"hideSelectedRows()\">\r\n Hide Rows\r\n </button>\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"showHiddenRows()\">\r\n Show All Rows\r\n </button>\r\n </ng-container>\r\n <button *ngIf=\"columnHidable\" class=\"hide-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('hideShow',$event)\" matTooltip=\"Column Visibility\" matTooltipPosition=\"above\">\r\n <mat-icon>visibility</mat-icon>\r\n </button>\r\n <button *ngIf=\"columnPinnable\" class=\"pin-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('columnPin',$event)\" matTooltip=\"Column Pinning\">\r\n <mat-icon svgIcon=\"pinIcon\"></mat-icon>\r\n </button>\r\n <button *ngIf=\"exportButtonEnable\" class=\"export-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('export',$event)\" matTooltip=\"Table Data Export\">\r\n <mat-icon>import_export</mat-icon> <span>Export</span>\r\n <mat-icon>expand_more</mat-icon>\r\n </button>\r\n <div style=\"visibility: hidden; position:fixed\" [matMenuTriggerFor]=\"menu\" [style.left.px]=\"menuX\"\r\n [style.top.px]=\"menuY\"></div>\r\n </mat-toolbar>\r\n <mat-menu #menu=\"matMenu\" (closed)=\"menuClosed()\" id=\"exportMenu\">\r\n <ng-container *ngIf=\"exportMenuCtrl\">\r\n <mat-option (click)=\"exportTable('xlsx')\">Export to Excel</mat-option>\r\n <mat-option (click)=\"exportTable('csv')\">Export to CSV</mat-option>\r\n </ng-container>\r\n </mat-menu>\r\n <div style=\"visibility: hidden; position:fixed\" #columnMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"columnMenu\"\r\n [style.left.px]=\"menuX\" [style.top.px]=\"menuY\">\r\n </div>\r\n <mat-menu #columnMenu=\"matMenu\" (closed)=\"resetMenuChecks()\">\r\n <div class=\"toolbar-menu-container\" *ngIf=\"hideShowMenuCtrl\" [formGroup]=\"hideShowMenuGroup\"\r\n (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Visible Columns</h4>\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <div class=\"showHide-menu-columns-list\">\r\n <div class=\"toolbar-menu-item\" *ngFor=\"let column of showHideColumnsArray\">\r\n <mat-checkbox color=\"primary\" class=\"toolbar-menu-checkbox\" style=\"width: max-content;\"\r\n [formControlName]=\"column.field\" (change)=\"setColumnHideShow()\">{{column.header}}</mat-checkbox>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"toolbar-menu-container\" *ngIf=\"columnPinMenuCtrl\" (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Pin Columns</h4>\r\n <form class=\"example-form\">\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n </form>\r\n <div class=\"showHide-menu-columns-list\">\r\n <app-column-pinning [columns]=\"showHideColumnsArray\"></app-column-pinning>\r\n </div>\r\n </div>\r\n </mat-menu>\r\n\r\n <mat-progress-bar *ngIf=\"loadingIndicator\" mode=\"indeterminate\"></mat-progress-bar>\r\n <section id=\"tableContainer\" class=\"mat-table-ext-container\" (scroll)=\"onScroll($event)\"\r\n [style.height]=\"tableHeight ? tableHeight :'max-content'\">\r\n <table mat-table [id]=\"'matTableExt'+tableID\" [dataSource]=\"dataSource\" matSort cdkDropList\r\n cdkDropListOrientation=\"horizontal\" multiTemplateDataRows (cdkDropListDropped)=\"onDrop($event)\"\r\n (click)=\"saveCellEditing()\" [style.width]=\"scrollbarH?'max-content':'100%'\">\r\n <!-- Row selection column -->\r\n <ng-container matColumnDef=\"select\">\r\n <th mat-header-cell *matHeaderCellDef cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\">\r\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\r\n [checked]=\"selection.hasValue() && isAllSelected()\"\r\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\" [aria-label]=\"checkboxLabel()\">\r\n </mat-checkbox>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i = dataIndex\">\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? setSelectedRows(row,i) : null\"\r\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\r\n </mat-checkbox>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n </ng-container>\r\n <!--dynamic columns are being generated here-->\r\n <div matColumnDef=\"{{column['field']}}\" [sticky]=\"column.pinned == 'left' ? true:false\"\r\n [stickyEnd]=\"column.pinned == 'right' ? true:false\" *ngFor=\"let column of columnsArray; let i = index\">\r\n <th mat-header-cell *matHeaderCellDef [style.width]=\"column.width\" [style.maxWidth]=\"column.maxWidth\"\r\n [style.minWidth]=\"column.minWidth\" cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\"\r\n [columnsResizable]=\"columnResizable\" [index]=\"i\">\r\n <span *ngIf=\"!headerTemplateRef\" matTooltip=\"{{column.headerTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.headerTooltip?.tooltipPosition!\" mat-sort-header\r\n [disabled]=\"!sorting || column.disabled === true\">{{column.header}}</span>\r\n <ng-container *ngIf=\"headerTemplateRef\" [ngTemplateOutlet]=\"headerTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n <ng-container *ngIf=\"column.headerTemplate\" [ngTemplateOutlet]=\"column.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row ;let i=dataIndex\">\r\n <div *ngIf=\"!row.editable && !cellEditing[i +'_'+column.field]\"\r\n (dblclick)=\"cellEditing[i +'_'+column.field] = inCellEditing;setCellData(row,i)\"\r\n matTooltip=\"{{column.cellTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.cellTooltip?.tooltipPosition!\">\r\n <span\r\n *ngIf=\"!cellTemplateRef && !column?.cellTemplate && !cellTemplateRefMap[column.field]\">{{row[column.field]}}</span>\r\n <ng-container *ngIf=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"!cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && !column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRef\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"row.editable || cellEditing[i +'_'+column.field]\" (click)=\"$event.stopPropagation()\">\r\n <ng-container *ngIf=\"inlineEditingTemplateRef && !cellEditing[i +'_'+column.field]\"\r\n [ngTemplateOutlet]=\"inlineEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"cellEditingTemplateRef && !(row.editable)\"\r\n [ngTemplateOutlet]=\"cellEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"!inlineEditingTemplateRef && (row.editable) && rowDataTemp['e'+i]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field style=\"width: 100%;\" *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cellEditingTemplateRef && cellEditing[i +'_'+column.field]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n </div>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef> {{column.footerText}} </td>\r\n </ng-container>\r\n </div>\r\n <ng-container matColumnDef=\"edit\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Edit </th>\r\n <td mat-cell *matCellDef=\"let row; let i = dataIndex\" class=\"inline-edit-column-cell\">\r\n <mat-icon class=\"edit-column-icons\" *ngIf=\"!row.editable && !row.editmodal\" aria-hidden=\"false\"\r\n (click)=\"enableInlineEditing(row,i)\" fontIcon=\"edit_note\">\r\n </mat-icon>\r\n <div class=\"inline-editing-controls\" *ngIf=\"row.editable && !row.editmodal\">\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"saveInlineEditing(row,i)\"\r\n fontIcon=\"done\"></mat-icon>\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"cancelInlineEditing(row,i)\"\r\n fontIcon=\"close\"></mat-icon>\r\n </div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef> edit </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"popup\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Popup\r\n </th>\r\n <td mat-cell *matCellDef=\"let row; let i = index\">\r\n <mat-icon aria-hidden=\"false\" (click)=\"openEditingDialog(row)\" fontIcon=\"edit\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"delete\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Delete\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i=dataIndex\">\r\n <mat-icon (click)=\"deleteRow(row,i)\" aria-hidden=\"false\" aria-label=\"Example home icon\"\r\n fontIcon=\"delete\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->\r\n <ng-container *ngIf=\"expandRows\" matColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let element;let i=dataIndex \"\r\n [attr.colspan]=\"columnsToDisplayWithExpand.length\">\r\n <div class=\"example-element-detail\"\r\n [@detailExpand]=\"element == expandedElement ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"expansionTemplateRef\" [ngTemplateOutlet]=\"expansionTemplateRef\"\r\n [ngTemplateOutletContext]=\"{$explicit:element,row:element,index:i}\">\r\n </ng-container>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let ids of headersFiltersIds; let i=index\" [matColumnDef]=\"ids\">\r\n <th mat-header-cell *matHeaderCellDef>\r\n <div class=\"filters-container\" [class.animate]=\"toggleFilters\">\r\n <app-filter-columns-component [obj]=\"columnsArray[returnIndex(ids)]\"\r\n (filterOutput)=\"applyColumnFilter($event,columnsArray[returnIndex(ids)])\"></app-filter-columns-component>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\" getDisplayedColumns(); sticky: stickyHeader\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns:getDisplayedColumns(); let i=dataIndex;\" class=\"data-row\"\r\n [ngClass]=\"{'data-row':expandRows,'stripedRows':(stripedRows && i % 2 == 1),'hoverClass':rowHover, 'hidden':hiddenCtrl.isSelected(row) && hideRows,'example-expanded-row':expandedElement === row}\"\r\n (click)=\"expandRow(row, row !== expandedElement,i)\">\r\n </tr>\r\n <tr style=\"height: 0px;\" mat-header-row class=\"no-default-height\" *matHeaderRowDef=\"headersFiltersIds\">\r\n </tr>\r\n <ng-container *ngIf=\"expandRows\">\r\n <tr style=\"height: 0px;\" mat-row *matRowDef=\"let row; columns: ['expandedDetail']\"\r\n [ngClass]=\"{'example-detail-row': (expandRows && row === expandedElement),'expand-row':row !== expandedElement}\">\r\n </tr>\r\n </ng-container>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <tr mat-footer-row *matFooterRowDef=\"getDisplayedColumns(); sticky: stickyFooter\"></tr>\r\n </ng-container>\r\n </table>\r\n </section>\r\n <mat-paginator *ngIf=\"showPaginator\" [pageSizeOptions]=\"pageSizeOptions\"\r\n [showFirstLastButtons]=\"showFirstLastButtons\">\r\n </mat-paginator>\r\n</mat-card>", styles: ["table{min-width:100%}.mat-table-sticky-border-elem-right{border-left:1px solid #e0e0e0}.mat-table-sticky-border-elem-left{border-right:1px solid #e0e0e0}tr.example-detail-row{display:table-row!important}.example-element-detail{overflow:hidden;display:flex}.hidden{display:none}.stripedRows{background:#eaeaea!important}.hoverClass:hover{background:#dbdbdb!important}.filters-container{overflow:hidden;max-height:0px;transition:max-height .5s ease-in-out}.animate{max-height:50px!important}.resize-handle{display:inline-block;border-right:2px solid rgb(140,140,140);position:absolute;top:0;right:0;height:100%;cursor:col-resize;opacity:0}.resize-handle:hover{width:20px}table th:hover .resize-handle{opacity:1;transition:.3s ease-in-out}.mat-table.resizing{-webkit-user-select:none;user-select:none;cursor:col-resize}.mat-table .mat-header-cell{position:relative}.mat-table .mat-header-cell:not(:last-child) .resize-holder{cursor:col-resize;width:20px;height:100%;position:absolute;right:-10px;top:0;z-index:1}.toolbar-container{display:flex;padding:0 15px;gap:1rem;grid-auto-rows:10px;justify-content:flex-end;align-items:center}.mat-table-ext-container{width:100%;max-width:100%;overflow:auto}.column-headers{font-family:Roboto,Helvetica Neue,sans-serif}.example-spacer{flex:1 1 auto}.export-button .mat-button-wrapper{display:flex!important;width:8em;justify-content:space-around;align-items:center}.toolbar-menu-container{display:flex;flex-direction:column;margin:auto .8em;width:15em;height:20em}.toolbar-menu-item{display:flex;height:3em}.toolbar-menu-checkbox{margin-left:8%}.toolbar-menu-checkbox.mat-checkbox{width:max-content;display:flex;align-items:center}.hide-button .mat-button-wrapper,.pin-button .mat-button-wrapper{display:flex!important;width:5em;justify-content:space-around;align-items:center}.hide-button,.pin-button,.export-button{height:3em;border:2px solid currentColor!important}.showHide-menu-columns-list{height:10em;max-height:10em;overflow-y:auto}mat-card.main-table-ext-container{padding:0}.main-table-ext-container{margin:10px}.mat-column-select{width:50px!important}.data-row td,.example-expanded-row td{border-bottom-width:0!important}.action-column-cells{width:40px;height:inherit}.inline-editing-controls{display:flex}.global-search-field{width:-webkit-fill-available}\n"] }]
912
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i2.MatTableExtService }, { type: i3.FormBuilder }, { type: i4.DomSanitizer }, { type: i5.MatIconRegistry }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menuTrigger: [{
913
+ type: ViewChild,
914
+ args: [MatMenuTrigger]
915
+ }], columnMenuTrigger: [{
916
+ type: ViewChild,
917
+ args: ['columnMenuTrigger']
918
+ }], paginator: [{
919
+ type: ViewChild,
920
+ args: [MatPaginator]
921
+ }], sort: [{
922
+ type: ViewChild,
923
+ args: [MatSort]
924
+ }], dataSource: [{
925
+ type: Input
926
+ }], columns: [{
927
+ type: Input
928
+ }], columnResizable: [{
929
+ type: Input
930
+ }], stripedRows: [{
931
+ type: Input
932
+ }], rowHover: [{
933
+ type: Input
934
+ }], inlineRowEditing: [{
935
+ type: Input
936
+ }], inCellEditing: [{
937
+ type: Input
938
+ }], popupRowEditing: [{
939
+ type: Input
940
+ }], enableDelete: [{
941
+ type: Input
942
+ }], rowSelection: [{
943
+ type: Input
944
+ }], multiRowSelection: [{
945
+ type: Input
946
+ }], stickyFooter: [{
947
+ type: Input
948
+ }], stickyHeader: [{
949
+ type: Input
950
+ }], showFooterRow: [{
951
+ type: Input
952
+ }], columnFilter: [{
953
+ type: Input
954
+ }], loadingIndicator: [{
955
+ type: Input
956
+ }], sorting: [{
957
+ type: Input
958
+ }], showToolbar: [{
959
+ type: Input
960
+ }], toolbarTitle: [{
961
+ type: Input
962
+ }], tableHeight: [{
963
+ type: Input
964
+ }], toolbarHeight: [{
965
+ type: Input
966
+ }], tableWidth: [{
967
+ type: Input
968
+ }], scrollbarH: [{
969
+ type: Input
970
+ }], toolbarTemplate: [{
971
+ type: Input
972
+ }], columnHidable: [{
973
+ type: Input
974
+ }], columnPinnable: [{
975
+ type: Input
976
+ }], globalSearch: [{
977
+ type: Input
978
+ }], expandRows: [{
979
+ type: Input
980
+ }], dndColumns: [{
981
+ type: Input
982
+ }], showPaginator: [{
983
+ type: Input
984
+ }], showFirstLastButtons: [{
985
+ type: Input
986
+ }], exportButtonEnable: [{
987
+ type: Input
988
+ }], pageSizeOptions: [{
989
+ type: Input
990
+ }], toolbarTemplateRef: [{
991
+ type: Input
992
+ }], headerTemplateRef: [{
993
+ type: Input
994
+ }], cellTemplateRef: [{
995
+ type: Input
996
+ }], expansionTemplateRef: [{
997
+ type: Input
998
+ }], popupEditingTemplateRef: [{
999
+ type: Input
1000
+ }], inlineEditingTemplateRef: [{
1001
+ type: Input
1002
+ }], cellEditingTemplateRef: [{
1003
+ type: Input
1004
+ }], cellTemplateRefMap: [{
1005
+ type: Input
1006
+ }], inlineChange: [{
1007
+ type: Output
1008
+ }], cellChange: [{
1009
+ type: Output
1010
+ }], popupChange: [{
1011
+ type: Output
1012
+ }], rowDeleted: [{
1013
+ type: Output
1014
+ }], scroll: [{
1015
+ type: Output
1016
+ }], selectionChanged: [{
1017
+ type: Output
1018
+ }], expansionChange: [{
1019
+ type: Output
1020
+ }] } });
1021
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0LXRhYmxlLWV4dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXQtdGFibGUtZXh0L3NyYy9saWIvbWF0LXRhYmxlLWV4dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXQtdGFibGUtZXh0L3NyYy9saWIvbWF0LXRhYmxlLWV4dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsT0FBTyxFQUNQLEtBQUssRUFDTCxLQUFLLEVBQ0wsVUFBVSxFQUNWLE9BQU8sR0FDUixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQWUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEUsT0FBTyxFQUdMLFlBQVksRUFDWixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBS0wsU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQWEsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFnQi9FLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWlCN0IsTUFBTSxPQUFPLG9CQUFvQjtJQWlIL0IsWUFDUyxN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LEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csb0JBQW9CO3NCQUE1QixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csdUJBQXVCO3NCQUEvQixLQUFLO2dCQUNHLHdCQUF3QjtzQkFBaEMsS0FBSztnQkFDRyxzQkFBc0I7c0JBQTlCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUdJLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFFRyxlQUFlO3NCQUF4QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBhbmltYXRlLFxyXG4gIHN0YXRlLFxyXG4gIHN0eWxlLFxyXG4gIHRyYW5zaXRpb24sXHJcbiAgdHJpZ2dlcixcclxufSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcclxuaW1wb3J0IHsgU2VsZWN0aW9uTW9kZWwgfSBmcm9tICdAYW5ndWxhci9jZGsvY29sbGVjdGlvbnMnO1xyXG5pbXBvcnQgeyBDZGtEcmFnRHJvcCwgbW92ZUl0ZW1JbkFycmF5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XHJcbmltcG9ydCB7XHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgT3V0cHV0LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBJbnB1dCxcclxuICBPbkNoYW5nZXMsXHJcbiAgT25Jbml0LFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVGVtcGxhdGVSZWYsXHJcbiAgVmlld0NoaWxkLFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBNYXREaWFsb2csIE1hdERpYWxvZ0NvbmZpZyB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XHJcbmltcG9ydCB7IE1hdE1lbnVUcmlnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbWVudSc7XHJcbmltcG9ydCB7IE1hdFBhZ2luYXRvciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3BhZ2luYXRvcic7XHJcbmltcG9ydCB7IE1hdFNvcnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zb3J0JztcclxuaW1wb3J0IHsgTWF0VGFibGVEYXRhU291cmNlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFibGUnO1xyXG5pbXBvcnQgeyBFZGl0aW5nQ29tcG9uZW50IH0gZnJvbSAnLi4vbGliL2NvbXBvbmVudHMvZWRpdGluZy9lZGl0aW5nLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7XHJcbiAgUm93Q2hhbmdlLFxyXG4gIERpc3BsYXlDb2x1bW4sXHJcbiAgTVRFeENvbHVtbixcclxuICBNVEV4Q29sdW1uUGluT3B0aW9uLFxyXG4gIFJvd1NlbGVjdGlvbkNoYW5nZSxcclxuICBDZWxsVGVtcGxhdGVSZWZNYXAsXHJcbiAgRXhwYW5zaW9uQ2hhbmdlLFxyXG4gIEZpbHRlclNlYXJjaFZhbHVlLFxyXG4gIE1URXhSb3csXHJcbiAgQ29sdW1uVmlzaWJpbGl0eSxcclxufSBmcm9tICcuLi9saWIvbW9kZWxzL3RhYmxlRXh0TW9kZWxzJztcclxuaW1wb3J0IHsgTWF0VGFibGVFeHRTZXJ2aWNlIH0gZnJvbSAnLi4vbGliL21hdC10YWJsZS1leHQuc2VydmljZSc7XHJcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5pbXBvcnQgeyBNYXRJY29uUmVnaXN0cnkgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcclxuaW1wb3J0ICogYXMgWExTWCBmcm9tICd4bHN4JztcclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdtYXQtdGFibGUtZXh0JyxcclxuICB0ZW1wbGF0ZVVybDogJ21hdC10YWJsZS1leHQuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWydtYXQtdGFibGUtZXh0LnNjc3MnXSxcclxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG4gIGFuaW1hdGlvbnM6IFtcclxuICAgIHRyaWdnZXIoJ2RldGFpbEV4cGFuZCcsIFtcclxuICAgICAgc3RhdGUoJ2NvbGxhcHNlZCcsIHN0eWxlKHsgaGVpZ2h0OiAnMHB4JywgbWluSGVpZ2h0OiAnMCcgfSkpLFxyXG4gICAgICBzdGF0ZSgnZXhwYW5kZWQnLCBzdHlsZSh7IGhlaWdodDogJyonIH0pKSxcclxuICAgICAgdHJhbnNpdGlvbihcclxuICAgICAgICAnZXhwYW5kZWQgPD0+IGNvbGxhcHNlZCcsXHJcbiAgICAgICAgYW5pbWF0ZSgnMzAwbXMgY3ViaWMtYmV6aWVyKDAuNCwgMC4wLCAwLjIsIDEpJylcclxuICAgICAgKSxcclxuICAgIF0pLFxyXG4gIF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXRUYWJsZUV4dENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcclxuICBAVmlld0NoaWxkKE1hdE1lbnVUcmlnZ2VyKSBtZW51VHJpZ2dlciE6IE1hdE1lbnVUcmlnZ2VyO1xyXG4gIEBWaWV3Q2hpbGQoJ2NvbHVtbk1lbnVUcmlnZ2VyJykgY29sdW1uTWVudVRyaWdnZXIhOiBNYXRNZW51VHJpZ2dlcjtcclxuICBAVmlld0NoaWxkKE1hdFBhZ2luYXRvcikgcGFnaW5hdG9yITogTWF0UGFnaW5hdG9yO1xyXG4gIEBWaWV3Q2hpbGQoTWF0U29ydCkgc29ydCE6IE1hdFNvcnQ7XHJcblxyXG4gIC8vIFRhYmxlIGlucHV0c1xyXG4gIEBJbnB1dCgpIGRhdGFTb3VyY2UhOiBNYXRUYWJsZURhdGFTb3VyY2U8YW55PjtcclxuICBASW5wdXQoKSBjb2x1bW5zOiBNVEV4Q29sdW1uW10gPSBbXTtcclxuICBASW5wdXQoKSBjb2x1bW5SZXNpemFibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBzdHJpcGVkUm93czogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHJvd0hvdmVyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgaW5saW5lUm93RWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGluQ2VsbEVkaXRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBwb3B1cFJvd0VkaXRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBlbmFibGVEZWxldGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSByb3dTZWxlY3Rpb246IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBtdWx0aVJvd1NlbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHN0aWNreUZvb3RlcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHN0aWNreUhlYWRlcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHNob3dGb290ZXJSb3c6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBjb2x1bW5GaWx0ZXI6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBsb2FkaW5nSW5kaWNhdG9yOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc29ydGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHNob3dUb29sYmFyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgdG9vbGJhclRpdGxlOiBzdHJpbmcgPSAnJztcclxuICBASW5wdXQoKSB0YWJsZUhlaWdodDogc3RyaW5nID0gJyc7XHJcbiAgQElucHV0KCkgdG9vbGJhckhlaWdodDogc3RyaW5nID0gJzUwcHgnO1xyXG4gIEBJbnB1dCgpIHRhYmxlV2lkdGg6IHN0cmluZyA9ICcxMDAlJztcclxuICBASW5wdXQoKSBzY3JvbGxiYXJIOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgdG9vbGJhclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIGNvbHVtbkhpZGFibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBjb2x1bW5QaW5uYWJsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGdsb2JhbFNlYXJjaDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGV4cGFuZFJvd3M6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBkbmRDb2x1bW5zOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc2hvd1BhZ2luYXRvcjogYm9vbGVhbiA9IHRydWU7XHJcbiAgQElucHV0KCkgc2hvd0ZpcnN0TGFzdEJ1dHRvbnM6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBleHBvcnRCdXR0b25FbmFibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBwYWdlU2l6ZU9wdGlvbnM6IG51bWJlcltdID0gWzEwLCA1MCwgMTAwXTtcclxuICBASW5wdXQoKSB0b29sYmFyVGVtcGxhdGVSZWYhOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIGhlYWRlclRlbXBsYXRlUmVmITogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBjZWxsVGVtcGxhdGVSZWYhOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIGV4cGFuc2lvblRlbXBsYXRlUmVmITogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBwb3B1cEVkaXRpbmdUZW1wbGF0ZVJlZiE6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQ7XHJcbiAgQElucHV0KCkgaW5saW5lRWRpdGluZ1RlbXBsYXRlUmVmITogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBjZWxsRWRpdGluZ1RlbXBsYXRlUmVmITogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBjZWxsVGVtcGxhdGVSZWZNYXA6IENlbGxUZW1wbGF0ZVJlZk1hcCA9IHt9O1xyXG5cclxuICAvLyBUYWJsZSBvdXRwdXRzXHJcbiAgQE91dHB1dCgpIGlubGluZUNoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPFJvd0NoYW5nZT4oKTtcclxuICBAT3V0cHV0KCkgY2VsbENoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPFJvd0NoYW5nZT4oKTtcclxuICBAT3V0cHV0KCkgcG9wdXBDaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxSb3dDaGFuZ2U+KCk7XHJcbiAgQE91dHB1dCgpIHJvd0RlbGV0ZWQ6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQE91dHB1dCgpIHNjcm9sbDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgc2VsZWN0aW9uQ2hhbmdlZDogRXZlbnRFbWl0dGVyPFJvd1NlbGVjdGlvbkNoYW5nZT4gPVxyXG4gICAgbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQE91dHB1dCgpIGV4cGFuc2lvbkNoYW5nZTogRXZlbnRFbWl0dGVyPEV4cGFuc2lvbkNoYW5nZT4gPVxyXG4gICAgbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgdGFibGVJRCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gIGNvbHVtblBpbm5pbmdPcHRpb25zOiBNVEV4Q29sdW1uUGluT3B0aW9uW10gPSBbXTtcclxuICBleHBvcnRNZW51Q3RybDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGNvbHVtblBpbk1lbnVDdHJsOiBib29sZWFuID0gZmFsc2U7XHJcbiAgaGlkZVNob3dNZW51Q3RybDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGNvbHVtbkZpbHRlckJ5U2VsZWN0aW9uOiBhbnkgPSBmYWxzZTtcclxuICByb3dEYXRhVGVtcDogYW55ID0ge307XHJcbiAgaW5saW5lRWRpdGluZ1RlbXBsYXRlUmVmRGF0YTogYW55ID0ge307XHJcbiAgZGlzcGxheWVkQ29sdW1uczogc3RyaW5nW10gPSBbXTtcclxuICBzaG93SGlkZUNvbHVtbnNBcnJheTogTVRFeENvbHVtbltdID0gW107XHJcbiAgY29sdW1uc0xpc3Q6IHN0cmluZ1tdID0gW107XHJcbiAgY29sdW1uc0FycmF5OiBNVEV4Q29sdW1uW10gPSBbXTtcclxuICBoZWFkZXJzRmlsdGVyc0lkczogc3RyaW5nW10gPSBbXTtcclxuICBjb2x1bW5zVG9EaXNwbGF5V2l0aEV4cGFuZDogc3RyaW5nW10gPSBbXTtcclxuICBzZWxlY3Rpb24gPSBuZXcgU2VsZWN0aW9uTW9kZWw8YW55PihmYWxzZSwgW10pO1xyXG4gIGhpZGRlbkN0cmwgPSBuZXcgU2VsZWN0aW9uTW9kZWw8YW55Pih0cnVlLCBbXSk7XHJcbiAgdGFibGVEYXRhOiBhbnkgPSBbXTtcclxuICBmaWx0ZXJWYWx1ZXM6IGFueSA9IHt9O1xyXG4gIGdsb2JhbEZpbHRlciA9ICcnO1xyXG4gIHNob3dIaWRlRmlsdGVyID0gJyc7XHJcbiAgaW5kaXZpZHVhbEZpbHRlciA9ICcnO1xyXG4gIHRvZ2dsZUZpbHRlcnMgPSBmYWxzZTtcclxuICBoaWRlUm93cyA9IGZhbHNlO1xyXG4gIGV4cGFuZGVkRWxlbWVudDogYW55IHwgbnVsbDtcclxuICBjdXJyZW50Um93SW5kZXg6IG51bWJlciA9IC0xO1xyXG4gIGN1cnJlbnRSb3c6IGFueSA9IHt9O1xyXG4gIGNlbGxFZGl0aW5nOiBhbnkgPSB7fTtcclxuICBoaWRlU2hvd01lbnVHcm91cCE6IEZvcm1Hcm91cDtcclxuICBjZWxsVGVtcGxhdGUhOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIG1lbnVYOiBudW1iZXIgPSAwO1xyXG4gIG1lbnVZOiBudW1iZXIgPSAwO1xyXG4gIGR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zOiBhbnlbXSA9IFtcclxuICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ3NlbGVjdCcsIHNob3c6IGZhbHNlIH0sXHJcbiAgICB7IGZpbHRlcjogZmFsc2UsIG5hbWU6ICdlZGl0Jywgc2hvdzogZmFsc2UgfSxcclxuICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ3BvcHVwJywgc2hvdzogZmFsc2UgfSxcclxuICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ2RlbGV0ZScsIHNob3c6IGZhbHNlIH0sXHJcbiAgICB7IGZpbHRlcjogZmFsc2UsIG5hbWU6ICdleHBhbmQnLCBzaG93OiBmYWxzZSB9LFxyXG4gIF07XHJcbiAgaW5wdXRQcm9wZXJ0eUtleXM6IHN0cmluZ1tdID0gW1xyXG4gICAgJ2RhdGFTb3VyY2UnLFxyXG4gICAgJ2NvbHVtbnMnLFxyXG4gICAgJ2lubGluZVJvd0VkaXRpbmcnLFxyXG4gICAgJ3BvcHVwUm93RWRpdGluZycsXHJcbiAgICAnZW5hYmxlRGVsZXRlJyxcclxuICAgICdyb3dTZWxlY3Rpb24nLFxyXG4gICAgJ211bHRpUm93U2VsZWN0aW9uJyxcclxuICAgICdzdGlja3lIZWFkZXInLFxyXG4gICAgJ3N0aWNreUZvb3RlcicsXHJcbiAgICAnY29sdW1uRmlsdGVyJyxcclxuICAgICdnbG9iYWxTZWFyY2gnLFxyXG4gICAgJ2V4cGFuZFJvd3MnLFxyXG4gICAgJ3NvcnRpbmcnLFxyXG4gIF07XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHVibGljIGRpYWxvZzogTWF0RGlhbG9nLFxyXG4gICAgcHVibGljIHNlcnZpY2U6IE1hdFRhYmxlRXh0U2VydmljZSxcclxuICAgIHB1YmxpYyBmb3JtQnVpbGRlcnNTZXJ2aWNlOiBGb3JtQnVpbGRlcixcclxuICAgIHB1YmxpYyBkb21TYW5pdGl6ZXI6IERvbVNhbml0aXplcixcclxuICAgIHB1YmxpYyBtYXRJY29uUmVnaXN0cnk6IE1hdEljb25SZWdpc3RyeSxcclxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxyXG4gICkge1xyXG4gICAgdGhpcy5hZGRJY29uc1RvUmVnaXN0cnkoKTtcclxuICAgIGlmICh0aGlzLmRhdGFTb3VyY2UpIHtcclxuICAgICAgdGhpcy50YWJsZURhdGEgPSB0aGlzLmRhdGFTb3VyY2UuZGF0YTtcclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICpcclxuICAgKiBAcGFyYW0gY2hhbmdlcyBjaGFuZ2VzIGNhcHR1cmVkIGVhY2ggdGltZSB1c2VyIGNoYW5nZXMgcHJvcGVydHkgdmFsdWUuXHJcbiAgICovXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgdGhpcy5zZXRQcm9wZXJ0eVZhbHVlKGNoYW5nZXMpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICBpZiAodGhpcy5kYXRhU291cmNlKSB7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZS5maWx0ZXJQcmVkaWNhdGUgPSB0aGlzLmNyZWF0ZUZpbHRlcigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgaWYgKHRoaXMuZGF0YVNvdXJjZSkge1xyXG4gICAgICB0aGlzLmRhdGFTb3VyY2UucGFnaW5hdG9yID0gdGhpcy5wYWdpbmF0b3I7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZS5zb3J0ID0gdGhpcy5zb3J0O1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gY2hlY2tzIGFuZCB1cGRhdGVzIHRoZSB0aGUgY29sdW1uJ3MgaGlkZSBhbmQgc2hvdyBwcm9wZXJ0aWVzLlxyXG4gICAqL1xyXG4gIHNldENvbHVtbkhpZGVTaG93KCkge1xyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmhpZGVTaG93TWVudUdyb3VwICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgdGhpcy5oaWRlU2hvd01lbnVHcm91cCAhPT0gbnVsbFxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMudXBkYXRlQ29sdW1uc0hpZGVTaG93KHRoaXMuaGlkZVNob3dNZW51R3JvdXAudmFsdWUpO1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gc2V0IHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSB0YWJsZS5cclxuICAgKiBAcGFyYW0gY2hhbmdlcyBjaGFuZ2VzIGNhcHR1cmVkIGVhY2ggdGltZSB1c2VyIGNoYW5nZXMgcHJvcGVydHkgdmFsdWUuXHJcbiAgICovXHJcbiAgc2V0UHJvcGVydHlWYWx1ZShjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKGNoYW5nZXMpO1xyXG4gICAga2V5cy5mb3JFYWNoKChwcm9wZXJ0eSkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5pbnB1dFByb3BlcnR5S2V5cy5pbmNsdWRlcyhwcm9wZXJ0eSkpIHtcclxuICAgICAgICB0aGlzLnNldFByb3BlcnRpZXNNYXBbcHJvcGVydHldKGNoYW5nZXNbcHJvcGVydHldKTtcclxuICAgICAgfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSAnc2hvd1Rvb2xiYXInKSB7XHJcbiAgICAgICAgaWYgKGNoYW5nZXNbJ2NvbHVtbnMnXSkge1xyXG4gICAgICAgICAgdGhpcy5zZXRUb29sYmFyTWVudUNvbnRyb2xzKGNoYW5nZXNbJ2NvbHVtbnMnXS5jdXJyZW50VmFsdWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLnNldFRvb2xiYXJNZW51Q29udHJvbHModGhpcy5jb2x1bW5zQXJyYXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1hcHBpbmcgaXMgdXNlZCB0byBzZXQgYW5kIHVwZGF0ZSBjaGFuZ2VzaW4gdGhlIHRhYmxlLlxyXG4gICAqL1xyXG4gIHNldFByb3BlcnRpZXNNYXA6IGFueSA9IHtcclxuICAgIGRhdGFTb3VyY2U6ICh2YWx1ZTogYW55KSA9PiB0aGlzLnNldFRhYmxlRGF0YVNvdXJjZSh2YWx1ZSksXHJcbiAgICBjb2x1bW5zOiAodmFsdWU6IGFueSkgPT4gdGhpcy5zZXRDb2x1bW5zRGF0YSh2YWx1ZS5jdXJyZW50VmFsdWUpLFxyXG4gICAgaW5saW5lUm93RWRpdGluZzogKHZhbHVlOiBhbnkpID0+XHJcbiAgICAgIHRoaXMuc2hvd0hpZGVDb2x1bW4oJ2VkaXQnLCB2YWx1ZS5jdXJyZW50VmFsdWUpLFxyXG4gICAgcG9wdXBSb3dFZGl0aW5nOiAodmFsdWU6IGFueSkgPT5cclxuICAgICAgdGhpcy5zaG93SGlkZUNvbHVtbigncG9wdXAnLCB2YWx1ZS5jdXJyZW50VmFsdWUpLFxyXG4gICAgZW5hYmxlRGVsZXRlOiAodmFsdWU6IGFueSkgPT5cclxuICAgICAgdGhpcy5zaG93SGlkZUNvbHVtbignZGVsZXRlJywgdmFsdWUuY3VycmVudFZhbHVlKSxcclxuICAgIHJvd1NlbGVjdGlvbjogKHZhbHVlOiBhbnkpID0+IHRoaXMuc2V0Um93U2VsZWN0aW9uKHZhbHVlLmN1cnJlbnRWYWx1ZSksXHJcbiAgICBtdWx0aVJvd1NlbGVjdGlvbjogKHZhbHVlOiBhbnkpID0+IHtcclxuICAgICAgdGhpcy5zZWxlY3Rpb24gPSBuZXcgU2VsZWN0aW9uTW9kZWw8YW55Pih2YWx1ZS5jdXJyZW50VmFsdWUsIFtdKTtcclxuICAgIH0sXHJcbiAgICBzdGlja3lIZWFkZXI6ICh2YWx1ZTogYW55KSA9PiB7XHJcbiAgICAgIHRoaXMuc3RpY2t5SGVhZGVyID0gdmFsdWUuY3VycmVudFZhbHVlO1xyXG4gICAgfSxcclxuICAgIHN0aWNreUZvb3RlcjogKHZhbHVlOiBhbnkpID0+IHtcclxuICAgICAgdGhpcy5zdGlja3lGb290ZXIgPSB2YWx1ZS5jdXJyZW50VmFsdWU7XHJcbiAgICB9LFxyXG4gICAgY29sdW1uRmlsdGVyOiAodmFsdWU6IGFueSkgPT4gdGhpcy5zZXRDb2x1bW5GaWx0ZXIodmFsdWUuY3VycmVudFZhbHVlKSxcclxuICAgIGdsb2JhbFNlYXJjaDogKHZhbHVlOiBhbnkpID0+XHJcbiAgICAgICh0aGlzLmRhdGFTb3VyY2UuZmlsdGVyUHJlZGljYXRlID0gdGhpcy5jcmVhdGVGaWx0ZXIoKSksXHJcbiAgICBleHBhbmRSb3dzOiAodmFsdWU6IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLmxvYWRpbmdJbmRpY2F0b3IgPSB0cnVlO1xyXG4gICAgICB0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VGFibGVEYXRhU291cmNlKHRoaXMudGFibGVEYXRhKTtcclxuICAgICAgaWYgKHZhbHVlLmN1cnJlbnRWYWx1ZSA9PSB0cnVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmRpc3BsYXllZENvbHVtbnMuaW5jbHVkZXMoJ2V4cGFuZCcpKSB7XHJcbiAgICAgICAgICB0aGlzLmRpc3BsYXllZENvbHVtbnMucHVzaCgnZXhwYW5kJyk7XHJcbiAgICAgICAgICB0aGlzLmNvbHVtbnNUb0Rpc3BsYXlXaXRoRXhwYW5kID0gWy4uLnRoaXMuZGlzcGxheWVkQ29sdW1uc107XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuY29sdW1uc1RvRGlzcGxheVdpdGhFeHBhbmQgPSBbLi4udGhpcy5kaXNwbGF5ZWRDb2x1bW5zXTtcclxuICAgICAgICBpZiAodGhpcy5kaXNwbGF5ZWRDb2x1bW5zLmluY2x1ZGVzKCdleHBhbmQnKSkge1xyXG4gICAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5kaXNwbGF5ZWRDb2x1bW5zLmluZGV4T2YoJ2V4cGFuZCcpO1xyXG4gICAgICAgICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZXhwYW5kZWRFbGVtZW50ID0gbnVsbDtcclxuICAgICAgfVxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICB0aGlzLmxvYWRpbmdJbmRpY2F0b3IgPSBmYWxzZTtcclxuICAgICAgfSwgMjAwKTtcclxuICAgIH0sXHJcbiAgICBzb3J0aW5nOiAodmFsdWU6IGFueSkgPT4gKHRoaXMuZGF0YVNvdXJjZS5zb3J0ID0gdGhpcy5zb3J0KSxcclxuICB9O1xyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiB1c2VkIHNldCBkYXRhIHNvdXJjZSBmb3IgdGFibGUuXHJcbiAgICogQHBhcmFtIHZhbHVlIGRhdGEgc291cmNlIHZhbHVlIGZyb20gdXNlci5cclxuICAgKi9cclxuICBzZXRUYWJsZURhdGFTb3VyY2UodmFsdWU6IGFueSkge1xyXG4gICAgaWYgKHZhbHVlLmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICB0aGlzLnRhYmxlRGF0YSA9IHZhbHVlLmN1cnJlbnRWYWx1ZS5kYXRhO1xyXG4gICAgICB0aGlzLmRhdGFTb3VyY2UgPSB2YWx1ZS5jdXJyZW50VmFsdWU7XHJcbiAgICAgIHRoaXMucmVDYWwoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZSA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UoW3t9XSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiB1c2VkIGNyZWF0ZSBzZWxldGlvbiBtb2RlbCBhbmQgc2V0IHNlbGVjdGlvbiBjb2x1bW4gdmlzaWJpbGl0eS5cclxuICAgKiBAcGFyYW0gdmFsdWUgYm9vbGVhbiB2YWx1ZSB0byBzaG93IG9yIGhpZGUgc2VsZWN0aW9uIENvbHVtbiBmcm9tIHRhYmxlLlxyXG4gICAqL1xyXG4gIHNldFJvd1NlbGVjdGlvbih2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgdGhpcy5zZWxlY3Rpb24gPSBuZXcgU2VsZWN0aW9uTW9kZWw8YW55Pih0cnVlLCBbXSk7XHJcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbkNvbHVtblZpc2liaWxpdHkodmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIGNyZWF0ZSBmaWx0ZXIgaGVhZGVyIHJvdyBhbmQgYXNzaWducyBmaWx0ZXIgcHJlZGljYXRlIHRvIHRhYmxlIGRhdGEgc291cmNlLlxyXG4gICAqIEBwYXJhbSB2YWx1ZSBib29sZWFuIHZhbHVlIHRvIGNoYW5nZSAgdmlzaWJpbGl0eSBvZiBjb2x1bW4gZmlsdGVyIHJvdy5cclxuICAgKi9cclxuICBzZXRDb2x1bW5GaWx0ZXIodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICBsZXQgYXJyYXk6IHN0cmluZ1tdID0gW107XHJcbiAgICAgIHRoaXMuY29sdW1uc0FycmF5LmZvckVhY2goKGNvbHVtbiwgaSkgPT4ge1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMuZmlsdGVyKChhKSA9PiBhLm5hbWUgPT0gY29sdW1uPy5maWVsZClbMF1cclxuICAgICAgICAgICAgLnNob3dcclxuICAgICAgICApIHtcclxuICAgICAgICAgIGFycmF5LnB1c2goY29sdW1uPy5maWVsZCArICdfJyArIGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuaGVhZGVyc0ZpbHRlcnNJZHMgPSBhcnJheTtcclxuICAgICAgdGhpcy5kYXRhU291cmNlLmZpbHRlclByZWRpY2F0ZSA9IHRoaXMuY3JlYXRlRmlsdGVyKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmhlYWRlcnNGaWx0ZXJzSWRzID0gW107XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZS5maWx0ZXIgPSAnJztcclxuICAgIH1cclxuICAgIHRoaXMudG9nZ2xlRmlsdGVycyA9IHZhbHVlO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgbGlzdCBvZiB2aXNpYmxlIGNvbHVtbiBuYW1lcy5cclxuICAgKiBAcmV0dXJucyBsaXN0IG9mIHZpc2libGUgY29sdW1uIG5hbWVzLlxyXG4gICAqL1xyXG4gIGdldERpc3BsYXllZENvbHVtbnMoKTogc3RyaW5nW10ge1xyXG4gICAgbGV0IGxpc3QgPSB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zXHJcbiAgICAgIC5maWx0ZXIoKGNkKSA9PiBjZC5zaG93KVxyXG4gICAgICAubWFwKChjZCkgPT4gY2QubmFtZSk7XHJcbiAgICByZXR1cm4gbGlzdDtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQHBhcmFtIG1lbnVUeXBlIHR5cGUgb2YgbWVudSB0byBvcGVuIGZyb20gdG9vbGJhci5cclxuICAgKiBAcGFyYW0gZXZlbnQgbW91c2UgZXZlbnQgdG8gb3BlbiBtZW51IG9uIHRoYXQgbG9jYXRpb24uXHJcbiAgICovXHJcbiAgb3Blbk1lbnUobWVudVR5cGU6IHN0cmluZywgZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIHRoaXMubWVudVggPSBldmVudC5jbGllbnRYO1xyXG4gICAgdGhpcy5tZW51WSA9IGV2ZW50LmNsaWVudFk7XHJcbiAgICBzd2l0Y2ggKG1lbnVUeXBlKSB7XHJcbiAgICAgIGNhc2UgJ2V4cG9ydCc6IHtcclxuICAgICAgICB0aGlzLmV4cG9ydE1lbnVDdHJsID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLm1lbnVUcmlnZ2VyLm9wZW5NZW51KCk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgICAgY2FzZSAnaGlkZVNob3cnOiB7XHJcbiAgICAgICAgdGhpcy5oaWRlU2hvd01lbnVDdHJsID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLm9wZW5IaWRlU2hvd01lbnUodGhpcy5jb2x1bW5zQXJyYXkpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgIGNhc2UgJ2NvbHVtblBpbic6IHtcclxuICAgICAgICB0aGlzLmNvbHVtblBpbk1lbnVDdHJsID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLm9wZW5IaWRlU2hvd01lbnUodGhpcy5jb2x1bW5zQXJyYXkpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiB0cmlnZ2VycyB3aGVuIG1lbnUgaXMgY2xvc2VkIGFuZCByZXNldCB0aGUgcmVxdWlyZWQgY29udHJvbHMuXHJcbiAgICovXHJcbiAgbWVudUNsb3NlZCgpIHtcclxuICAgIHRoaXMuZXhwb3J0TWVudUN0cmwgPSBmYWxzZTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIHNldCBsaXN0IG9mIGNvbHVtbnMgdG8gZGlzcGxheSBpbiB0YWJsZS5cclxuICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIGFycmF5IGZyb20gdXNlciBpbnB1dC5cclxuICAgKi9cclxuICBzZXRDb2x1bW5zRGF0YShjb2x1bW5zOiBNVEV4Q29sdW1uW10pIHtcclxuICAgIGlmIChjb2x1bW5zLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLmNvbHVtbnNBcnJheSA9IFsuLi5jb2x1bW5zXTtcclxuICAgICAgdGhpcy5zZXRDb2x1bW5zTGlzdChjb2x1bW5zKTtcclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIHNldCBsaXN0IG9mIGNvbHVtbnMgdG8gZGlzcGxheSBpbiB0YWJsZS5cclxuICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIGFycmF5IGZyb20gdXNlciBpbnB1dCB3aXRoIGNvbmZpZ3VyYXRpb25zLlxyXG4gICAqL1xyXG4gIHNldENvbHVtbnNMaXN0KGNvbHVtbnM6IE1URXhDb2x1bW5bXSkge1xyXG4gICAgdGhpcy5jb2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zID0gWydzZWxlY3QnLCAnZWRpdCcsICdwb3B1cCcsICdkZWxldGUnXTtcclxuICAgIGxldCBjb2x1bW5zQXJyYXk6IERpc3BsYXlDb2x1bW5bXSA9IFtdO1xyXG4gICAgY29sdW1ucy5mb3JFYWNoKChjb2wpID0+IHtcclxuICAgICAgaWYgKHR5cGVvZiBjb2w/LmhlYWRlciA9PSAnc3RyaW5nJykge1xyXG4gICAgICAgIHRoaXMuY29sdW1uc0xpc3QucHVzaChjb2w/LmhlYWRlcik7XHJcbiAgICAgICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zLnB1c2goY29sPy5maWVsZCk7XHJcbiAgICAgICAgY29sdW1uc0FycmF5LnB1c2goeyBmaWx0ZXI6IHRydWUsIG5hbWU6IGNvbD8uZmllbGQsIHNob3c6ICFjb2wuaGlkZSB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zID0gW1xyXG4gICAgICB7IGZpbHRlcjogZmFsc2UsIG5hbWU6ICdzZWxlY3QnLCBzaG93OiBmYWxzZSB9LFxyXG4gICAgICB7IGZpbHRlcjogZmFsc2UsIG5hbWU6ICdlZGl0Jywgc2hvdzogZmFsc2UgfSxcclxuICAgICAgeyBmaWx0ZXI6IGZhbHNlLCBuYW1lOiAncG9wdXAnLCBzaG93OiBmYWxzZSB9LFxyXG4gICAgICB7IGZpbHRlcjogZmFsc2UsIG5hbWU6ICdkZWxldGUnLCBzaG93OiBmYWxzZSB9LFxyXG4gICAgXTtcclxuICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMgPSBjb2x1bW5zQXJyYXkuY29uY2F0KFxyXG4gICAgICB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zXHJcbiAgICApO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGFrZSBib29sZWFuIHZhbHVlIGFuZCBuYW1lIGNvbHVtbiBhbmQgdXBkYXRlIGl0cyB2aXNpYmlsaXR5IHN0YXR1cyBpbiB0YWJsZS5cclxuICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBjb2x1bW4gdG8gc2V0IHZpc2liaWxpdHkuXHJcbiAgICogQHBhcmFtIHZhbHVlIGJvb2xlYW4gdmFsdWUgdG8gc2V0IHZpc2liaWxpdHkgb2YgdGhlIGNvbHVtbi5cclxuICAgKi9cclxuICBzaG93SGlkZUNvbHVtbihuYW1lOiBzdHJpbmcsIHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zLmZpbHRlcigoYSkgPT4gYS5uYW1lID09IG5hbWUpWzBdLnNob3cgPSB2YWx1ZTtcclxuICAgIGlmICh0aGlzLmNvbHVtbkZpbHRlcikge1xyXG4gICAgICB0aGlzLnNldENvbHVtbkZpbHRlcih0cnVlKTtcclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIHdpbGwgcG9zaXRpb24gdGhlIHNlbGVjdGlvbiBjb2x1bW4gdG8gZmlyc3QgYW5kIGFsc28gdXBkYXRlIGl0cyB2aXNpYmlsaXR5LlxyXG4gICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB1c2VkIHRvIHNldCB2aXNpYmlsaXR5IG9mIHRoZSBzZWxlY3Rpb24gY29sdW1uLlxyXG4gICAqL1xyXG4gIHVwZGF0ZVNlbGVjdGlvbkNvbHVtblZpc2liaWxpdHkodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIGxldCBjb2x1bW5OYW1lID0gJ3NlbGVjdCc7XHJcbiAgICBsZXQgY29sdW1uID0gdGhpcy5keW5hbWljRGlzcGxheWVkQ29sdW1ucy5maWx0ZXIoXHJcbiAgICAgIChhKSA9PiBhLm5hbWUgPT0gY29sdW1uTmFtZVxyXG4gICAgKVswXTtcclxuICAgIGxldCBpbmRleCA9IHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMuZmluZEluZGV4KFxyXG4gICAgICAoY29sdW1uOiBhbnkpID0+IGNvbHVtbi5uYW1lID09IGNvbHVtbk5hbWVcclxuICAgICk7XHJcbiAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMudW5zaGlmdChjb2x1bW4pO1xyXG4gICAgICB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zLmZpbHRlcihcclxuICAgICAgICAoY29sdW1uKSA9PiBjb2x1bW4ubmFtZSA9PSBjb2x1bW5OYW1lXHJcbiAgICAgIClbMF0uc2hvdyA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byB1cGRhdGUgdGhlIHBvc2l0aW9uIG9mICBjb2x1bW4gaW4gY29sdW1ucyBhcnJheSBhY2NvcmRpbmcgdG8gaXRzIGRyb3BwZWQgcG9zaXRpb24uXHJcbiAgICogQHBhcmFtIGV2ZW50IENka0RyYWdEcm9wIHVzZWQgdG8gdXBkYXRlIGNvbHVtbiBwb3NpdGlvbiBpbiBjb2x1bW5zIGFycmF5LlxyXG4gICAqL1xyXG4gIG9uRHJvcChldmVudDogQ2RrRHJhZ0Ryb3A8YW55Pikge1xyXG4gICAgaWYgKHRoaXMuZG5kQ29sdW1ucykge1xyXG4gICAgICBsZXQgYWRqdXN0ZWRWYWx1ZSA9IDA7XHJcbiAgICAgIGlmIChcclxuICAgICAgICB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zWzBdLm5hbWUgPT0gJ3NlbGVjdCcgJiZcclxuICAgICAgICB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zWzBdLnNob3cgPT0gZmFsc2VcclxuICAgICAgKSB7XHJcbiAgICAgICAgYWRqdXN0ZWRWYWx1ZSA9IDE7XHJcbiAgICAgIH1cclxuICAgICAgbW92ZUl0ZW1JbkFycmF5KFxyXG4gICAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMsXHJcbiAgICAgICAgZXZlbnQucHJldmlvdXNJbmRleCArIGFkanVzdGVkVmFsdWUsXHJcbiAgICAgICAgZXZlbnQuY3VycmVudEluZGV4ICsgYWRqdXN0ZWRWYWx1ZVxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2hkIGNyZWF0ZSBmaWx0ZXIgcHJlZGljYXRlIGZ1bmN0aW9uIHdoaWNoIHdpbGwgc2V0IHNlYXJjaCB2YWx1ZSB0byB0YWJsZSBmaWx0ZXJzXHJcbiAgICogZm9yIGJvdGggZ2xvYmFsIGFuZCBpbmRpdmlkdWFsIGNvbHVtIGZpbHRlcmluZy5cclxuICAgKiBAcmV0dXJucyByZXR1cm5zIGJvb2xlYW4gdmFsdWUgdG8gZmlsdGVyIHJvd3MgaW4gdGFibGUuXHJcbiAgICovXHJcbiAgY3JlYXRlRmlsdGVyKCk6IChkYXRhOiBhbnksIGZpbHRlcjogc3RyaW5nKSA9PiBib29sZWFuIHtcclxuICAgIGNvbnN0IHRhYmxlRmlsdGVyUHJlZGljYXRlID0gKGRhdGE6IGFueSwgZmlsdGVyOiBzdHJpbmcpOiBib29sZWFuID0+IHtcclxuICAgICAgbGV0IHJlc3VsdDogYm9vbGVhbiA9IHRydWU7XHJcbiAgICAgIC8vIHNlYXJjaCBhbGwgY29sdW1uIGZpZWxkc1xyXG4gICAgICBpZiAodGhpcy5nbG9iYWxGaWx0ZXIpIHtcclxuICAgICAgICBsZXQgZXhwcmVzc2lvbiA9ICcnO1xyXG4gICAgICAgIGxldCBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSk7XHJcbiAgICAgICAga2V5cy5mb3JFYWNoKChrZXkpID0+IHtcclxuICAgICAgICAgIGV4cHJlc3Npb24gPVxyXG4gICAgICAgICAgICBleHByZXNzaW9uICtcclxuICAgICAgICAgICAgYGRhdGEuJHtrZXl9LnRvU3RyaW5nKCkudHJpbSgpLnRvTG93ZXJDYXNlKCkuaW5kZXhPZih0aGlzLmdsb2JhbEZpbHRlci50b0xvd2VyQ2FzZSgpKSAhPT0gLTEgfHxgO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgIGV4cHJlc3Npb24uY2hhckF0KGV4cHJlc3Npb24ubGVuZ3RoIC0gMikgK1xyXG4gICAgICAgICAgICBleHByZXNzaW9uLmNoYXJBdChleHByZXNzaW9uLmxlbmd0aCAtIDEpID09XHJcbiAgICAgICAgICAnfHwnXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBleHByZXNzaW9uID0gZXhwcmVzc2lvbi5zdWJzdHJpbmcoMCwgZXhwcmVzc2lvbi5sZW5ndGggLSAyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVzdWx0ID0gZXZhbChleHByZXNzaW9uKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoIXJlc3VsdCkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgICBsZXQgc2VhcmNoU3RyaW5nID0gSlNPTi5wYXJzZShmaWx0ZXIpO1xyXG4gICAgICAvL3NlYXJjaCBzaW5nbGUgY29sdW1uIGZpZWxkXHJcbiAgICAgIGlmICh0aGlzLmluZGl2aWR1YWxGaWx0ZXIpIHtcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgZGF0YVt0aGlzLmluZGl2aWR1YWxGaWx0ZXJdXHJcbiAgICAgICAgICAgIC50b1N0cmluZygpXHJcbiAgICAgICAgICAgIC50cmltKClcclxuICAgICAgICAgICAgLnRvTG93ZXJDYXNlKClcclxuICAgICAgICAgICAgLmluZGV4T2YoXHJcbiAgICAgICAgICAgICAgc2VhcmNoU3RyaW5nW3RoaXMuaW5kaXZpZHVhbEZpbHRlcl0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpXHJcbiAgICAgICAgICAgICkgIT09IC0xXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gdGFibGVGaWx0ZXJQcmVkaWNhdGU7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBhc3NpZ25zIHRoZSBzZWFyY2ggdmFsdWUgdG8gbWF0IHRhYmxlIGRhdGEgc291cmNlIHRvIGFwcGx5IHRoZSBmaWx0ZXIuXHJcbiAgICogQHBhcmFtIHNlYXJjaFZhbHVlIHZhbHVlIHRvIGJlIHNlYXJjaGVkIGZyb20gdGFibGUgcm93cy5cclxuICAgKi9cclxuICBhcHBseUdsb2JhbEZpbHRlcihzZWFyY2hWYWx1ZTogc3RyaW5nKSB7XHJcbiAgICB0aGlzLmdsb2JhbEZpbHRlciA9IHNlYXJjaFZhbHVlO1xyXG4gICAgbGV0IGNvbHVtbnM6IGFueSA9IHt9O1xyXG4gICAgdGhpcy5jb2x1bW5zQXJyYXkuZm9yRWFjaCgoY29sdW1uOiBNVEV4Q29sdW1uKSA9PiB7XHJcbiAgICAgIGlmIChjb2x1bW4uZmllbGQpIGNvbHVtbnNbY29sdW1uLmZpZWxkXSA9IHNlYXJjaFZhbHVlO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyID0gSlNPTi5zdHJpbmdpZnkoY29sdW1ucyk7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGFwcGx5IGNvbHVtbiBiYXNlZCBmaWx0ZXJpbmdcclxuICAgKiBAcGFyYW0gc2VhcmNoVmFsdWUgdmFsdWUgdG8gYmUgc2VhcmNoZWQgZnJvbSB0YWJsZSByb3dzLlxyXG4gICAqIEBwYXJhbSBjb2x1bW4gZmlsdGVyIHdpbGwgYmUgYXBwbGllZCBiYXNlZCBvbiB0aGlzIGNvbHVtbiBmaWVsZC5cclxuICAgKi9cclxuICBhcHBseUNvbHVtbkZpbHRlcihzZWFyY2hWYWx1ZTogRmlsdGVyU2VhcmNoVmFsdWUsIGNvbHVtbjogTVRFeENvbHVtbikge1xyXG4gICAgdGhpcy5pbmRpdmlkdWFsRmlsdGVyID0gY29sdW1uLmZpZWxkO1xyXG4gICAgdGhpcy5maWx0ZXJWYWx1ZXNbY29sdW1uLmZpZWxkXSA9IHNlYXJjaFZhbHVlW2NvbHVtbi5maWVsZF07XHJcbiAgICB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyID0gSlNPTi5zdHJpbmdpZnkodGhpcy5maWx0ZXJWYWx1ZXMpO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2Qgd2lsbCB0YWtlIHJvdyBhbmQgaXRzIGluZGV4IGVuYWJsZSBpbmxpbmUgZWRpdGluZyB0b29scyBvbiB0aGF0IHJvdy5cclxuICAgKiBAcGFyYW0gcm93IHJvdyBvbiB3aGljaCB1c2VyIHdhbnRzIHRvIGRvIGVkaXQuXHJcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSByb3cgd2hlcmUgaW5saW5lIGVkaXRpbmcgd2lsbCBiZSBlbmFibGVkLlxyXG4gICAqL1xyXG4gIGVuYWJsZUlubGluZUVkaXRpbmcocm93OiBhbnksIGluZGV4OiBudW1iZXIpIHtcclxuICAgIGNvbnN0IHJvd0RhdGE6IGFueSA9IHt9O1xyXG4gICAgcm93RGF0YVsnZScgKyBpbmRleF0gPSB7IC4uLnJvdyB9O1xyXG4gICAgdGhpcy5yb3dEYXRhVGVtcCA9IHJvd0RhdGE7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgdGhpcy50YWJsZURhdGFbaW5kZXhdWydlZGl0YWJsZSddID0gIXRoaXMudGFibGVEYXRhW2luZGV4XVsnZWRpdGFibGUnXTtcclxuICAgIH0sIDApO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2Qgd2lsbCBjcmVhdGUgYW5kIHJldHVybiBkYXRhIHRvIGlubGluZSBlZGl0aW5nIHRlbXBsYXRlLlxyXG4gICAqIEBwYXJhbSByb3cgcm93IG9uIHdoaWNoIHVzZXIgd2FudHMgdG8gZG8gZWRpdC5cclxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIHJvdyB3aGVyZSBpbmxpbmUgZWRpdGluZyB3aWxsIGJlIGVuYWJsZWQuXHJcbiAgICogQHBhcmFtIGNvbHVtbiBjdXJyZW50IGNvbHVtbiBvZiB0aGUgdGFibGUuXHJcbiAgICovXHJcbiAgZ2V0SW5saW5lRWRpdGluZ0RhdGEocm93OiBNVEV4Um93LCBpbmRleDogbnVtYmVyLCBjb2x1bW46IE1URXhDb2x1bW4pIHtcclxuICAgIHRoaXMuaW5saW5lRWRpdGluZ1RlbXBsYXRlUmVmRGF0YSA9IHtcclxuICAgICAgcm93OiB7IC4uLnJvdyB9LFxyXG4gICAgICBjb2x1bW46IHsgLi4uY29sdW1uIH0sXHJcbiAgICAgIGluZGV4OiBpbmRleCxcclxuICAgICAgdXBkYXRlRnVuYzogdGhpcy51cGRhdGVJbmxpbmVUZW1wbGF0ZURhdGEsXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIHRoaXMuaW5saW5lRWRpdGluZ1RlbXBsYXRlUmVmRGF0YTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIHdpbGwgdGFrZSBkYXRhIGZyb20gaW5saW5lIGVkaXRpbmcgdGVtcGxhdGUgYW5kIHVwZGF0ZSBpbiB0YWJsZSBkYXRhIHNvdXJjZS5cclxuICAgKiBAcGFyYW0gcm93IHVwZGF0ZWQgcm93IGZyb20gaW5saW5lIGVkaXRpbmcgdGVtcGxhdGUuXHJcbiAgICovXHJcbiAgdXBkYXRlSW5saW5lVGVtcGxhdGVEYXRhID0gKHJvdzogTVRFeFJvdykgPT4ge1xyXG4gICAgdGhpcy5zZXJ2aWNlLnNlbGVjdGVkUm93Lm5leHQocm93KTtcclxuICB9O1xyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBzZXQgZGF0YSBmb3IgaW4tY2VsbCBlZGl0aW5nLlxyXG4gICAqIEBwYXJhbSByb3cgcm93IG9uIHdoaWNoIHVzZXIgd2FudHMgdG8gZG8gZWRpdC5cclxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIHJvdyB3aGVyZSBpbmxpbmUgZWRpdGluZyB3aWxsIGJlIGVuYWJsZWQuXHJcbiAgICovXHJcbiAgc2V0Q2VsbERhdGEocm93OiBNVEV4Um93LCBpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmN1cnJlbnRSb3cgPSB7IC4uLnJvdyB9O1xyXG4gICAgdGhpcy5jdXJyZW50Um93SW5kZXggPSBpbmRleDtcclxuICAgIHRoaXMucm93RGF0YVRlbXBbJ2UnICsgaW5kZXhdID0geyAuLi5yb3cgfTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgd2lsbCByZXN0b3JlIHRoZSBkYXRhIGFuZCBjZW5jZWwgdGhlIGlubGluZSBlZGl0aW5nLlxyXG4gICAqIEBwYXJhbSByb3cgcm93IG9uIHdoaWNoIHVzZXIgd2FudHMgdG8gZG8gZWRpdC5cclxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIHJvdyB3aGVyZSBpbmxpbmUgZWRpdGluZyB3aWxsIGJlIGVuYWJsZWQuXHJcbiAgICovXHJcbiAgY2FuY2VsSW5saW5lRWRpdGluZyhyb3c6IE1URXhSb3csIGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMudGFibGVEYXRhLmZpbHRlcigoYTogYW55LCBpOiBudW1iZXIpID0+IGkgPT0gaW5kZXgpWzBdWydlZGl0YWJsZSddID1cclxuICAgICAgIXRoaXMudGFibGVEYXRhLmZpbHRlcigoYTogYW55LCBpOiBudW1iZXIpID0+IGkgPT0gaW5kZXgpWzBdWydlZGl0YWJsZSddO1xyXG4gICAgdGhpcy5kYXRhU291cmNlID0gbmV3IE1hdFRhYmxlRGF0YVNvdXJjZSh0aGlzLnRhYmxlRGF0YSk7XHJcbiAgICB0aGlzLnJvd0RhdGFUZW1wWydlJyArIGluZGV4XSA9IHt9O1xyXG4gICAgdGhpcy5zZXJ2aWNlLnNlbGVjdGVkUm93Lm5leHQodW5kZWZpbmVkKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIHdpbGwgc2F2ZSBhbmQgdXBkYXRlIHRoZSBpbmxpbmUgZWRpdGluZyBkYXRhIGFuZCBlbWl0IHRoZSB1cGRhdGUgcm93IGFuZCBpbmRleC5cclxuICAgKiBAcGFyYW0gcm93IHJvdyBvbiB3aGljaCB1c2VyIHdhbnRzIHRvIGRvIGVkaXQuXHJcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSByb3cgd2hlcmUgaW5saW5lIGVkaXRpbmcgd2lsbCBiZSBlbmFibGVkLlxyXG4gICAqL1xyXG4gIHNhdmVJbmxpbmVFZGl0aW5nKHJvdzogTVRFeFJvdywgaW5kZXg6IG51bWJlcikge1xyXG4gICAgaWYgKCF0aGlzLmlubGluZUVkaXRpbmdUZW1wbGF0ZVJlZikge1xyXG4gICAgICB0aGlzLnRhYmxlRGF0YVtpbmRleF0gPSB7IC4uLnRoaXMucm93RGF0YVRlbXBbJ2UnICsgaW5kZXhdIH07XHJcbiAgICAgIHJvdyA9IHsgLi4udGhpcy5yb3dEYXRhVGVtcFsnZScgKyBpbmRleF0gfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxldCBjaGFuZ2VkRGF0YSA9IHRoaXMuc2VydmljZS5zZWxlY3RlZFJvdy52YWx1ZTtcclxuICAgICAgaWYgKGNoYW5nZWREYXRhKSB7XHJcbiAgICAgICAgdGhpcy50YWJsZURhdGFbaW5kZXhdID0geyAuLi5jaGFuZ2VkRGF0YSB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VGFibGVEYXRhU291cmNlKHRoaXMudGFibGVEYXRhKTtcclxuICAgIHRoaXMucm93RGF0YVRlbXBbJ2UnICsgaW5kZXhdID0ge307XHJcbiAgICBsZXQgZGF0YTogUm93Q2hhbmdlID0ge1xyXG4gICAgICByb3c6IHJvdyxcclxuICAgICAgaW5kZXg6IGluZGV4LFxyXG4gICAgfTtcclxuICAgIHRoaXMuaW5saW5lQ2hhbmdlLmVtaXQoZGF0YSk7XHJcbiAgICB0aGlzLnRhYmxlRGF0YVtpbmRleF1bJ2VkaXRhYmxlJ10gPSBmYWxzZTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIHdpbGwgc2F2ZSBhbmQgdXBkYXRlIHRoZSBjZWxsIGVkaXRpbmcgZGF0YSBhbmQgZW1pdCB0aGUgdXBkYXRlIHJvdyBhbmQgaW5kZXguXHJcbiAgICovXHJcbiAgc2F2ZUNlbGxFZGl0aW5nKCkge1xyXG4gICAgdGhpcy5jZWxsRWRpdGluZyA9IHt9O1xyXG4gICAgbGV0IGluZGV4ID0gdGhpcy5jdXJyZW50Um93SW5kZXg7XHJcbiAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICBpZiAodGhpcy5jZWxsRWRpdGluZ1RlbXBsYXRlUmVmKSB7XHJcbiAgICAgICAgbGV0IGNoYW5nZWREYXRhID0gdGhpcy5zZXJ2aWNlLnNlbGVjdGVkUm93LnZhbHVlO1xyXG4gICAgICAgIGlmIChjaGFuZ2VkRGF0YSkge1xyXG4gICAgICAgICAgdGhpcy50YWJsZURhdGFbaW5kZXhdID0geyAuLi5jaGFuZ2VkRGF0YSB9O1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnRhYmxlRGF0YVtpbmRleF0gPSB7IC4uLnRoaXMucm93RGF0YVRlbXBbJ2UnICsgaW5kZXhdIH07XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5kYXRhU291cmNlID0gbmV3IE1hdFRhYmxlRGF0YVNvdXJjZSh0aGlzLnRhYmxlRGF0YSk7XHJcbiAgICAgIHRoaXMucm93RGF0YVRlbXBbJ2UnICsgaW5kZXhdID0ge307XHJcbiAgICAgIGxldCBkYXRhOiBSb3dDaGFuZ2UgPSB7XHJcbiAgICAgICAgcm93OiB7IC4uLnRoaXMudGFibGVEYXRhW2luZGV4XSB9LFxyXG4gICAgICAgIGluZGV4OiBpbmRleCxcclxuICAgICAgfTtcclxuICAgICAgdGhpcy5jdXJyZW50Um93SW5kZXggPSAtMTtcclxuICAgICAgdGhpcy5jZWxsQ2hhbmdlLmVtaXQoZGF0YSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCB3aWxsIGRlbGV0ZSB0aGUgcm93IGZyb20gdGhlIGdpdmVuIGluZGV4IGFuZCBlbWl0IHRoZSBkZWxldGVkIHJvdyBhbmQgaW5kZXguXHJcbiAgICogQHBhcmFtIHJvdyByb3cgdG8gYmUgZGVsZXRlZC5cclxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIHJvdyB0byBiZSBkZWxldGVkLlxyXG4gICAqL1xyXG4gIGRlbGV0ZVJvdyhyb3c6IGFueSwgaW5kZXg6IG51bWJlcikge1xyXG4gICAgdGhpcy50YWJsZURhdGEuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIHRoaXMuZGF0YVNvdXJjZSA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UodGhpcy50YWJsZURhdGEpO1xyXG4gICAgdGhpcy5kYXRhU291cmNlLnBhZ2luYXRvciA9IHRoaXMucGFnaW5hdG9yO1xyXG4gICAgdGhpcy5kYXRhU291cmNlLnNvcnQgPSB0aGlzLnNvcnQ7XHJcbiAgICB0aGlzLnJvd0RlbGV0ZWQuZW1pdCh7IHJlbW92ZWRSb3c6IHJvdywgZnJvbUluZGV4OiBpbmRleCB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCB3aWxsIGV4cGFuZCBvciBjb2xsYXBzZSB0aGUgcm93IGFuZCBlbWl0IGV4cGFuZCBldmVudC5cclxuICAgKiBAcGFyYW0gcm93IHJvdyB0byBiZSBleHBhbmRlZCBvciBjb2xsYXBzZWQuXHJcbiAgICogQHBhcmFtIGV4cGFuZCB2YWx1ZSB1c2VkIHRvIGV4cGFuZCBvciBjb2xsYXBzZSB0aGUgcm93LlxyXG4gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiB0aGUgcm93LlxyXG4gICAqL1xyXG4gIGV4cGFuZFJvdyhyb3c6IE1URXhSb3csIGV4cGFuZDogYm9vbGVhbiwgaW5kZXg6IG51bWJlcikge1xyXG4gICAgaWYgKHRoaXMuZXhwYW5kUm93cykge1xyXG4gICAgICB0aGlzLmV4cGFuc2lvbkNoYW5nZS5lbWl0KHsgZGF0YTogcm93LCBleHBhbmRlZDogZXhwYW5kLCBpbmRleDogaW5kZXggfSk7XHJcbiAgICAgIHRoaXMuZXhwYW5kZWRFbGVtZW50ID0gdGhpcy5leHBhbmRlZEVsZW1lbnQgPT09IHJvdyA/IG51bGwgOiByb3c7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHNldCBkYXRhIGZvciBwb3B1cCBjb21wb25lbnQgYW5kIG9wZW4gZWRpdGluZyBkaWFsb2cuXHJcbiAgICogQHBhcmFtIHJvdyByb3cgd2hpY2ggdXNlZCB3YW50IHRvIGVkaXQuXHJcbiAgICovXHJcbiAgb3BlbkVkaXRpbmdEaWFsb2cocm93OiBNVEV4Um93KSB7XHJcbiAgICBjb25zdCBkaWFsb2dDb25maWcgPSBuZXcgTWF0RGlhbG9nQ29uZmlnKCk7XHJcbiAgICBkaWFsb2dDb25maWcuZGlzYWJsZUNsb3NlID0gdHJ1ZTtcclxuICAgIGRpYWxvZ0NvbmZpZy53aWR0aCA9ICc0MCUnO1xyXG4gICAgZGlhbG9nQ29uZmlnLmhlaWdodCA9ICc3MCUnO1xyXG4gICAgZGlhbG9nQ29uZmlnLm1heFdpZHRoID0gJzEwMCUnO1xyXG4gICAgbGV0IHJvd0RhdGEgPSB7IC4uLnJvdyB9O1xyXG4gICAgZGlhbG9nQ29uZmlnLmRhdGEgPSB7XHJcbiAgICAgIHJvdzogcm93RGF0YSxcclxuICAgICAgY29sdW1uczogWy4uLnRoaXMuY29sdW1uc0FycmF5XSxcclxuICAgICAgdGVtcGxhdGVSZWY6IHRoaXMucG9wdXBFZGl0aW5nVGVtcGxhdGVSZWYsXHJcbiAgICB9O1xyXG4gICAgdGhpcy5kaWFsb2dcclxuICAgICAgLm9wZW4oRWRpdGluZ0NvbXBvbmVudCwgZGlhbG9nQ29uZmlnKVxyXG4gICAgICAuYWZ0ZXJDbG9zZWQoKVxyXG4gICAgICAuc3Vic2NyaWJlKChkYXRhKSA9PiB7XHJcbiAgICAgICAgbGV0IGluZGV4ID0gdGhpcy50YWJsZURhdGEuaW5kZXhPZihyb3cpO1xyXG4gICAgICAgIGlmIChkYXRhICYmIGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgIHRoaXMudGFibGVEYXRhW2luZGV4XSA9IGRhdGE7XHJcbiAgICAgICAgICB0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VGFibGVEYXRhU291cmNlKHRoaXMudGFibGVEYXRhKTtcclxuICAgICAgICAgIGxldCBkYXRhQ2hhbmdlOiBSb3dDaGFuZ2UgPSB7XHJcbiAgICAgICAgICAgIHJvdzogZGF0YSxcclxuICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgIHRoaXMucG9wdXBDaGFuZ2UuZW1pdChkYXRhQ2hhbmdlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gdXNlZCB0byBjaGVjayB3aGV0aGVyIGFsbCByb3dzIGFyZSBzZWxlY3RlZC5cclxuICAgKi9cclxuICBpc0FsbFNlbGVjdGVkKCkge1xyXG4gICAgY29uc3QgbnVtU2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGlvbi5zZWxlY3RlZC5sZW5ndGg7XHJcbiAgICBjb25zdCBudW1Sb3dzID0gdGhpcy5kYXRhU291cmNlLmRhdGEubGVuZ3RoO1xyXG4gICAgcmV0dXJuIG51bVNlbGVjdGVkID09PSBudW1Sb3dzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIHRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gdG9nZ2xlIHRoZSBhbGwgYW5kIG5vIHJvd3Mgc2VsZWN0aW9uLlxyXG4gICAqL1xyXG4gIHRvZ2dsZUFsbFJvd3MoKSB7XHJcbiAgICBpZiAodGhpcy5pc0FsbFNlbGVjdGVkKCkpIHtcclxuICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zZWxlY3Rpb24uc2VsZWN0KC4uLnRoaXMuZGF0YVNvdXJjZS5kYXRhKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHJldHVybiBhcmlhLWxhYmVsIGZvciBzZWxlY3Rpb24gY29sdW1uIGNoZWNrYm94cy5cclxuICAgKiBAcGFyYW0gcm93IHJvdyBmcm9tIHRhYmxlLlxyXG4gICAqIEByZXR1cm5zIGxhYmVscyBmb3Igc2VsZWN0aW9uIGNvbHVtbiBjaGVja2JveHMuXHJcbiAgICovXHJcbiAgY2hlY2tib3hMYWJlbChyb3c/OiBhbnkpOiBzdHJpbmcge1xyXG4gICAgaWYgKCFyb3cpIHtcclxuICAgICAgcmV0dXJuIGAke3RoaXMuaXNBbGxTZWxlY3RlZCgpID8gJ2Rlc2VsZWN0JyA6ICdzZWxlY3QnfSBhbGxgO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGAke3RoaXMuc2VsZWN0aW9uLmlzU2VsZWN0ZWQocm93KSA/ICdkZXNlbGVjdCcgOiAnc2VsZWN0J30gcm93ICR7XHJcbiAgICAgIHJvdy5wb3NpdGlvbiArIDFcclxuICAgIH1gO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIGNyZWF0ZSBmb3JtIGNvbnRyb2wgZm9yIGNvbHVtbnMgZm9yIGhpZGluZyBhbmQgYW5kIHBpbm5pbmcgcHVycG9zZVxyXG4gICAqIEBwYXJhbSBjb2x1bW5zIGxpc3Qgb2YgY29sdW1ucyB0byBiZSBkaXNwbGF5ZWRcclxuICAgKi9cclxuICBzZXRUb29sYmFyTWVudUNvbnRyb2xzKGNvbHVtbnM6IE1URXhDb2x1bW5bXSkge1xyXG4gICAgaWYgKGNvbHVtbnMubGVuZ3RoID4gMCAmJiB0aGlzLnNob3dUb29sYmFyKSB7XHJcbiAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5mb3JtQnVpbGRlcnNTZXJ2aWNlLmdyb3VwKHt9KTtcclxuICAgICAgY29sdW1ucy5mb3JFYWNoKChjb2x1bW46IE1URXhDb2x1bW4pID0+IHtcclxuICAgICAgICBjb25zdCBjb250cm9sID0gdGhpcy5mb3JtQnVpbGRlcnNTZXJ2aWNlLmNvbnRyb2wodHJ1ZSk7XHJcbiAgICAgICAgZ3JvdXAuYWRkQ29udHJvbChjb2x1bW4uZmllbGQsIGNvbnRyb2wpO1xyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5oaWRlU2hvd01lbnVHcm91cCA9IGdyb3VwO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQHBhcmFtIGNvbHVtbiBjdXJyZW50IGNvbHVtblxyXG4gICAqIEBwYXJhbSBldmVudCBtb3VzZSBldmVudCB1c2VkIHRvIHNldCB0aGUgbWVudSBwb3NpdGlvblxyXG4gICAqL1xyXG4gIG9wZW5QaW5uYWJsZVByb3BlcnR5TWVudShjb2x1bW46IE1URXhDb2x1bW4sIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICB0aGlzLm1lbnVYID0gZXZlbnQuY2xpZW50WDtcclxuICAgIHRoaXMubWVudVkgPSBldmVudC5jbGllbnRZO1xyXG4gICAgbGV0IG9wdGlvbnM6IE1URXhDb2x1bW5QaW5PcHRpb25bXSA9IFtcclxuICAgICAge1xyXG4gICAgICAgIGxhYmVsOiAnUGluIExlZnQnLFxyXG4gICAgICAgIHZhbHVlOiAnbGVmdCcsXHJcbiAgICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGZpZWxkOiBjb2x1bW4uZmllbGQsXHJcbiAgICAgIH0sXHJcbiAgICAgIHtcclxuICAgICAgICBsYWJlbDogJ1BpbiBSaWdodCcsXHJcbiAgICAgICAgdmFsdWU6ICdyaWdodCcsXHJcbiAgICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGZpZWxkOiBjb2x1bW4uZmllbGQsXHJcbiAgICAgIH0sXHJcbiAgICAgIHsgbGFiZWw6ICdObyBQaW4nLCB2YWx1ZTogbnVsbCwgc2VsZWN0ZWQ6IGZhbHNlLCBmaWVsZDogY29sdW1uLmZpZWxkIH0sXHJcbiAgICBdO1xyXG4gICAgaWYgKGNvbHVtbi5waW5uZWQgJiYgY29sdW1uLnBpbm5lZCAhPT0gbnVsbCkge1xyXG4gICAgICBvcHRpb25zLmZvckVhY2goKG9wdDogTVRFeENvbHVtblBpbk9wdGlvbikgPT4ge1xyXG4gICAgICAgIGlmIChvcHQudmFsdWUgPT09IGNvbHVtbi5waW5uZWQpIHtcclxuICAgICAgICAgIG9wdC5zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSBpZiAoY29sdW1uLnBpbm5lZCA9PSBudWxsIHx8IGNvbHVtbi5waW5uZWQgPT0gJ251bGwnKSB7XHJcbiAgICAgIG9wdGlvbnNbMl0uc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jb2x1bW5QaW5uaW5nT3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICB0aGlzLmNvbHVtbk1lbnVUcmlnZ2VyLm9wZW5NZW51KCk7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHJlc2V0IG1lbnUgY2hlY2tzIHdoZW4gcmVxdWlyZWQuXHJcbiAgICovXHJcbiAgcmVzZXRNZW51Q2hlY2tzKCkge1xyXG4gICAgdGhpcy5oaWRlU2hvd01lbnVDdHJsID0gZmFsc2U7XHJcbiAgICB0aGlzLnNob3dIaWRlQ29sdW1uc0FycmF5ID0gW107XHJcbiAgICB0aGlzLmNvbHVtblBpbk1lbnVDdHJsID0gZmFsc2U7XHJcbiAgICB0aGlzLmNvbHVtblBpbm5pbmdPcHRpb25zID0gW107XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGZpbHRlciBjb2x1bW5zIGZvciBtZW51cyBsaWtlIHBpbm5pbmcgb3IgaGlkZSBzaG93IG1lbnUuXHJcbiAgICogQHBhcmFtIHZhbHVlIHNlYXJjaCB2YWx1ZSB0byBmaWx0ZXIgY29sdW5tc1xyXG4gICAqL1xyXG4gIGZpbHRlckNvbHVtbnModmFsdWU6IHN0cmluZykge1xyXG4gICAgaWYgKHZhbHVlICE9PSAnJykge1xyXG4gICAgICB0aGlzLnNob3dIaWRlQ29sdW1uc0FycmF5ID0gdGhpcy5jb2x1bW5zQXJyYXkuZmlsdGVyKFxyXG4gICAgICAgIChjb2w6IE1URXhDb2x1bW4pID0+IHtcclxuICAgICAgICAgIHJldHVybiBjb2wuaGVhZGVyIS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2hvd0hpZGVDb2x1bW5zQXJyYXkgPSB0aGlzLmNvbHVtbnNBcnJheTtcclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gb3BlbiBoaWRlIHNob3cgY29sdW1uIG1lbnUuXHJcbiAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyBhcnJheSB0byBkaXNwbGF5IGluIGhpZGUgc2hvdyBtZW51LlxyXG4gICAqL1xyXG4gIG9wZW5IaWRlU2hvd01lbnUoY29sdW1uczogTVRFeENvbHVtbltdKSB7XHJcbiAgICB0aGlzLnNob3dIaWRlQ29sdW1uc0FycmF5ID0gWy4uLmNvbHVtbnNdO1xyXG4gICAgdGhpcy5jb2x1bW5NZW51VHJpZ2dlci5vcGVuTWVudSgpO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAcGFyYW0gdmFsdWVzIGNvbHVtbnNcclxuICAgKi9cclxuICB1cGRhdGVDb2x1bW5zSGlkZVNob3codmFsdWVzOiBDb2x1bW5WaXNpYmlsaXR5KSB7XHJcbiAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlcyk7XHJcbiAgICBrZXlzLmZvckVhY2goKGtleTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIHRoaXMuc2hvd0hpZGVDb2x1bW4oa2V5LCB2YWx1ZXNba2V5XSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgdGFibGUgcm93cyBhcmUgc2Nyb2xsZWQuXHJcbiAgICogQHBhcmFtIGV2ZW50IHNjcm9sbCBldmVudFxyXG4gICAqL1xyXG4gIG9uU2Nyb2xsKGV2ZW50OiBhbnkpIHtcclxuICAgIHRoaXMuc2Nyb2xsLmVtaXQoZXZlbnQpO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAcGFyYW0gcm93IHJvdyB0byBiZSB0b2dnbGVkXHJcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRvZ2dsZWQgcm93XHJcbiAgICovXHJcbiAgc2V0U2VsZWN0ZWRSb3dzKHJvdzogYW55LCBpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnNlbGVjdGlvbi50b2dnbGUocm93KTtcclxuICAgIGlmICh0aGlzLnNlbGVjdGlvbi5pc1NlbGVjdGVkKHJvdykpIHtcclxuICAgICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2VkLmVtaXQoeyByb3c6IHJvdywgaW5kZXg6IGluZGV4LCBpc1NlbGVjdGVkOiB0cnVlIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2VkLmVtaXQoeyByb3c6IHJvdywgaW5kZXg6IGluZGV4LCBpc1NlbGVjdGVkOiBmYWxzZSB9KTtcclxuICAgIH1cclxuICB9XHJcbi8qKlxyXG4gKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBkaXNwbGF5IGFsbCBoaWRkZW4gcm93cy5cclxuICovXHJcbiAgc2hvd0hpZGRlblJvd3MoKSB7XHJcbiAgICB0aGlzLmhpZGVSb3dzID0gZmFsc2U7XHJcbiAgICB0aGlzLnNlbGVjdGlvbi5jbGVhcigpO1xyXG4gICAgdGhpcy5oaWRkZW5DdHJsLmNsZWFyKCk7XHJcbiAgfVxyXG4vKipcclxuICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gaGlkZSBhbGwgc2VsZWN0ZWQgcm93cy5cclxuICovXHJcbiAgaGlkZVNlbGVjdGVkUm93cygpIHtcclxuICAgIGlmICghdGhpcy5zZWxlY3Rpb24uaXNFbXB0eSgpKSB7XHJcbiAgICAgIGxldCB2YWx1ZXMgPSBbLi4udGhpcy5zZWxlY3Rpb24uc2VsZWN0ZWRdO1xyXG4gICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMuaGlkZGVuQ3RybC5pc1NlbGVjdGVkKHZhbHVlKSkge1xyXG4gICAgICAgICAgdGhpcy5oaWRkZW5DdHJsLnRvZ2dsZSh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIoKTtcclxuICAgICAgdGhpcy5oaWRlUm93cyA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG4vKipcclxuICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gcmVjYWxjdWxhdGUgdGhlIHJlcXVpcmVkIHZhbHVlcyBmb3IgdGFibGUuXHJcbiAqL1xyXG4gIHJlQ2FsKCkge1xyXG4gICAgaWYgKHRoaXMuc2hvd1BhZ2luYXRvcikge1xyXG4gICAgICB0aGlzLmRhdGFTb3VyY2UucGFnaW5hdG9yID0gdGhpcy5wYWdpbmF0b3I7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5zb3J0aW5nKSB7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZS5zb3J0ID0gdGhpcy5zb3J0O1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuY29sdW1uRmlsdGVyKSB7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZS5maWx0ZXJQcmVkaWNhdGUgPSB0aGlzLmNyZWF0ZUZpbHRlcigpO1xyXG4gICAgfVxyXG4gIH1cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgaW4gY29uc3RydWN0b3IgbWV0aG9kIHRvIGFkZCBTVkdzIGludG8gaWNvbiByZWdpc3RyYXRpb24uXHJcbiAqL1xyXG4gIGFkZEljb25zVG9SZWdpc3RyeSgpIHtcclxuICAgIGxldCB5ID0gdGhpcy5kb21TYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFJlc291cmNlVXJsKFxyXG4gICAgICBgYXNzZXRzL3BpblJpZ2h0LnN2Z2BcclxuICAgICk7XHJcbiAgICBsZXQgaWNvbk5hbWVzID0gWydwaW5MZWZ0JywgJ3BpblJpZ2h0JywgJ3Bpbk5vbmUnLCAncGlubmVkJywgJ3Bpbkljb24nXTtcclxuICAgIGljb25OYW1lcy5mb3JFYWNoKChpY29uKSA9PiB7XHJcbiAgICAgIHRoaXMubWF0SWNvblJlZ2lzdHJ5LmFkZFN2Z0ljb24oXHJcbiAgICAgICAgaWNvbixcclxuICAgICAgICB0aGlzLmRvbVNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0UmVzb3VyY2VVcmwoXHJcbiAgICAgICAgICBgYXNzZXRzLyR7aWNvbn0uc3ZnYFxyXG4gICAgICAgIClcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG4gIH1cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGV4cG9ydCB0YWJsZSBkYXRhLlxyXG4gKiBAcGFyYW0gdHlwZSB0eXBlIG9mIGZpbGUgdG8gYmUgZXhwb3J0ZWQuXHJcbiAqL1xyXG4gIGV4cG9ydFRhYmxlKHR5cGU6IHN0cmluZykge1xyXG4gICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF0VGFibGVFeHQnICsgdGhpcy50YWJsZUlEKTtcclxuICAgIHZhciB3czogWExTWC5Xb3JrU2hlZXQgPSBYTFNYLnV0aWxzLnRhYmxlX3RvX3NoZWV0KGVsZW1lbnQpO1xyXG4gICAgd3MgPSB0aGlzLndyaXRlU2hlZXREYXRhKHdzKTtcclxuICAgIGNvbnN0IHdiOiBYTFNYLldvcmtCb29rID0gWExTWC51dGlscy5ib29rX25ldygpO1xyXG4gICAgWExTWC51dGlscy5ib29rX2FwcGVuZF9zaGVldCh3Yiwgd3MsICdTaGVldDEnKTtcclxuICAgIFhMU1gud3JpdGVGaWxlKHdiLCBgdGFibGVzaGVldHMuJHt0eXBlfWApO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBzcGxpdCBuYW1lIG9mIGZpbHRlciByb3cgaGVhZGVyIHRvIGdldCBpbmRleC5cclxuICAgKiBAcGFyYW0gdmFsdWUgdmFsdWUgdG8gYmUgc3BsaXRlZCBmb3IgaW5kZXguXHJcbiAgICogQHJldHVybnMgV2lsbCByZXR1cm4gaW5kZXggb2YgY29sdW1uIGZyb20gdmFsdWUuXHJcbiAgICovXHJcbiAgcmV0dXJuSW5kZXgodmFsdWU6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTnVtYmVyKHZhbHVlLnNwbGl0KCdfJylbMV0pO1xyXG4gIH1cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIG1hbmFnZSBjb2x1bW4gZmlsdGVyaW5nLCBleHBhbmRlZCBkYXRhIGZvciBleHBvcnRpbmcuXHJcbiAqIEBwYXJhbSB3cyB3b3JrIHNoZWV0XHJcbiAqIEByZXR1cm5zIGN1c3RvbSBnZW5lcmF0ZWQgd29ya3NoZWV0IHRvIGJlIHVzZWQgaW4gZXhwb3J0LlxyXG4gKi9cclxuICB3cml0ZVNoZWV0RGF0YSh3czogWExTWC5Xb3JrU2hlZXQpOiBYTFNYLldvcmtTaGVldCB7XHJcbiAgICBsZXQgZGlzcGxheWVkQ29sdW1ucyA9IHRoaXMuZ2V0RGlzcGxheWVkQ29sdW1ucygpO1xyXG4gICAgdmFyIG5NZXJnZXMgPSB0aGlzLmdldE1lcmdlSW5kZXgod3NbJyFtZXJnZXMnXSB8fCBbXSk7XHJcbiAgICB2YXIgbWVyZ2VzID0gd3NbJyFtZXJnZXMnXSB8fCBbXTtcclxuICAgIGxldCBkYXRhOiBYTFNYLldvcmtTaGVldCA9IHtcclxuICAgICAgJyFjb2xzJzogW10sXHJcbiAgICAgICchcm93cyc6IFtdLFxyXG4gICAgICAnIW1lcmdlcyc6IG5NZXJnZXMsXHJcbiAgICB9O1xyXG4gICAgdmFyIHJhbmdlID0gWExTWC51dGlscy5kZWNvZGVfcmFuZ2Uod3NbJyFyZWYnXSB8fCAnJyk7XHJcbiAgICBsZXQgZXh0cmFjb2x1bW5zID0gWydwb3B1cCcsICdkZWxldGUnLCAnc2VsZWN0JywgJ2VkaXQnXTtcclxuICAgIGxldCBrZXlzID0gT2JqZWN0LmtleXMod3MpO1xyXG4gICAgbGV0IG5LZXkgPSAnQSc7XHJcbiAgICBrZXlzLmZvckVhY2goKGtleSwgaSkgPT4ge1xyXG4gICAgICBpZiAod3Nba2V5XT8udiAmJiB0eXBlb2Ygd3Nba2V5XT8udiA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICAhZXh0cmFjb2x1bW5zLmluY2x1ZGVzKHdzW2tleV0udi50b0xvd2VyQ2FzZSgpKSAmJlxyXG4gICAgICAgICAgZGlzcGxheWVkQ29sdW1ucy5pbmNsdWRlcyh3c1trZXldLnYudG9Mb3dlckNhc2UoKSlcclxuICAgICAgICApIHtcclxuICAgICAgICAgIGxldCBsYXN0Um93SW5kZXggPSByYW5nZT8uZT8ucjtcclxuICAgICAgICAgIGRhdGFba2V5XSA9IHdzW2tleV07XHJcbiAgICAgICAgICBsZXQgY2hyID0ga2V5LmNoYXJBdCgwKTtcclxuICAgICAgICAgIGZvciAobGV0IGogPSAyOyBqIDw9IGxhc3RSb3dJbmRleDsgaisrKSB7XHJcbiAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICB3c1tjaHIgKyAoaiArIDEpXSAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgICAgICAgKHR5cGVvZiB3c1tjaHIgKyAoaiArIDEpXS52ID09PSAnc3RyaW5nJyB8fFxyXG4gICAgICAgICAgICAgICAgdHlwZW9mIHdzW2NociArIChqICsgMSldLnYgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICBkYXRhW25LZXkgKyBqXSA9IHdzW2NociArIChqICsgMSldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBuS2V5ID0gU3RyaW5nLmZyb21DaGFyQ29kZShuS2V5LmNoYXJDb2RlQXQoMCkgKyAxKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgaWYgKHRoaXMucm93U2VsZWN0aW9uKSB7XHJcbiAgICAgIGxldCBjaHIgPSAnQSc7XHJcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuZ2UuZS5jICsgMTsgaSsrKSB7XHJcbiAgICAgICAgZGF0YVtjaHIgKyAxXSA9IGRhdGFbU3RyaW5nLmZyb21DaGFyQ29kZShjaHIuY2hhckNvZGVBdCgwKSArIDEpICsgMV07XHJcbiAgICAgICAgY2hyID0gU3RyaW5nLmZyb21DaGFyQ29kZShjaHIuY2hhckNvZGVBdCgwKSArIDEpO1xyXG4gICAgICAgIGlmIChpID09IHJhbmdlLmUuYykge1xyXG4gICAgICAgICAgZGF0YVtjaHIgKyAxXSA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0aGlzLnJvd1NlbGVjdGlvbiAmJiB0aGlzLmV4cGFuZFJvd3MpIHtcclxuICAgICAgbWVyZ2VzLmZvckVhY2goKG1lcmdlKSA9PiB7XHJcbiAgICAgICAgZGF0YVsnQScgKyBtZXJnZS5zLnJdID0gd3NbJ0EnICsgKG1lcmdlLnMuciArIDEpXTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByYW5nZS5lLnItLTtcclxuICAgIGxldCBuUmVmID0gWExTWC51dGlscy5lbmNvZGVfcmFuZ2UocmFuZ2UpO1xyXG4gICAgZGF0YVsnIXJlZiddID0gblJlZjtcclxuICAgIGRhdGFbJyFmdWxscmVmJ10gPSBuUmVmO1xyXG4gICAgcmV0dXJuIGRhdGE7XHJcbiAgfVxyXG4gIGdldE1lcmdlSW5kZXgobWVyZ2VzOiBhbnlbXSkge1xyXG4gICAgdmFyIGFycjogYW55W10gPSBbXTtcclxuICAgIG1lcmdlcy5mb3JFYWNoKChlbGVtZW50OiBhbnkpID0+IHtcclxuICAgICAgYXJyLnB1c2goe1xyXG4gICAgICAgIGU6IHtcclxuICAgICAgICAgIHI6IGVsZW1lbnQuZS5yID09IDAgPyBlbGVtZW50LmUuciA6IGVsZW1lbnQuZS5yIC0gMSxcclxuICAgICAgICAgIGM6IGVsZW1lbnQuZS5jLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgczoge1xyXG4gICAgICAgICAgcjogZWxlbWVudC5zLnIgPT0gMCA/IGVsZW1lbnQucy5yIDogZWxlbWVudC5zLnIgLSAxLFxyXG4gICAgICAgICAgYzogZWxlbWVudC5zLmMsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBhcnI7XHJcbiAgfVxyXG59XHJcbiIsIjxtYXQtY2FyZCBjbGFzcz1cIm1haW4tdGFibGUtZXh0LWNvbnRhaW5lciBtYXQtZWxldmF0aW9uLXo4XCIgW3N0eWxlLndpZHRoXT1cInRhYmxlV2lkdGhcIj5cclxuICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImdsb2JhbC1zZWFyY2gtZmllbGRcIiBhcHBlYXJhbmNlPVwiZmlsbFwiICpuZ0lmPVwiZ2xvYmFsU2VhcmNoXCI+XHJcbiAgICAgICAgPG1hdC1sYWJlbD5TZWFyY2g8L21hdC1sYWJlbD5cclxuICAgICAgICA8aW5wdXQgbWF0SW5wdXQgW25nTW9kZWxdPVwiZ2xvYmFsRmlsdGVyXCIgKG5nTW9kZWxDaGFuZ2UpPVwiYXBwbHlHbG9iYWxGaWx0ZXIoJGV2ZW50KVwiIHBsYWNlaG9sZGVyPVwiRXguIE1pYVwiICNpbnB1dD5cclxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICA8bWF0LXRvb2xiYXIgY2xhc3M9XCJ0b29sYmFyLWNvbnRhaW5lclwiICpuZ0lmPVwic2hvd1Rvb2xiYXJcIiBbc3R5bGUuaGVpZ2h0XT1cInRvb2xiYXJIZWlnaHQ/dG9vbGJhckhlaWdodDonNTBweCdcIj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2xiYXItdGl0bGVcIiAqbmdJZj1cInRvb2xiYXJUaXRsZVwiPnt7dG9vbGJhclRpdGxlfX08L3NwYW4+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRvb2xiYXJUZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInRvb2xiYXJUZW1wbGF0ZVJlZlwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwiZXhhbXBsZS1zcGFjZXJcIj48L3NwYW4+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInJvd1NlbGVjdGlvbiB8fCBtdWx0aVJvd1NlbGVjdGlvblwiPlxyXG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiaGlkZS1idXR0b25cIiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cImhpZGVTZWxlY3RlZFJvd3MoKVwiPlxyXG4gICAgICAgICAgICAgICAgSGlkZSBSb3dzXHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiaGlkZS1idXR0b25cIiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInNob3dIaWRkZW5Sb3dzKClcIj5cclxuICAgICAgICAgICAgICAgIFNob3cgQWxsIFJvd3NcclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImNvbHVtbkhpZGFibGVcIiBjbGFzcz1cImhpZGUtYnV0dG9uXCIgbWF0LXN0cm9rZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJvcGVuTWVudSgnaGlkZVNob3cnLCRldmVudClcIiBtYXRUb29sdGlwPVwiQ29sdW1uIFZpc2liaWxpdHlcIiBtYXRUb29sdGlwUG9zaXRpb249XCJhYm92ZVwiPlxyXG4gICAgICAgICAgICA8bWF0LWljb24+dmlzaWJpbGl0eTwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImNvbHVtblBpbm5hYmxlXCIgY2xhc3M9XCJwaW4tYnV0dG9uXCIgbWF0LXN0cm9rZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJvcGVuTWVudSgnY29sdW1uUGluJywkZXZlbnQpXCIgbWF0VG9vbHRpcD1cIkNvbHVtbiBQaW5uaW5nXCI+XHJcbiAgICAgICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwicGluSWNvblwiPjwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImV4cG9ydEJ1dHRvbkVuYWJsZVwiIGNsYXNzPVwiZXhwb3J0LWJ1dHRvblwiIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgICAgICAoY2xpY2spPVwib3Blbk1lbnUoJ2V4cG9ydCcsJGV2ZW50KVwiIG1hdFRvb2x0aXA9XCJUYWJsZSBEYXRhIEV4cG9ydFwiPlxyXG4gICAgICAgICAgICA8bWF0LWljb24+aW1wb3J0X2V4cG9ydDwvbWF0LWljb24+IDxzcGFuPkV4cG9ydDwvc3Bhbj5cclxuICAgICAgICAgICAgPG1hdC1pY29uPmV4cGFuZF9tb3JlPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8ZGl2IHN0eWxlPVwidmlzaWJpbGl0eTogaGlkZGVuOyBwb3NpdGlvbjpmaXhlZFwiIFttYXRNZW51VHJpZ2dlckZvcl09XCJtZW51XCIgW3N0eWxlLmxlZnQucHhdPVwibWVudVhcIlxyXG4gICAgICAgICAgICBbc3R5bGUudG9wLnB4XT1cIm1lbnVZXCI+PC9kaXY+XHJcbiAgICA8L21hdC10b29sYmFyPlxyXG4gICAgPG1hdC1tZW51ICNtZW51PVwibWF0TWVudVwiIChjbG9zZWQpPVwibWVudUNsb3NlZCgpXCIgaWQ9XCJleHBvcnRNZW51XCI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImV4cG9ydE1lbnVDdHJsXCI+XHJcbiAgICAgICAgICAgIDxtYXQtb3B0aW9uIChjbGljayk9XCJleHBvcnRUYWJsZSgneGxzeCcpXCI+RXhwb3J0IHRvIEV4Y2VsPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiAoY2xpY2spPVwiZXhwb3J0VGFibGUoJ2NzdicpXCI+RXhwb3J0IHRvIENTVjwvbWF0LW9wdGlvbj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvbWF0LW1lbnU+XHJcbiAgICA8ZGl2IHN0eWxlPVwidmlzaWJpbGl0eTogaGlkZGVuOyBwb3NpdGlvbjpmaXhlZFwiICNjb2x1bW5NZW51VHJpZ2dlcj1cIm1hdE1lbnVUcmlnZ2VyXCIgW21hdE1lbnVUcmlnZ2VyRm9yXT1cImNvbHVtbk1lbnVcIlxyXG4gICAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cIm1lbnVYXCIgW3N0eWxlLnRvcC5weF09XCJtZW51WVwiPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8bWF0LW1lbnUgI2NvbHVtbk1lbnU9XCJtYXRNZW51XCIgKGNsb3NlZCk9XCJyZXNldE1lbnVDaGVja3MoKVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sYmFyLW1lbnUtY29udGFpbmVyXCIgKm5nSWY9XCJoaWRlU2hvd01lbnVDdHJsXCIgW2Zvcm1Hcm91cF09XCJoaWRlU2hvd01lbnVHcm91cFwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cclxuICAgICAgICAgICAgPGg0IGNsYXNzPVwiY29sdW1uLWhlYWRlcnNcIj5WaXNpYmxlIENvbHVtbnM8L2g0PlxyXG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cImZpbGxcIiBzdHlsZT1cIndpZHRoOiAtd2Via2l0LWZpbGwtYXZhaWxhYmxlO1wiPlxyXG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5GaWx0ZXIgQ29sdW1uczwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFsobmdNb2RlbCldPVwic2hvd0hpZGVGaWx0ZXJcIiAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDb2x1bW5zKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cclxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNob3dIaWRlLW1lbnUtY29sdW1ucy1saXN0XCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9vbGJhci1tZW51LWl0ZW1cIiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHNob3dIaWRlQ29sdW1uc0FycmF5XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCBjb2xvcj1cInByaW1hcnlcIiBjbGFzcz1cInRvb2xiYXItbWVudS1jaGVja2JveFwiIHN0eWxlPVwid2lkdGg6IG1heC1jb250ZW50O1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiY29sdW1uLmZpZWxkXCIgKGNoYW5nZSk9XCJzZXRDb2x1bW5IaWRlU2hvdygpXCI+e3tjb2x1bW4uaGVhZGVyfX08L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwidG9vbGJhci1tZW51LWNvbnRhaW5lclwiICpuZ0lmPVwiY29sdW1uUGluTWVudUN0cmxcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XHJcbiAgICAgICAgICAgIDxoNCBjbGFzcz1cImNvbHVtbi1oZWFkZXJzXCI+UGluIENvbHVtbnM8L2g0PlxyXG4gICAgICAgICAgICA8Zm9ybSBjbGFzcz1cImV4YW1wbGUtZm9ybVwiPlxyXG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJmaWxsXCIgc3R5bGU9XCJ3aWR0aDogLXdlYmtpdC1maWxsLWF2YWlsYWJsZTtcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPkZpbHRlciBDb2x1bW5zPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFsobmdNb2RlbCldPVwic2hvd0hpZGVGaWx0ZXJcIiAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJDb2x1bW5zKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCI+XHJcbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICA8L2Zvcm0+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzaG93SGlkZS1tZW51LWNvbHVtbnMtbGlzdFwiPlxyXG4gICAgICAgICAgICAgICAgPGFwcC1jb2x1bW4tcGlubmluZyBbY29sdW1uc109XCJzaG93SGlkZUNvbHVtbnNBcnJheVwiPjwvYXBwLWNvbHVtbi1waW5uaW5nPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvbWF0LW1lbnU+XHJcblxyXG4gICAgPG1hdC1wcm9ncmVzcy1iYXIgKm5nSWY9XCJsb2FkaW5nSW5kaWNhdG9yXCIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIj48L21hdC1wcm9ncmVzcy1iYXI+XHJcbiAgICA8c2VjdGlvbiBpZD1cInRhYmxlQ29udGFpbmVyXCIgY2xhc3M9XCJtYXQtdGFibGUtZXh0LWNvbnRhaW5lclwiIChzY3JvbGwpPVwib25TY3JvbGwoJGV2ZW50KVwiXHJcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCJ0YWJsZUhlaWdodCA/IHRhYmxlSGVpZ2h0IDonbWF4LWNvbnRlbnQnXCI+XHJcbiAgICAgICAgPHRhYmxlIG1hdC10YWJsZSBbaWRdPVwiJ21hdFRhYmxlRXh0Jyt0YWJsZUlEXCIgW2RhdGFTb3VyY2VdPVwiZGF0YVNvdXJjZVwiIG1hdFNvcnQgY2RrRHJvcExpc3RcclxuICAgICAgICAgICAgY2RrRHJvcExpc3RPcmllbnRhdGlvbj1cImhvcml6b250YWxcIiBtdWx0aVRlbXBsYXRlRGF0YVJvd3MgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJvbkRyb3AoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJzYXZlQ2VsbEVkaXRpbmcoKVwiIFtzdHlsZS53aWR0aF09XCJzY3JvbGxiYXJIPydtYXgtY29udGVudCc6JzEwMCUnXCI+XHJcbiAgICAgICAgICAgIDwhLS0gUm93IHNlbGVjdGlvbiBjb2x1bW4gLS0+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic2VsZWN0XCI+XHJcbiAgICAgICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIGNka0RyYWdMb2NrQXhpcz1cInhcIiBjZGtEcmFnIFtjZGtEcmFnRGlzYWJsZWRdPVwiIWRuZENvbHVtbnNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IChjaGFuZ2UpPVwiJGV2ZW50ID8gdG9nZ2xlQWxsUm93cygpIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGlvbi5oYXNWYWx1ZSgpICYmIGlzQWxsU2VsZWN0ZWQoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cInNlbGVjdGlvbi5oYXNWYWx1ZSgpICYmICFpc0FsbFNlbGVjdGVkKClcIiBbYXJpYS1sYWJlbF09XCJjaGVja2JveExhYmVsKClcIj5cclxuICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93O2xldCBpID0gZGF0YUluZGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGNoYW5nZSk9XCIkZXZlbnQgPyBzZXRTZWxlY3RlZFJvd3Mocm93LGkpIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGlvbi5pc1NlbGVjdGVkKHJvdylcIiBbYXJpYS1sYWJlbF09XCJjaGVja2JveExhYmVsKHJvdylcIj5cclxuICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd0Zvb3RlclJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPCEtLWR5bmFtaWMgY29sdW1ucyBhcmUgYmVpbmcgZ2VuZXJhdGVkIGhlcmUtLT5cclxuICAgICAgICAgICAgPGRpdiBtYXRDb2x1bW5EZWY9XCJ7e2NvbHVtblsnZmllbGQnXX19XCIgW3N0aWNreV09XCJjb2x1bW4ucGlubmVkID09ICdsZWZ0JyA/IHRydWU6ZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgW3N0aWNreUVuZF09XCJjb2x1bW4ucGlubmVkID09ICdyaWdodCcgPyB0cnVlOmZhbHNlXCIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBjb2x1bW5zQXJyYXk7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgW3N0eWxlLndpZHRoXT1cImNvbHVtbi53aWR0aFwiIFtzdHlsZS5tYXhXaWR0aF09XCJjb2x1bW4ubWF4V2lkdGhcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5taW5XaWR0aF09XCJjb2x1bW4ubWluV2lkdGhcIiBjZGtEcmFnTG9ja0F4aXM9XCJ4XCIgY2RrRHJhZyBbY2RrRHJhZ0Rpc2FibGVkXT1cIiFkbmRDb2x1bW5zXCJcclxuICAgICAgICAgICAgICAgICAgICBbY29sdW1uc1Jlc2l6YWJsZV09XCJjb2x1bW5SZXNpemFibGVcIiBbaW5kZXhdPVwiaVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIWhlYWRlclRlbXBsYXRlUmVmXCIgbWF0VG9vbHRpcD1cInt7Y29sdW1uLmhlYWRlclRvb2x0aXA/LnZhbHVlfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcFBvc2l0aW9uXT1cImNvbHVtbj8uaGVhZGVyVG9vbHRpcD8udG9vbHRpcFBvc2l0aW9uIVwiIG1hdC1zb3J0LWhlYWRlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIXNvcnRpbmcgfHwgY29sdW1uLmRpc2FibGVkID09PSB0cnVlXCI+e3tjb2x1bW4uaGVhZGVyfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImhlYWRlclRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaGVhZGVyVGVtcGxhdGVSZWZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2RhdGE6Y29sdW1ufVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2x1bW4uaGVhZGVyVGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJjb2x1bW4uaGVhZGVyVGVtcGxhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2RhdGE6Y29sdW1ufVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3cgO2xldCBpPWRhdGFJbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhcm93LmVkaXRhYmxlICYmICFjZWxsRWRpdGluZ1tpICsnXycrY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJjZWxsRWRpdGluZ1tpICsnXycrY29sdW1uLmZpZWxkXSA9IGluQ2VsbEVkaXRpbmc7c2V0Q2VsbERhdGEocm93LGkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cInt7Y29sdW1uLmNlbGxUb29sdGlwPy52YWx1ZX19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBQb3NpdGlvbl09XCJjb2x1bW4/LmNlbGxUb29sdGlwPy50b29sdGlwUG9zaXRpb24hXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFjZWxsVGVtcGxhdGVSZWYgJiYgIWNvbHVtbj8uY2VsbFRlbXBsYXRlICYmICFjZWxsVGVtcGxhdGVSZWZNYXBbY29sdW1uLmZpZWxkXVwiPnt7cm93W2NvbHVtbi5maWVsZF19fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNlbGxUZW1wbGF0ZVJlZk1hcFtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNlbGxUZW1wbGF0ZVJlZk1hcFtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7cm93OnJvdyxjb2x1bW46Y29sdW1uLGluZGV4Oml9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNlbGxUZW1wbGF0ZVJlZiAmJiBjb2x1bW4uY2VsbFRlbXBsYXRlICYmICFjZWxsVGVtcGxhdGVSZWZNYXBbY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJjb2x1bW4uY2VsbFRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7cm93OnJvdyxjb2x1bW46Y29sdW1uLGluZGV4Oml9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFjZWxsVGVtcGxhdGVSZWYgJiYgY29sdW1uLmNlbGxUZW1wbGF0ZSAmJiAhY2VsbFRlbXBsYXRlUmVmTWFwW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sdW1uLmNlbGxUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie3Jvdzpyb3csY29sdW1uOmNvbHVtbixpbmRleDppfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjZWxsVGVtcGxhdGVSZWYgJiYgIWNvbHVtbi5jZWxsVGVtcGxhdGUgJiYgIWNlbGxUZW1wbGF0ZVJlZk1hcFtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNlbGxUZW1wbGF0ZVJlZlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie3Jvdzpyb3csY29sdW1uOmNvbHVtbixpbmRleDppfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93LmVkaXRhYmxlIHx8IGNlbGxFZGl0aW5nW2kgKydfJytjb2x1bW4uZmllbGRdXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaW5saW5lRWRpdGluZ1RlbXBsYXRlUmVmICYmICFjZWxsRWRpdGluZ1tpICsnXycrY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJpbmxpbmVFZGl0aW5nVGVtcGxhdGVSZWZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntkYXRhOmdldElubGluZUVkaXRpbmdEYXRhKHJvdyxpLGNvbHVtbil9XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjZWxsRWRpdGluZ1RlbXBsYXRlUmVmICYmICEocm93LmVkaXRhYmxlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJjZWxsRWRpdGluZ1RlbXBsYXRlUmVmXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ZGF0YTpnZXRJbmxpbmVFZGl0aW5nRGF0YShyb3csaSxjb2x1bW4pfVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlubGluZUVkaXRpbmdUZW1wbGF0ZVJlZiAmJiAocm93LmVkaXRhYmxlKSAmJiByb3dEYXRhVGVtcFsnZScraV1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cImNvbHVtbi50eXBlID09ICdudW1iZXInXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWVkaXRpbmctZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cIm51bWJlclwiIFsobmdNb2RlbCldPVwicm93RGF0YVRlbXBbJ2UnK2ldW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIHN0eWxlPVwid2lkdGg6IDEwMCU7XCIgKm5nSWY9XCJjb2x1bW4udHlwZSA9PSAnc3RyaW5nJ1wiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1lZGl0aW5nLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJyb3dEYXRhVGVtcFsnZScraV1bY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJjb2x1bW4udHlwZSA9PSAnZGF0ZSdcIiBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZWRpdGluZy1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCB0eXBlPVwiZGF0ZVwiIFsobmdNb2RlbCldPVwicm93RGF0YVRlbXBbJ2UnK2ldW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwiY29sdW1uLnR5cGUgPT0gJ3NlbGVjdGlvbidcIiBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZWRpdGluZy1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IFt2YWx1ZV09XCJyb3dEYXRhVGVtcFsnZScraV1bY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93RGF0YVRlbXBbJ2UnK2ldW2NvbHVtbi5maWVsZF1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBjb2x1bW4ub3B0aW9uc1wiIFt2YWx1ZV09XCJvcHRpb25cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7b3B0aW9ufX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAqbmdJZj1cImNvbHVtbi50eXBlID09ICdib29sZWFuJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCIgWyhuZ01vZGVsKV09XCJyb3dbY29sdW1uLmZpZWxkXVwiPjwvbWF0LWNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFjZWxsRWRpdGluZ1RlbXBsYXRlUmVmICYmIGNlbGxFZGl0aW5nW2kgKydfJytjb2x1bW4uZmllbGRdXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJjb2x1bW4udHlwZSA9PSAnbnVtYmVyJ1wiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1lZGl0aW5nLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJudW1iZXJcIiBbKG5nTW9kZWwpXT1cInJvd0RhdGFUZW1wWydlJytpXVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cImNvbHVtbi50eXBlID09ICdzdHJpbmcnXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWVkaXRpbmctZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInJvd0RhdGFUZW1wWydlJytpXVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cImNvbHVtbi50eXBlID09ICdkYXRlJ1wiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1lZGl0aW5nLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJkYXRlXCIgWyhuZ01vZGVsKV09XCJyb3dEYXRhVGVtcFsnZScraV1bY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJjb2x1bW4udHlwZSA9PSAnc2VsZWN0aW9uJ1wiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1lZGl0aW5nLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgW3ZhbHVlXT1cInJvd0RhdGFUZW1wWydlJytpXVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dEYXRhVGVtcFsnZScraV1bY29sdW1uLmZpZWxkXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGNvbHVtbi5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tvcHRpb259fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiICpuZ0lmPVwiY29sdW1uLnR5cGUgPT0gJ2Jvb2xlYW4nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIiBbKG5nTW9kZWwpXT1cInJvd1tjb2x1bW4uZmllbGRdXCI+PC9tYXQtY2hlY2tib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzaG93Rm9vdGVyUm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj4ge3tjb2x1bW4uZm9vdGVyVGV4dH19IDwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZWRpdFwiIHN0aWNreUVuZD1cImZhbHNlXCI+XHJcbiAgICAgICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIGNka0RyYWdMb2NrQXhpcz1cInhcIiBjZGtEcmFnIFtjZGtEcmFnRGlzYWJsZWRdPVwidHJ1ZVwiICptYXRIZWFkZXJDZWxsRGVmXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJhY3Rpb24tY29sdW1uLWNlbGxzXCI+IEVkaXQgPC90aD5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3c7IGxldCBpID0gZGF0YUluZGV4XCIgY2xhc3M9XCJpbmxpbmUtZWRpdC1jb2x1bW4tY2VsbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImVkaXQtY29sdW1uLWljb25zXCIgKm5nSWY9XCIhcm93LmVkaXRhYmxlICYmICFyb3cuZWRpdG1vZGFsXCIgYXJpYS1oaWRkZW49XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJlbmFibGVJbmxpbmVFZGl0aW5nKHJvdyxpKVwiIGZvbnRJY29uPVwiZWRpdF9ub3RlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5saW5lLWVkaXRpbmctY29udHJvbHNcIiAqbmdJZj1cInJvdy5lZGl0YWJsZSAmJiAhcm93LmVkaXRtb2RhbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJlZGl0LWNvbHVtbi1pY29uc1wiIGFyaWEtaGlkZGVuPVwiZmFsc2VcIiAoY2xpY2spPVwic2F2ZUlubGluZUVkaXRpbmcocm93LGkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRJY29uPVwiZG9uZVwiPjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImVkaXQtY29sdW1uLWljb25zXCIgYXJpYS1oaWRkZW49XCJmYWxzZVwiIChjbGljayk9XCJjYW5jZWxJbmxpbmVFZGl0aW5nKHJvdyxpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250SWNvbj1cImNsb3NlXCI+PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPiBlZGl0IDwvdGQ+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInBvcHVwXCIgc3RpY2t5RW5kPVwiZmFsc2VcIj5cclxuICAgICAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgY2RrRHJhZ0xvY2tBeGlzPVwieFwiIGNka0RyYWcgW2Nka0RyYWdEaXNhYmxlZF09XCJ0cnVlXCIgKm1hdEhlYWRlckNlbGxEZWZcclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1jb2x1bW4tY2VsbHNcIj4gUG9wdXBcclxuICAgICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93OyBsZXQgaSA9IGluZGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGFyaWEtaGlkZGVuPVwiZmFsc2VcIiAoY2xpY2spPVwib3BlbkVkaXRpbmdEaWFsb2cocm93KVwiIGZvbnRJY29uPVwiZWRpdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZGVsZXRlXCI+XHJcbiAgICAgICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIGNka0RyYWdMb2NrQXhpcz1cInhcIiBjZGtEcmFnIFtjZGtEcmFnRGlzYWJsZWRdPVwidHJ1ZVwiICptYXRIZWFkZXJDZWxsRGVmXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJhY3Rpb24tY29sdW1uLWNlbGxzXCI+IERlbGV0ZVxyXG4gICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3c7bGV0IGk9ZGF0YUluZGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIChjbGljayk9XCJkZWxldGVSb3cocm93LGkpXCIgYXJpYS1oaWRkZW49XCJmYWxzZVwiIGFyaWEtbGFiZWw9XCJFeGFtcGxlIGhvbWUgaWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRJY29uPVwiZGVsZXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8IS0tIEV4cGFuZGVkIENvbnRlbnQgQ29sdW1uIC0gVGhlIGRldGFpbCByb3cgaXMgbWFkZSB1cCBvZiB0aGlzIG9uZSBjb2x1bW4gdGhhdCBzcGFucyBhY3Jvc3MgYWxsIGNvbHVtbnMgLS0+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJleHBhbmRSb3dzXCIgbWF0Q29sdW1uRGVmPVwiZXhwYW5kZWREZXRhaWxcIj5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50O2xldCBpPWRhdGFJbmRleCBcIlxyXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLmNvbHNwYW5dPVwiY29sdW1uc1RvRGlzcGxheVdpdGhFeHBhbmQubGVuZ3RoXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV4YW1wbGUtZWxlbWVudC1kZXRhaWxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbQGRldGFpbEV4cGFuZF09XCJlbGVtZW50ID09IGV4cGFuZGVkRWxlbWVudCA/ICdleHBhbmRlZCcgOiAnY29sbGFwc2VkJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZXhwYW5zaW9uVGVtcGxhdGVSZWZcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJleHBhbnNpb25UZW1wbGF0ZVJlZlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRleHBsaWNpdDplbGVtZW50LHJvdzplbGVtZW50LGluZGV4Oml9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGlkcyBvZiBoZWFkZXJzRmlsdGVyc0lkczsgbGV0IGk9aW5kZXhcIiBbbWF0Q29sdW1uRGVmXT1cImlkc1wiPlxyXG4gICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmlsdGVycy1jb250YWluZXJcIiBbY2xhc3MuYW5pbWF0ZV09XCJ0b2dnbGVGaWx0ZXJzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxhcHAtZmlsdGVyLWNvbHVtbnMtY29tcG9uZW50IFtvYmpdPVwiY29sdW1uc0FycmF5W3JldHVybkluZGV4KGlkcyldXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmaWx0ZXJPdXRwdXQpPVwiYXBwbHlDb2x1bW5GaWx0ZXIoJGV2ZW50LGNvbHVtbnNBcnJheVtyZXR1cm5JbmRleChpZHMpXSlcIj48L2FwcC1maWx0ZXItY29sdW1ucy1jb21wb25lbnQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPHRyIG1hdC1oZWFkZXItcm93ICptYXRIZWFkZXJSb3dEZWY9XCIgZ2V0RGlzcGxheWVkQ29sdW1ucygpOyBzdGlja3k6IHN0aWNreUhlYWRlclwiPjwvdHI+XHJcbiAgICAgICAgICAgIDx0ciBtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOmdldERpc3BsYXllZENvbHVtbnMoKTsgbGV0IGk9ZGF0YUluZGV4O1wiIGNsYXNzPVwiZGF0YS1yb3dcIlxyXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydkYXRhLXJvdyc6ZXhwYW5kUm93cywnc3RyaXBlZFJvd3MnOihzdHJpcGVkUm93cyAmJiAgaSAlIDIgPT0gMSksJ2hvdmVyQ2xhc3MnOnJvd0hvdmVyLCAnaGlkZGVuJzpoaWRkZW5DdHJsLmlzU2VsZWN0ZWQocm93KSAmJiBoaWRlUm93cywnZXhhbXBsZS1leHBhbmRlZC1yb3cnOmV4cGFuZGVkRWxlbWVudCA9PT0gcm93fVwiXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhwYW5kUm93KHJvdywgcm93ICE9PSBleHBhbmRlZEVsZW1lbnQsaSlcIj5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgPHRyIHN0eWxlPVwiaGVpZ2h0OiAwcHg7XCIgbWF0LWhlYWRlci1yb3cgY2xhc3M9XCJuby1kZWZhdWx0LWhlaWdodFwiICptYXRIZWFkZXJSb3dEZWY9XCJoZWFkZXJzRmlsdGVyc0lkc1wiPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZXhwYW5kUm93c1wiPlxyXG4gICAgICAgICAgICAgICAgPHRyIHN0eWxlPVwiaGVpZ2h0OiAwcHg7XCIgbWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogWydleHBhbmRlZERldGFpbCddXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2V4YW1wbGUtZGV0YWlsLXJvdyc6IChleHBhbmRSb3dzICYmIHJvdyA9PT0gZXhwYW5kZWRFbGVtZW50KSwnZXhwYW5kLXJvdyc6cm93ICE9PSBleHBhbmRlZEVsZW1lbnR9XCI+XHJcbiAgICAgICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3dGb290ZXJSb3dcIj5cclxuICAgICAgICAgICAgICAgIDx0ciBtYXQtZm9vdGVyLXJvdyAqbWF0Rm9vdGVyUm93RGVmPVwiZ2V0RGlzcGxheWVkQ29sdW1ucygpOyBzdGlja3k6IHN0aWNreUZvb3RlclwiPjwvdHI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwvdGFibGU+XHJcbiAgICA8L3NlY3Rpb24+XHJcbiAgICA8bWF0LXBhZ2luYXRvciAqbmdJZj1cInNob3dQYWdpbmF0b3JcIiBbcGFnZVNpemVPcHRpb25zXT1cInBhZ2VTaXplT3B0aW9uc1wiXHJcbiAgICAgICAgW3Nob3dGaXJzdExhc3RCdXR0b25zXT1cInNob3dGaXJzdExhc3RCdXR0b25zXCI+XHJcbiAgICA8L21hdC1wYWdpbmF0b3I+XHJcbjwvbWF0LWNhcmQ+Il19