@beshkari/mb-ui 0.5.0-alpha.1

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 (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/esm2022/beshkari-mb-ui.mjs +5 -0
  4. package/esm2022/lib/accordion/mb-accordion.component.mjs +37 -0
  5. package/esm2022/lib/alert/mb-alert.component.mjs +28 -0
  6. package/esm2022/lib/avatar/mb-avatar.component.mjs +32 -0
  7. package/esm2022/lib/badge/mb-badge.component.mjs +28 -0
  8. package/esm2022/lib/breadcrumb/mb-breadcrumb.component.mjs +23 -0
  9. package/esm2022/lib/button/mb-button.component.mjs +48 -0
  10. package/esm2022/lib/card/mb-card.component.mjs +28 -0
  11. package/esm2022/lib/checkbox/mb-checkbox.component.mjs +75 -0
  12. package/esm2022/lib/chip/mb-chip.component.mjs +33 -0
  13. package/esm2022/lib/combobox/mb-combobox.component.mjs +235 -0
  14. package/esm2022/lib/confirm/mb-confirm-dialog.component.mjs +44 -0
  15. package/esm2022/lib/confirm/mb-confirm.service.mjs +39 -0
  16. package/esm2022/lib/confirm/mb-confirm.types.mjs +2 -0
  17. package/esm2022/lib/datepicker/mb-datepicker.component.mjs +382 -0
  18. package/esm2022/lib/dialog/mb-dialog-container.component.mjs +37 -0
  19. package/esm2022/lib/dialog/mb-dialog-ref.mjs +17 -0
  20. package/esm2022/lib/dialog/mb-dialog.component.mjs +87 -0
  21. package/esm2022/lib/dialog/mb-dialog.service.mjs +61 -0
  22. package/esm2022/lib/dialog/mb-dialog.tokens.mjs +3 -0
  23. package/esm2022/lib/divider/mb-divider.component.mjs +18 -0
  24. package/esm2022/lib/drawer/mb-drawer.component.mjs +34 -0
  25. package/esm2022/lib/dropdown/mb-dropdown.component.mjs +24 -0
  26. package/esm2022/lib/empty/mb-empty.component.mjs +27 -0
  27. package/esm2022/lib/form-field/mb-form-field.component.mjs +24 -0
  28. package/esm2022/lib/grid/mb-grid-data.mjs +266 -0
  29. package/esm2022/lib/grid/mb-grid-export.mjs +36 -0
  30. package/esm2022/lib/grid/mb-grid-messages.mjs +10 -0
  31. package/esm2022/lib/grid/mb-grid-state-adapter.mjs +97 -0
  32. package/esm2022/lib/grid/mb-grid-state.service.mjs +47 -0
  33. package/esm2022/lib/grid/mb-grid-template.directive.mjs +109 -0
  34. package/esm2022/lib/grid/mb-grid.component.mjs +998 -0
  35. package/esm2022/lib/grid/mb-grid.types.mjs +2 -0
  36. package/esm2022/lib/i18n/mb-ui-locale.mjs +18 -0
  37. package/esm2022/lib/i18n/mb-ui-messages-en.mjs +103 -0
  38. package/esm2022/lib/i18n/mb-ui-messages-fa.mjs +103 -0
  39. package/esm2022/lib/i18n/mb-ui-messages.mjs +34 -0
  40. package/esm2022/lib/i18n/mb-ui-messages.types.mjs +2 -0
  41. package/esm2022/lib/i18n/provide-mb-ui.mjs +20 -0
  42. package/esm2022/lib/input/mb-input.component.mjs +86 -0
  43. package/esm2022/lib/pagination/mb-pagination.component.mjs +47 -0
  44. package/esm2022/lib/progress/mb-progress.component.mjs +29 -0
  45. package/esm2022/lib/radio/mb-radio-group.component.mjs +63 -0
  46. package/esm2022/lib/select/mb-select.component.mjs +73 -0
  47. package/esm2022/lib/skeleton/mb-skeleton.component.mjs +24 -0
  48. package/esm2022/lib/spinner/mb-spinner.component.mjs +21 -0
  49. package/esm2022/lib/switch/mb-switch.component.mjs +59 -0
  50. package/esm2022/lib/tabs/mb-tabs.component.mjs +31 -0
  51. package/esm2022/lib/textarea/mb-textarea.component.mjs +83 -0
  52. package/esm2022/lib/toast/mb-toast-container.component.mjs +21 -0
  53. package/esm2022/lib/toast/mb-toast.service.mjs +47 -0
  54. package/esm2022/lib/toast/mb-toast.types.mjs +2 -0
  55. package/esm2022/lib/tokens/mb-ui-config.token.mjs +11 -0
  56. package/esm2022/lib/tooltip/mb-tooltip.directive.mjs +48 -0
  57. package/esm2022/lib/utils/coerce.mjs +10 -0
  58. package/esm2022/lib/utils/mb-jalali-date.mjs +120 -0
  59. package/esm2022/public-api.mjs +56 -0
  60. package/fesm2022/beshkari-mb-ui.mjs +3828 -0
  61. package/fesm2022/beshkari-mb-ui.mjs.map +1 -0
  62. package/index.d.ts +5 -0
  63. package/lib/accordion/mb-accordion.component.d.ts +19 -0
  64. package/lib/alert/mb-alert.component.d.ts +12 -0
  65. package/lib/avatar/mb-avatar.component.d.ts +12 -0
  66. package/lib/badge/mb-badge.component.d.ts +12 -0
  67. package/lib/breadcrumb/mb-breadcrumb.component.d.ts +15 -0
  68. package/lib/button/mb-button.component.d.ts +19 -0
  69. package/lib/card/mb-card.component.d.ts +10 -0
  70. package/lib/checkbox/mb-checkbox.component.d.ts +25 -0
  71. package/lib/chip/mb-chip.component.d.ts +12 -0
  72. package/lib/combobox/mb-combobox.component.d.ts +65 -0
  73. package/lib/confirm/mb-confirm-dialog.component.d.ts +17 -0
  74. package/lib/confirm/mb-confirm.service.d.ts +12 -0
  75. package/lib/confirm/mb-confirm.types.d.ts +10 -0
  76. package/lib/datepicker/mb-datepicker.component.d.ts +87 -0
  77. package/lib/dialog/mb-dialog-container.component.d.ts +14 -0
  78. package/lib/dialog/mb-dialog-ref.d.ts +9 -0
  79. package/lib/dialog/mb-dialog.component.d.ts +27 -0
  80. package/lib/dialog/mb-dialog.service.d.ts +14 -0
  81. package/lib/dialog/mb-dialog.tokens.d.ts +13 -0
  82. package/lib/divider/mb-divider.component.d.ts +7 -0
  83. package/lib/drawer/mb-drawer.component.d.ts +14 -0
  84. package/lib/dropdown/mb-dropdown.component.d.ts +10 -0
  85. package/lib/empty/mb-empty.component.d.ts +10 -0
  86. package/lib/form-field/mb-form-field.component.d.ts +9 -0
  87. package/lib/grid/mb-grid-data.d.ts +20 -0
  88. package/lib/grid/mb-grid-export.d.ts +9 -0
  89. package/lib/grid/mb-grid-messages.d.ts +6 -0
  90. package/lib/grid/mb-grid-state-adapter.d.ts +24 -0
  91. package/lib/grid/mb-grid-state.service.d.ts +10 -0
  92. package/lib/grid/mb-grid-template.directive.d.ts +43 -0
  93. package/lib/grid/mb-grid.component.d.ts +233 -0
  94. package/lib/grid/mb-grid.types.d.ts +255 -0
  95. package/lib/i18n/mb-ui-locale.d.ts +2 -0
  96. package/lib/i18n/mb-ui-messages-en.d.ts +3 -0
  97. package/lib/i18n/mb-ui-messages-fa.d.ts +3 -0
  98. package/lib/i18n/mb-ui-messages.d.ts +5 -0
  99. package/lib/i18n/mb-ui-messages.types.d.ts +90 -0
  100. package/lib/i18n/provide-mb-ui.d.ts +7 -0
  101. package/lib/input/mb-input.component.d.ts +30 -0
  102. package/lib/pagination/mb-pagination.component.d.ts +16 -0
  103. package/lib/progress/mb-progress.component.d.ts +11 -0
  104. package/lib/radio/mb-radio-group.component.d.ts +30 -0
  105. package/lib/select/mb-select.component.d.ts +31 -0
  106. package/lib/skeleton/mb-skeleton.component.d.ts +9 -0
  107. package/lib/spinner/mb-spinner.component.d.ts +9 -0
  108. package/lib/switch/mb-switch.component.d.ts +22 -0
  109. package/lib/tabs/mb-tabs.component.d.ts +19 -0
  110. package/lib/textarea/mb-textarea.component.d.ts +29 -0
  111. package/lib/toast/mb-toast-container.component.d.ts +10 -0
  112. package/lib/toast/mb-toast.service.d.ts +15 -0
  113. package/lib/toast/mb-toast.types.d.ts +8 -0
  114. package/lib/tokens/mb-ui-config.token.d.ts +12 -0
  115. package/lib/tooltip/mb-tooltip.directive.d.ts +13 -0
  116. package/lib/utils/coerce.d.ts +3 -0
  117. package/lib/utils/mb-jalali-date.d.ts +18 -0
  118. package/package.json +50 -0
  119. package/public-api.d.ts +55 -0
  120. package/theme/_components.scss +19 -0
  121. package/theme/_dark.scss +1 -0
  122. package/theme/_density.scss +1 -0
  123. package/theme/_tokens.scss +57 -0
  124. package/theme/mb-ui.scss +28 -0
@@ -0,0 +1,998 @@
1
+ import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, EventEmitter, Inject, Input, Output, } from '@angular/core';
2
+ import { DecimalPipe, KeyValuePipe, NgClass, NgFor, NgIf, NgStyle, NgTemplateOutlet } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
5
+ import { ScrollingModule } from '@angular/cdk/scrolling';
6
+ import { mbGridBuildFilter, mbGridDefaultState, mbGridExportCsv, mbGridFormatValue, mbGridGetValue, mbGridProcess, } from './mb-grid-data';
7
+ import { mbGridExportExcelHtml, mbGridExportJson } from './mb-grid-export';
8
+ import { MbGridCellTemplateDirective, MbGridDetailTemplateDirective, MbGridEditTemplateDirective, MbGridFooterTemplateDirective, MbGridHeaderTemplateDirective, MbGridToolbarTemplateDirective, } from './mb-grid-template.directive';
9
+ import { MB_UI_CONFIG } from '../tokens/mb-ui-config.token';
10
+ import { MB_GRID_MESSAGES } from './mb-grid-messages';
11
+ import * as i0 from "@angular/core";
12
+ import * as i1 from "./mb-grid-state.service";
13
+ import * as i2 from "@angular/forms";
14
+ import * as i3 from "@angular/cdk/drag-drop";
15
+ export class MbGridComponent {
16
+ cdr;
17
+ stateStore;
18
+ uiConfig;
19
+ messages;
20
+ data = [];
21
+ columns = [];
22
+ loading = false;
23
+ dataMode = 'client';
24
+ state = mbGridDefaultState();
25
+ total = 0;
26
+ height = null;
27
+ rowHeight = 44;
28
+ density = 'comfortable';
29
+ locale;
30
+ dir;
31
+ noRecordsText;
32
+ loadingText;
33
+ pageable = true;
34
+ pageSizeOptions = [10, 20, 50, 100];
35
+ sortable = true;
36
+ multiSort = false;
37
+ filterable = true;
38
+ filterMode = 'row';
39
+ groupable = false;
40
+ selectable = false;
41
+ selectionMode = 'multiple';
42
+ rowKey = 'id';
43
+ selectedKeys = [];
44
+ resizable = true;
45
+ reorderable = true;
46
+ columnMenu = true;
47
+ showToolbar = true;
48
+ showSearch = true;
49
+ showColumnChooser = true;
50
+ showExport = true;
51
+ showFooter = false;
52
+ virtualScroll = false;
53
+ exportFileName = 'mb-grid-export.csv';
54
+ excelFileName = 'mb-grid-export.xls';
55
+ jsonFileName = 'mb-grid-export.json';
56
+ showExcelExport = true;
57
+ showJsonExport = true;
58
+ persistKey = '';
59
+ autoPersist = false;
60
+ editable = false;
61
+ editMode = 'inline';
62
+ allowAdd = false;
63
+ allowDelete = false;
64
+ confirmDelete = false;
65
+ commandColumnTitle;
66
+ newItemFactory;
67
+ expandable = false;
68
+ detailInitiallyExpanded = false;
69
+ rowClassName;
70
+ responsiveColumns = true;
71
+ stateChange = new EventEmitter();
72
+ pageChange = new EventEmitter();
73
+ sortChange = new EventEmitter();
74
+ filterChange = new EventEmitter();
75
+ groupChange = new EventEmitter();
76
+ selectedKeysChange = new EventEmitter();
77
+ columnResize = new EventEmitter();
78
+ columnReorder = new EventEmitter();
79
+ columnVisibilityChange = new EventEmitter();
80
+ columnLockChange = new EventEmitter();
81
+ selectionChange = new EventEmitter();
82
+ edit = new EventEmitter();
83
+ save = new EventEmitter();
84
+ cancel = new EventEmitter();
85
+ remove = new EventEmitter();
86
+ detailToggle = new EventEmitter();
87
+ rowClick = new EventEmitter();
88
+ cellClick = new EventEmitter();
89
+ cellTemplates;
90
+ headerTemplates;
91
+ editTemplates;
92
+ footerTemplates;
93
+ toolbarTemplate;
94
+ detailTemplate;
95
+ processed = { data: [], total: 0, aggregates: {} };
96
+ internalColumns = [];
97
+ globalSearch = '';
98
+ filtersByField = {};
99
+ openColumnMenuField = '';
100
+ resizing;
101
+ expandedGroupKeys = new Set();
102
+ expandedDetailKeys = new Set();
103
+ editingKey = null;
104
+ editingModel = null;
105
+ originalModel = null;
106
+ editingRowIndex = -1;
107
+ editingIsNew = false;
108
+ validationErrors = {};
109
+ mediaQueryLists = new Map();
110
+ mediaListeners = new Map();
111
+ textOperators = ['contains', 'doesNotContain', 'startsWith', 'endsWith', 'eq', 'neq', 'isEmpty', 'isNotEmpty'];
112
+ numericOperators = ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'between', 'isNull', 'isNotNull'];
113
+ booleanOperators = ['eq', 'neq'];
114
+ constructor(cdr, stateStore, uiConfig, messages) {
115
+ this.cdr = cdr;
116
+ this.stateStore = stateStore;
117
+ this.uiConfig = uiConfig;
118
+ this.messages = messages;
119
+ }
120
+ get effectiveLocale() {
121
+ return this.locale ?? this.uiConfig.locale;
122
+ }
123
+ get effectiveDir() {
124
+ return this.dir ?? this.uiConfig.direction;
125
+ }
126
+ get effectiveCommandColumnTitle() {
127
+ return this.commandColumnTitle ?? this.messages.commandColumn;
128
+ }
129
+ get formatOptions() {
130
+ return { locale: this.effectiveLocale, yes: this.messages.yes, no: this.messages.no };
131
+ }
132
+ ngOnInit() {
133
+ this.syncMediaQueries();
134
+ }
135
+ ngOnDestroy() {
136
+ for (const [query, listener] of this.mediaListeners) {
137
+ this.mediaQueryLists.get(query)?.removeEventListener('change', listener);
138
+ }
139
+ this.mediaListeners.clear();
140
+ this.mediaQueryLists.clear();
141
+ }
142
+ ngOnChanges(changes) {
143
+ if (changes['columns']) {
144
+ this.internalColumns = (this.columns ?? []).map((column) => ({
145
+ sortable: true,
146
+ filterable: true,
147
+ groupable: true,
148
+ resizable: true,
149
+ reorderable: true,
150
+ menu: true,
151
+ exportable: true,
152
+ ...column,
153
+ }));
154
+ this.applyProjectedTemplates();
155
+ this.ensureFilterDefaults();
156
+ this.restorePersistedState();
157
+ this.syncMediaQueries();
158
+ }
159
+ if (changes['state'] && !this.state) {
160
+ this.state = mbGridDefaultState();
161
+ }
162
+ this.reprocess();
163
+ }
164
+ ngAfterContentInit() {
165
+ this.applyProjectedTemplates();
166
+ this.cellTemplates?.changes.subscribe(() => this.applyProjectedTemplates());
167
+ this.headerTemplates?.changes.subscribe(() => this.applyProjectedTemplates());
168
+ this.editTemplates?.changes.subscribe(() => this.applyProjectedTemplates());
169
+ this.footerTemplates?.changes.subscribe(() => this.applyProjectedTemplates());
170
+ this.reprocess();
171
+ this.cdr.markForCheck();
172
+ }
173
+ get visibleColumns() {
174
+ return this.internalColumns.filter((column) => !column.hidden && this.matchesMedia(column));
175
+ }
176
+ get lockedStartColumns() {
177
+ return this.visibleColumns.filter((column) => this.isLockedStart(column));
178
+ }
179
+ get lockedEndColumns() {
180
+ return this.visibleColumns.filter((column) => this.isLockedEnd(column));
181
+ }
182
+ get hasFilterRow() {
183
+ return this.filterable && (this.filterMode === 'row' || this.filterMode === 'both');
184
+ }
185
+ get hasColumnMenu() {
186
+ return this.columnMenu && (this.filterMode === 'menu' || this.filterMode === 'both' || this.showColumnChooser || this.groupable);
187
+ }
188
+ get pageIndex() {
189
+ return Math.floor((this.state?.skip ?? 0) / (this.state?.take || 1));
190
+ }
191
+ get pageSize() {
192
+ return this.state?.take ?? 10;
193
+ }
194
+ get effectiveTotal() {
195
+ return this.dataMode === 'server' ? this.total : this.processed.total;
196
+ }
197
+ get pageCount() {
198
+ return Math.max(1, Math.ceil(this.effectiveTotal / this.pageSize));
199
+ }
200
+ get from() {
201
+ if (!this.effectiveTotal)
202
+ return 0;
203
+ return this.pageIndex * this.pageSize + 1;
204
+ }
205
+ get to() {
206
+ return Math.min((this.pageIndex + 1) * this.pageSize, this.effectiveTotal);
207
+ }
208
+ get gridStyle() {
209
+ return { height: typeof this.height === 'number' ? `${this.height}px` : this.height };
210
+ }
211
+ get allVisibleRowsSelected() {
212
+ const dataRows = this.dataRowsFromRendered();
213
+ return dataRows.length > 0 && dataRows.every((row) => this.selectedKeys.includes(this.getRowKey(row)));
214
+ }
215
+ get someVisibleRowsSelected() {
216
+ const dataRows = this.dataRowsFromRendered();
217
+ return dataRows.some((row) => this.selectedKeys.includes(this.getRowKey(row))) && !this.allVisibleRowsSelected;
218
+ }
219
+ get toolbarContext() {
220
+ return {
221
+ state: this.state,
222
+ total: this.effectiveTotal,
223
+ selectedKeys: this.selectedKeys,
224
+ selectedRows: this.selectedRows,
225
+ add: () => this.createRow(),
226
+ exportCsv: () => this.exportCsv(),
227
+ exportExcel: () => this.exportExcel(),
228
+ reset: () => this.resetState(),
229
+ };
230
+ }
231
+ get selectedRows() {
232
+ const allRows = this.data ?? [];
233
+ return allRows.filter((row) => this.selectedKeys.includes(this.getRowKey(row)));
234
+ }
235
+ get columnSpan() {
236
+ return this.visibleColumns.length + (this.selectable ? 1 : 0) + (this.expandable ? 1 : 0) + (this.showCommandColumn ? 1 : 0);
237
+ }
238
+ get showCommandColumn() {
239
+ return this.editable || this.allowDelete;
240
+ }
241
+ getOperatorLabel(operator) {
242
+ return this.messages.operatorLabels[operator] ?? operator;
243
+ }
244
+ getOperators(column) {
245
+ if (column.type === 'number' || column.type === 'date')
246
+ return this.numericOperators;
247
+ if (column.type === 'boolean')
248
+ return this.booleanOperators;
249
+ return this.textOperators;
250
+ }
251
+ getColumnStyle(column) {
252
+ const lockedStart = this.isLockedStart(column);
253
+ const lockedEnd = this.isLockedEnd(column);
254
+ return {
255
+ width: this.toCssSize(column.width),
256
+ minWidth: this.toCssSize(column.minWidth),
257
+ maxWidth: this.toCssSize(column.maxWidth),
258
+ position: lockedStart || lockedEnd ? 'sticky' : null,
259
+ insetInlineStart: lockedStart ? `${this.getLockedOffset(column, 'start')}px` : null,
260
+ insetInlineEnd: lockedEnd ? `${this.getLockedOffset(column, 'end')}px` : null,
261
+ zIndex: lockedStart || lockedEnd ? '6' : null,
262
+ };
263
+ }
264
+ getColumnClass(column) {
265
+ return {
266
+ 'mb-grid__cell--locked-start': this.isLockedStart(column),
267
+ 'mb-grid__cell--locked-end': this.isLockedEnd(column),
268
+ };
269
+ }
270
+ isLockedStart(column) {
271
+ return !!column.locked || column.sticky === 'start';
272
+ }
273
+ isLockedEnd(column) {
274
+ return column.sticky === 'end';
275
+ }
276
+ matchesMedia(column) {
277
+ if (!this.responsiveColumns || !column.media || typeof window === 'undefined') {
278
+ return true;
279
+ }
280
+ return this.mediaQueryLists.get(column.media)?.matches ?? true;
281
+ }
282
+ pagerInfoText() {
283
+ return this.messages.pagerInfo(this.from, this.to, this.effectiveTotal);
284
+ }
285
+ getSortIndex(column) {
286
+ return (this.state.sort ?? []).findIndex((item) => String(item.field) === String(column.field));
287
+ }
288
+ getSortDirection(column) {
289
+ return this.state.sort?.find((item) => String(item.field) === String(column.field))?.dir ?? '';
290
+ }
291
+ getValue(row, column, rowIndex = -1) {
292
+ return column.valueGetter ? column.valueGetter(row, rowIndex) : mbGridGetValue(row, column.field);
293
+ }
294
+ formatCell(row, column, rowIndex) {
295
+ return mbGridFormatValue(row, column, rowIndex, this.formatOptions);
296
+ }
297
+ getCellClass(row, column, rowIndex) {
298
+ if (!column.className)
299
+ return null;
300
+ if (typeof column.className === 'function') {
301
+ return column.className(row, this.getValue(row, column, rowIndex), rowIndex);
302
+ }
303
+ return column.className;
304
+ }
305
+ getCellTemplate(column) {
306
+ return column.cellTemplate ?? null;
307
+ }
308
+ getHeaderTemplate(column) {
309
+ return column.headerTemplate ?? null;
310
+ }
311
+ getFooterTemplate(column) {
312
+ return column.footerTemplate ?? null;
313
+ }
314
+ getRowKey(row) {
315
+ if (typeof this.rowKey === 'function')
316
+ return this.rowKey(row);
317
+ return mbGridGetValue(row, this.rowKey);
318
+ }
319
+ toggleSort(column, event) {
320
+ if (!this.sortable || column.sortable === false)
321
+ return;
322
+ const field = String(column.field);
323
+ const current = [...(this.state.sort ?? [])];
324
+ const index = current.findIndex((item) => String(item.field) === field);
325
+ const isMulti = this.multiSort && !!event?.shiftKey;
326
+ const base = isMulti ? current : index >= 0 ? [current[index]] : [];
327
+ const targetIndex = base.findIndex((item) => String(item.field) === field);
328
+ if (targetIndex < 0) {
329
+ base.push({ field: column.field, dir: 'asc' });
330
+ }
331
+ else if (base[targetIndex].dir === 'asc') {
332
+ base[targetIndex] = { ...base[targetIndex], dir: 'desc' };
333
+ }
334
+ else {
335
+ base.splice(targetIndex, 1);
336
+ }
337
+ this.setState({ ...this.state, sort: base, skip: 0 });
338
+ this.sortChange.emit({ sort: base });
339
+ }
340
+ setFilterValue(column, value) {
341
+ const field = String(column.field);
342
+ const current = this.filtersByField[field] ?? { operator: this.defaultOperator(column), value: '' };
343
+ this.filtersByField = { ...this.filtersByField, [field]: { ...current, value } };
344
+ this.applyFilters();
345
+ }
346
+ setFilterOperator(column, operator) {
347
+ const field = String(column.field);
348
+ const current = this.filtersByField[field] ?? { operator, value: '' };
349
+ this.filtersByField = { ...this.filtersByField, [field]: { ...current, operator } };
350
+ this.applyFilters();
351
+ }
352
+ clearFilter(column) {
353
+ if (!column) {
354
+ this.filtersByField = {};
355
+ }
356
+ else {
357
+ const clone = { ...this.filtersByField };
358
+ delete clone[String(column.field)];
359
+ this.filtersByField = clone;
360
+ }
361
+ this.applyFilters();
362
+ }
363
+ applyGlobalSearch(value) {
364
+ this.globalSearch = value;
365
+ const filters = this.visibleColumns
366
+ .filter((column) => column.filterable !== false && column.type !== 'custom')
367
+ .map((column) => ({ field: column.field, operator: 'contains', value, ignoreCase: true }));
368
+ const columnFilter = mbGridBuildFilter(this.filtersByField);
369
+ const globalFilter = value?.trim()
370
+ ? { logic: 'or', filters }
371
+ : undefined;
372
+ const filter = columnFilter && globalFilter
373
+ ? { logic: 'and', filters: [columnFilter, globalFilter] }
374
+ : columnFilter ?? globalFilter;
375
+ this.setState({ ...this.state, filter, skip: 0 });
376
+ this.filterChange.emit({ filter });
377
+ }
378
+ changePage(pageIndex) {
379
+ const nextPage = Math.min(Math.max(pageIndex, 0), this.pageCount - 1);
380
+ const state = { ...this.state, skip: nextPage * this.pageSize };
381
+ this.setState(state);
382
+ this.pageChange.emit({ pageIndex: nextPage, pageSize: this.pageSize, skip: state.skip, take: state.take });
383
+ }
384
+ changePageSize(value) {
385
+ const take = Number(value);
386
+ const state = { ...this.state, skip: 0, take };
387
+ this.setState(state);
388
+ this.pageChange.emit({ pageIndex: 0, pageSize: take, skip: 0, take });
389
+ }
390
+ toggleRow(row, event) {
391
+ event?.stopPropagation();
392
+ const key = this.getRowKey(row);
393
+ const exists = this.selectedKeys.includes(key);
394
+ const next = this.selectionMode === 'single'
395
+ ? exists ? [] : [key]
396
+ : exists ? this.selectedKeys.filter((item) => item !== key) : [...this.selectedKeys, key];
397
+ this.selectedKeys = next;
398
+ this.selectedKeysChange.emit(next);
399
+ this.selectionChange.emit({ selectedKeys: next, selectedRows: this.selectedRows });
400
+ }
401
+ toggleAllVisible(event) {
402
+ event?.stopPropagation();
403
+ const visible = this.dataRowsFromRendered().map((row) => this.getRowKey(row));
404
+ const allSelected = visible.every((key) => this.selectedKeys.includes(key));
405
+ this.selectedKeys = allSelected
406
+ ? this.selectedKeys.filter((key) => !visible.includes(key))
407
+ : Array.from(new Set([...this.selectedKeys, ...visible]));
408
+ this.selectedKeysChange.emit(this.selectedKeys);
409
+ this.selectionChange.emit({ selectedKeys: this.selectedKeys, selectedRows: this.selectedRows });
410
+ }
411
+ isSelected(row) {
412
+ return this.selectedKeys.includes(this.getRowKey(row));
413
+ }
414
+ onRowClick(row, rowIndex) {
415
+ this.rowClick.emit({ row, rowIndex });
416
+ }
417
+ onCellClick(row, column, rowIndex) {
418
+ this.cellClick.emit({ row, column, value: this.getValue(row, column, rowIndex), rowIndex });
419
+ }
420
+ toggleColumnMenu(column, event) {
421
+ event.stopPropagation();
422
+ const field = String(column.field);
423
+ this.openColumnMenuField = this.openColumnMenuField === field ? '' : field;
424
+ }
425
+ hideColumn(column) {
426
+ column.hidden = true;
427
+ this.openColumnMenuField = '';
428
+ this.columnVisibilityChange.emit({ column, field: column.field, visible: false, columns: this.internalColumns });
429
+ this.persistState();
430
+ this.cdr.markForCheck();
431
+ }
432
+ showColumn(column, visible) {
433
+ column.hidden = !visible;
434
+ this.columnVisibilityChange.emit({ column, field: column.field, visible, columns: this.internalColumns });
435
+ this.persistState();
436
+ this.cdr.markForCheck();
437
+ }
438
+ toggleLock(column) {
439
+ column.locked = !column.locked;
440
+ column.sticky = column.locked ? 'start' : false;
441
+ this.columnLockChange.emit({ column, field: column.field, locked: !!column.locked, columns: this.internalColumns });
442
+ this.persistState();
443
+ this.cdr.markForCheck();
444
+ }
445
+ resetColumns() {
446
+ this.internalColumns = (this.columns ?? []).map((column) => ({ ...column }));
447
+ this.applyProjectedTemplates();
448
+ this.cdr.markForCheck();
449
+ }
450
+ toggleGroup(column) {
451
+ if (!this.groupable || column.groupable === false)
452
+ return;
453
+ const field = String(column.field);
454
+ const exists = this.state.group?.some((group) => String(group.field) === field);
455
+ const group = exists
456
+ ? this.state.group.filter((item) => String(item.field) !== field)
457
+ : [...(this.state.group ?? []), { field: column.field, dir: 'asc' }];
458
+ this.setState({ ...this.state, group, skip: 0 });
459
+ this.groupChange.emit({ group });
460
+ this.openColumnMenuField = '';
461
+ }
462
+ removeGroup(group) {
463
+ const next = this.state.group.filter((item) => String(item.field) !== String(group.field));
464
+ this.setState({ ...this.state, group: next, skip: 0 });
465
+ this.groupChange.emit({ group: next });
466
+ }
467
+ toggleGroupRow(row) {
468
+ if (row.kind !== 'group')
469
+ return;
470
+ if (this.expandedGroupKeys.has(row.key))
471
+ this.expandedGroupKeys.delete(row.key);
472
+ else
473
+ this.expandedGroupKeys.add(row.key);
474
+ this.reprocess();
475
+ }
476
+ startResize(column, event) {
477
+ if (!this.resizable || column.resizable === false)
478
+ return;
479
+ event.preventDefault();
480
+ event.stopPropagation();
481
+ const header = event.target.closest('th');
482
+ this.resizing = { field: String(column.field), startX: event.clientX, startWidth: header?.offsetWidth ?? 120 };
483
+ const move = (moveEvent) => this.resizeColumn(moveEvent);
484
+ const up = () => {
485
+ document.removeEventListener('mousemove', move);
486
+ document.removeEventListener('mouseup', up);
487
+ this.resizing = undefined;
488
+ };
489
+ document.addEventListener('mousemove', move);
490
+ document.addEventListener('mouseup', up);
491
+ }
492
+ dropColumn(event) {
493
+ if (!this.reorderable || event.previousIndex === event.currentIndex)
494
+ return;
495
+ moveItemInArray(this.internalColumns, event.previousIndex, event.currentIndex);
496
+ this.columnReorder.emit({ previousIndex: event.previousIndex, currentIndex: event.currentIndex, columns: this.internalColumns });
497
+ this.persistState();
498
+ this.cdr.markForCheck();
499
+ }
500
+ exportCsv() {
501
+ const rows = this.exportRows();
502
+ mbGridExportCsv(rows, this.visibleColumns, this.exportFileName, this.formatOptions);
503
+ }
504
+ exportExcel() {
505
+ mbGridExportExcelHtml(this.exportRows(), this.visibleColumns, this.excelFileName, this.formatOptions, this.effectiveDir);
506
+ }
507
+ exportJson() {
508
+ mbGridExportJson(this.exportRows(), this.visibleColumns, this.jsonFileName);
509
+ }
510
+ resetState() {
511
+ this.globalSearch = '';
512
+ this.filtersByField = {};
513
+ this.expandedGroupKeys.clear();
514
+ this.expandedDetailKeys.clear();
515
+ this.cancelEditInternal(false);
516
+ this.setState(mbGridDefaultState(this.pageSize));
517
+ }
518
+ createRow() {
519
+ if (!this.editable || !this.allowAdd)
520
+ return;
521
+ const row = this.newItemFactory ? this.newItemFactory() : {};
522
+ const key = `__new_${Date.now()}`;
523
+ this.editingKey = key;
524
+ this.editingModel = this.cloneRow(row);
525
+ this.originalModel = null;
526
+ this.editingRowIndex = 0;
527
+ this.editingIsNew = true;
528
+ this.validationErrors = {};
529
+ this.cdr.markForCheck();
530
+ }
531
+ startEdit(row, rowIndex, event) {
532
+ event?.stopPropagation();
533
+ if (!this.editable || this.editMode === 'none')
534
+ return;
535
+ const key = this.getRowKey(row);
536
+ this.editingKey = key;
537
+ this.editingModel = this.cloneRow(row);
538
+ this.originalModel = this.cloneRow(row);
539
+ this.editingRowIndex = rowIndex;
540
+ this.editingIsNew = false;
541
+ this.validationErrors = {};
542
+ this.edit.emit({ row, rowIndex, key });
543
+ this.cdr.markForCheck();
544
+ }
545
+ saveEdit(event) {
546
+ event?.stopPropagation();
547
+ if (!this.editingModel || this.editingKey === null)
548
+ return;
549
+ if (!this.validateEditingModel()) {
550
+ this.cdr.markForCheck();
551
+ return;
552
+ }
553
+ const row = this.cloneRow(this.editingModel);
554
+ const key = this.editingKey;
555
+ this.save.emit({ row, originalRow: this.originalModel, rowIndex: this.editingRowIndex, key, isNew: this.editingIsNew });
556
+ this.cancelEditInternal(false);
557
+ this.cdr.markForCheck();
558
+ }
559
+ cancelEditRow(event) {
560
+ event?.stopPropagation();
561
+ if (!this.editingModel || this.editingKey === null)
562
+ return;
563
+ this.cancel.emit({ row: this.editingModel, originalRow: this.originalModel, rowIndex: this.editingRowIndex, key: this.editingKey, isNew: this.editingIsNew });
564
+ this.cancelEditInternal(true);
565
+ }
566
+ removeRow(row, rowIndex, event) {
567
+ event?.stopPropagation();
568
+ if (this.confirmDelete && !confirm(this.messages.deleteConfirm))
569
+ return;
570
+ this.remove.emit({ row, rowIndex, key: this.getRowKey(row) });
571
+ }
572
+ isEditing(row) {
573
+ return this.editingKey !== null && this.getRowKey(row) === this.editingKey;
574
+ }
575
+ isNewRowEditing() {
576
+ return this.editingIsNew && !!this.editingModel;
577
+ }
578
+ setEditValue(column, value) {
579
+ if (!this.editingModel)
580
+ return;
581
+ if (column.valueSetter) {
582
+ this.editingModel = column.valueSetter(this.editingModel, value, this.editingRowIndex);
583
+ }
584
+ else {
585
+ this.setNestedValue(this.editingModel, String(column.field), value);
586
+ }
587
+ delete this.validationErrors[String(column.field)];
588
+ this.cdr.markForCheck();
589
+ }
590
+ getEditValue(column) {
591
+ return this.editingModel ? this.getValue(this.editingModel, column, this.editingRowIndex) : undefined;
592
+ }
593
+ canEditColumn(column) {
594
+ return this.editable && column.editable !== false && column.type !== 'custom';
595
+ }
596
+ getEditorType(column) {
597
+ if (column.editor)
598
+ return column.editor;
599
+ if (column.type === 'number')
600
+ return 'number';
601
+ if (column.type === 'date')
602
+ return 'date';
603
+ if (column.type === 'boolean')
604
+ return 'checkbox';
605
+ if (column.type === 'enum')
606
+ return 'select';
607
+ return 'text';
608
+ }
609
+ toggleDetail(row, rowIndex, event) {
610
+ event?.stopPropagation();
611
+ const key = this.getRowKey(row);
612
+ const expanded = !this.expandedDetailKeys.has(key);
613
+ if (expanded)
614
+ this.expandedDetailKeys.add(key);
615
+ else
616
+ this.expandedDetailKeys.delete(key);
617
+ this.detailToggle.emit({ row, rowIndex, key, expanded });
618
+ this.cdr.markForCheck();
619
+ }
620
+ isDetailExpanded(row) {
621
+ const key = this.getRowKey(row);
622
+ return this.detailInitiallyExpanded || this.expandedDetailKeys.has(key);
623
+ }
624
+ getRowClass(row, rowIndex) {
625
+ if (!this.rowClassName)
626
+ return null;
627
+ return typeof this.rowClassName === 'function' ? this.rowClassName(row, rowIndex) : this.rowClassName;
628
+ }
629
+ trackColumn(_, column) {
630
+ return String(column.field);
631
+ }
632
+ trackRow(_, row) {
633
+ return row.kind === 'group' ? row.key : this.getRowKey(row.dataItem);
634
+ }
635
+ toCssSize(value) {
636
+ if (value === undefined || value === null || value === '')
637
+ return null;
638
+ return typeof value === 'number' ? `${value}px` : value;
639
+ }
640
+ getLockedOffset(column, side) {
641
+ const columns = side === 'start' ? this.lockedStartColumns : this.lockedEndColumns;
642
+ let offset = 0;
643
+ for (const item of columns) {
644
+ if (String(item.field) === String(column.field))
645
+ break;
646
+ offset += this.resolveColumnWidth(item);
647
+ }
648
+ return offset;
649
+ }
650
+ resolveColumnWidth(column) {
651
+ if (typeof column.width === 'number')
652
+ return column.width;
653
+ if (typeof column.width === 'string' && column.width.endsWith('px')) {
654
+ return Number.parseFloat(column.width);
655
+ }
656
+ if (typeof column.minWidth === 'number')
657
+ return column.minWidth;
658
+ return 120;
659
+ }
660
+ syncMediaQueries() {
661
+ if (!this.responsiveColumns || typeof window === 'undefined')
662
+ return;
663
+ const queries = new Set(this.internalColumns
664
+ .map((column) => column.media)
665
+ .filter((media) => !!media));
666
+ for (const query of queries) {
667
+ if (this.mediaQueryLists.has(query))
668
+ continue;
669
+ const mediaQueryList = window.matchMedia(query);
670
+ const listener = () => {
671
+ this.cdr.markForCheck();
672
+ };
673
+ mediaQueryList.addEventListener('change', listener);
674
+ this.mediaQueryLists.set(query, mediaQueryList);
675
+ this.mediaListeners.set(query, listener);
676
+ }
677
+ }
678
+ setState(state) {
679
+ this.state = { ...state, sort: state.sort ?? [], group: state.group ?? [] };
680
+ this.stateChange.emit(this.state);
681
+ this.persistState();
682
+ this.reprocess();
683
+ }
684
+ reprocess() {
685
+ const safeState = this.state ?? mbGridDefaultState();
686
+ if (this.dataMode === 'server') {
687
+ this.processed = {
688
+ data: (this.data ?? []).map((dataItem, rowIndex) => ({ kind: 'data', dataItem, rowIndex: safeState.skip + rowIndex })),
689
+ total: this.total,
690
+ aggregates: {},
691
+ };
692
+ }
693
+ else {
694
+ this.processed = mbGridProcess(this.data ?? [], safeState, this.internalColumns, this.expandedGroupKeys);
695
+ }
696
+ this.cdr.markForCheck();
697
+ }
698
+ applyFilters() {
699
+ const columnFilter = mbGridBuildFilter(this.filtersByField);
700
+ if (this.globalSearch) {
701
+ this.applyGlobalSearch(this.globalSearch);
702
+ return;
703
+ }
704
+ this.setState({ ...this.state, filter: columnFilter, skip: 0 });
705
+ this.filterChange.emit({ filter: columnFilter });
706
+ }
707
+ defaultOperator(column) {
708
+ if (column.type === 'number' || column.type === 'date' || column.type === 'boolean')
709
+ return 'eq';
710
+ return 'contains';
711
+ }
712
+ ensureFilterDefaults() {
713
+ const next = { ...this.filtersByField };
714
+ for (const column of this.internalColumns) {
715
+ const field = String(column.field);
716
+ next[field] ??= { operator: this.defaultOperator(column), value: '' };
717
+ }
718
+ this.filtersByField = next;
719
+ }
720
+ applyProjectedTemplates() {
721
+ for (const column of this.internalColumns) {
722
+ const field = String(column.field);
723
+ const cell = this.cellTemplates?.find((item) => item.field === field);
724
+ const header = this.headerTemplates?.find((item) => item.field === field);
725
+ const footer = this.footerTemplates?.find((item) => item.field === field);
726
+ const edit = this.editTemplates?.find((item) => item.field === field);
727
+ if (cell)
728
+ column.cellTemplate = cell.templateRef;
729
+ if (header)
730
+ column.headerTemplate = header.templateRef;
731
+ if (footer)
732
+ column.footerTemplate = footer.templateRef;
733
+ if (edit)
734
+ column.editTemplate = edit.templateRef;
735
+ }
736
+ }
737
+ resizeColumn(event) {
738
+ if (!this.resizing)
739
+ return;
740
+ const delta = this.effectiveDir === 'rtl' ? this.resizing.startX - event.clientX : event.clientX - this.resizing.startX;
741
+ const width = Math.max(56, this.resizing.startWidth + delta);
742
+ const column = this.internalColumns.find((item) => String(item.field) === this.resizing?.field);
743
+ if (!column)
744
+ return;
745
+ column.width = width;
746
+ this.columnResize.emit({ column, field: column.field, width });
747
+ this.cdr.markForCheck();
748
+ }
749
+ exportRows() {
750
+ if (this.dataMode === 'server')
751
+ return this.data ?? [];
752
+ const safeState = { ...this.state, skip: 0, take: Number.MAX_SAFE_INTEGER };
753
+ return mbGridProcess(this.data ?? [], safeState, this.internalColumns, this.expandedGroupKeys)
754
+ .data
755
+ .filter((row) => row.kind === 'data')
756
+ .map((row) => row.dataItem);
757
+ }
758
+ validateEditingModel() {
759
+ if (!this.editingModel)
760
+ return true;
761
+ const errors = {};
762
+ for (const column of this.visibleColumns) {
763
+ if (!this.canEditColumn(column))
764
+ continue;
765
+ const value = this.getValue(this.editingModel, column, this.editingRowIndex);
766
+ const field = String(column.field);
767
+ if (column.required && (value === null || value === undefined || String(value).trim() === '')) {
768
+ errors[field] = this.messages.fieldRequired(column.title);
769
+ continue;
770
+ }
771
+ const custom = column.validator?.(value, this.editingModel, column);
772
+ if (custom)
773
+ errors[field] = custom;
774
+ }
775
+ this.validationErrors = errors;
776
+ return Object.keys(errors).length === 0;
777
+ }
778
+ cloneRow(row) {
779
+ if (typeof structuredClone === 'function')
780
+ return structuredClone(row);
781
+ return JSON.parse(JSON.stringify(row));
782
+ }
783
+ setNestedValue(row, path, value) {
784
+ const parts = path.split('.');
785
+ let cursor = row;
786
+ for (let index = 0; index < parts.length - 1; index++) {
787
+ const part = parts[index];
788
+ cursor[part] ??= {};
789
+ cursor = cursor[part];
790
+ }
791
+ cursor[parts[parts.length - 1]] = value;
792
+ }
793
+ cancelEditInternal(mark = true) {
794
+ this.editingKey = null;
795
+ this.editingModel = null;
796
+ this.originalModel = null;
797
+ this.editingRowIndex = -1;
798
+ this.editingIsNew = false;
799
+ this.validationErrors = {};
800
+ if (mark)
801
+ this.cdr.markForCheck();
802
+ }
803
+ restorePersistedState() {
804
+ if (!this.persistKey)
805
+ return;
806
+ const saved = this.stateStore.load(this.persistKey);
807
+ if (!saved)
808
+ return;
809
+ this.state = saved.state ?? this.state;
810
+ this.selectedKeys = saved.selectedKeys ?? this.selectedKeys;
811
+ for (const savedColumn of saved.columns ?? []) {
812
+ const target = this.internalColumns.find((column) => String(column.field) === String(savedColumn.field));
813
+ if (!target)
814
+ continue;
815
+ target.width = savedColumn.width ?? target.width;
816
+ target.hidden = savedColumn.hidden ?? target.hidden;
817
+ target.locked = savedColumn.locked ?? target.locked;
818
+ target.sticky = savedColumn.sticky ?? target.sticky;
819
+ }
820
+ }
821
+ persistState() {
822
+ if (!this.autoPersist || !this.persistKey)
823
+ return;
824
+ this.stateStore.save(this.persistKey, this.state, this.internalColumns, this.selectedKeys);
825
+ }
826
+ dataRowsFromRendered() {
827
+ return this.processed.data.filter((row) => row.kind === 'data').map((row) => row.dataItem);
828
+ }
829
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MbGridComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.MbGridStateService }, { token: MB_UI_CONFIG }, { token: MB_GRID_MESSAGES }], target: i0.ɵɵFactoryTarget.Component });
830
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MbGridComponent, isStandalone: true, selector: "mb-grid", inputs: { data: "data", columns: "columns", loading: "loading", dataMode: "dataMode", state: "state", total: "total", height: "height", rowHeight: "rowHeight", density: "density", locale: "locale", dir: "dir", noRecordsText: "noRecordsText", loadingText: "loadingText", pageable: "pageable", pageSizeOptions: "pageSizeOptions", sortable: "sortable", multiSort: "multiSort", filterable: "filterable", filterMode: "filterMode", groupable: "groupable", selectable: "selectable", selectionMode: "selectionMode", rowKey: "rowKey", selectedKeys: "selectedKeys", resizable: "resizable", reorderable: "reorderable", columnMenu: "columnMenu", showToolbar: "showToolbar", showSearch: "showSearch", showColumnChooser: "showColumnChooser", showExport: "showExport", showFooter: "showFooter", virtualScroll: "virtualScroll", exportFileName: "exportFileName", excelFileName: "excelFileName", jsonFileName: "jsonFileName", showExcelExport: "showExcelExport", showJsonExport: "showJsonExport", persistKey: "persistKey", autoPersist: "autoPersist", editable: "editable", editMode: "editMode", allowAdd: "allowAdd", allowDelete: "allowDelete", confirmDelete: "confirmDelete", commandColumnTitle: "commandColumnTitle", newItemFactory: "newItemFactory", expandable: "expandable", detailInitiallyExpanded: "detailInitiallyExpanded", rowClassName: "rowClassName", responsiveColumns: "responsiveColumns" }, outputs: { stateChange: "stateChange", pageChange: "pageChange", sortChange: "sortChange", filterChange: "filterChange", groupChange: "groupChange", selectedKeysChange: "selectedKeysChange", columnResize: "columnResize", columnReorder: "columnReorder", columnVisibilityChange: "columnVisibilityChange", columnLockChange: "columnLockChange", selectionChange: "selectionChange", edit: "edit", save: "save", cancel: "cancel", remove: "remove", detailToggle: "detailToggle", rowClick: "rowClick", cellClick: "cellClick" }, queries: [{ propertyName: "toolbarTemplate", first: true, predicate: MbGridToolbarTemplateDirective, descendants: true }, { propertyName: "detailTemplate", first: true, predicate: MbGridDetailTemplateDirective, descendants: true }, { propertyName: "cellTemplates", predicate: MbGridCellTemplateDirective }, { propertyName: "headerTemplates", predicate: MbGridHeaderTemplateDirective }, { propertyName: "editTemplates", predicate: MbGridEditTemplateDirective }, { propertyName: "footerTemplates", predicate: MbGridFooterTemplateDirective }], usesOnChanges: true, ngImport: i0, template: "<div class=\"mb-grid\" [attr.dir]=\"effectiveDir\" [ngClass]=\"['mb-grid--' + density, loading ? 'mb-grid--loading' : '']\" [ngStyle]=\"gridStyle\">\n <div *ngIf=\"showToolbar\" class=\"mb-grid__toolbar\">\n <ng-container *ngIf=\"toolbarTemplate?.templateRef as toolbarTpl; else defaultToolbar\">\n <ng-container [ngTemplateOutlet]=\"toolbarTpl\" [ngTemplateOutletContext]=\"toolbarContext\"></ng-container>\n </ng-container>\n\n <ng-template #defaultToolbar>\n <div class=\"mb-grid__toolbar-start\">\n <div *ngIf=\"groupable\" class=\"mb-grid__group-panel\">\n <span class=\"mb-grid__group-label\">{{ messages.groupLabel }}</span>\n <button\n *ngFor=\"let group of state.group\"\n type=\"button\"\n class=\"mb-grid__group-chip\"\n (click)=\"removeGroup(group)\">\n {{ group.field }} \u00D7\n </button>\n <span *ngIf=\"!state.group.length\" class=\"mb-grid__group-hint\">{{ messages.groupHint }}</span>\n </div>\n </div>\n\n <div class=\"mb-grid__toolbar-end\">\n <button *ngIf=\"editable && allowAdd\" type=\"button\" class=\"mb-grid__tool-button mb-grid__tool-button--primary\" (click)=\"createRow()\">{{ messages.addRow }}</button>\n <input\n *ngIf=\"showSearch\"\n class=\"mb-grid__search\"\n [ngModel]=\"globalSearch\"\n (ngModelChange)=\"applyGlobalSearch($event)\"\n [placeholder]=\"messages.searchPlaceholder\" />\n\n <div *ngIf=\"showColumnChooser\" class=\"mb-grid__chooser\">\n <button type=\"button\" class=\"mb-grid__tool-button\" (click)=\"openColumnMenuField = openColumnMenuField === '__chooser' ? '' : '__chooser'\">\n {{ messages.columns }}\n </button>\n <div *ngIf=\"openColumnMenuField === '__chooser'\" class=\"mb-grid__chooser-menu\" (click)=\"$event.stopPropagation()\">\n <label *ngFor=\"let column of internalColumns\" class=\"mb-grid__chooser-option\">\n <input type=\"checkbox\" [checked]=\"!column.hidden\" (change)=\"showColumn(column, $any($event.target).checked)\" />\n <span>{{ column.title }}</span>\n </label>\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"resetColumns()\">{{ messages.resetColumns }}</button>\n </div>\n </div>\n\n <button *ngIf=\"showExport\" type=\"button\" class=\"mb-grid__tool-button\" (click)=\"exportCsv()\">{{ messages.exportCsv }}</button>\n <button *ngIf=\"showExport && showExcelExport\" type=\"button\" class=\"mb-grid__tool-button\" (click)=\"exportExcel()\">{{ messages.exportExcel }}</button>\n <button *ngIf=\"showExport && showJsonExport\" type=\"button\" class=\"mb-grid__tool-button\" (click)=\"exportJson()\">{{ messages.exportJson }}</button>\n <button type=\"button\" class=\"mb-grid__tool-button\" (click)=\"resetState()\">{{ messages.reset }}</button>\n </div>\n </ng-template>\n </div>\n\n <div *ngIf=\"loading\" class=\"mb-grid__loading\" aria-live=\"polite\">\n <span class=\"mb-grid__spinner\"></span>\n <span>{{ loadingText || messages.loading }}</span>\n </div>\n\n <div class=\"mb-grid__scroll\">\n <table class=\"mb-grid__table\">\n <thead>\n <tr\n class=\"mb-grid__header-row\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListDisabled]=\"!reorderable\"\n [cdkDropListData]=\"visibleColumns\"\n (cdkDropListDropped)=\"dropColumn($event)\">\n <th *ngIf=\"expandable\" class=\"mb-grid__select-cell mb-grid__header-cell\"></th>\n <th *ngIf=\"selectable\" class=\"mb-grid__select-cell mb-grid__header-cell\">\n <input\n type=\"checkbox\"\n [checked]=\"allVisibleRowsSelected\"\n [indeterminate]=\"someVisibleRowsSelected\"\n (change)=\"toggleAllVisible($event)\"\n [attr.aria-label]=\"messages.selectAllRows\" />\n </th>\n\n <th\n *ngFor=\"let column of visibleColumns; let columnIndex = index; trackBy: trackColumn\"\n cdkDrag\n class=\"mb-grid__header-cell\"\n [ngClass]=\"['mb-grid__cell--' + (column.headerAlign || column.align || 'start'), column.sortable === false ? '' : 'mb-grid__header-cell--sortable', getColumnClass(column)]\"\n [ngStyle]=\"getColumnStyle(column)\">\n <div class=\"mb-grid__header-content\" (click)=\"toggleSort(column, $event)\">\n <ng-container *ngIf=\"getHeaderTemplate(column) as headerTpl; else defaultHeader\">\n <ng-container [ngTemplateOutlet]=\"headerTpl\" [ngTemplateOutletContext]=\"{ $implicit: column, column: column }\"></ng-container>\n </ng-container>\n <ng-template #defaultHeader>\n <span class=\"mb-grid__header-title\">{{ column.title }}</span>\n </ng-template>\n\n <span *ngIf=\"getSortDirection(column) as dir\" class=\"mb-grid__sort\">\n <span>{{ dir === 'asc' ? '\u2191' : '\u2193' }}</span>\n <small *ngIf=\"multiSort && getSortIndex(column) >= 0\">{{ getSortIndex(column) + 1 }}</small>\n </span>\n </div>\n\n <button\n *ngIf=\"hasColumnMenu && column.menu !== false\"\n type=\"button\"\n class=\"mb-grid__column-menu-button\"\n [attr.aria-label]=\"messages.columnMenu\"\n (click)=\"toggleColumnMenu(column, $event)\">\u22EE</button>\n\n <span\n *ngIf=\"resizable && column.resizable !== false\"\n class=\"mb-grid__resize-handle\"\n (mousedown)=\"startResize(column, $event)\"></span>\n\n <div *ngIf=\"openColumnMenuField === column.field.toString()\" class=\"mb-grid__column-menu\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"toggleSort(column)\">{{ messages.sort }}</button>\n <button *ngIf=\"groupable && column.groupable !== false\" type=\"button\" class=\"mb-grid__menu-action\" (click)=\"toggleGroup(column)\">\n {{ state.group.length && state.group[0].field === column.field ? messages.removeGroup : messages.groupByColumn }}\n </button>\n\n <div *ngIf=\"filterable && column.filterable !== false && (filterMode === 'menu' || filterMode === 'both')\" class=\"mb-grid__menu-filter\">\n <label>{{ messages.filter }}</label>\n <select [ngModel]=\"filtersByField[column.field.toString()].operator\" (ngModelChange)=\"setFilterOperator(column, $event)\">\n <option *ngFor=\"let operator of getOperators(column)\" [ngValue]=\"operator\">{{ getOperatorLabel(operator) }}</option>\n </select>\n <input\n [type]=\"column.type === 'number' ? 'number' : column.type === 'date' ? 'date' : 'text'\"\n [ngModel]=\"filtersByField[column.field.toString()].value\"\n (ngModelChange)=\"setFilterValue(column, $event)\"\n [placeholder]=\"messages.filterValuePlaceholder\" />\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"clearFilter(column)\">{{ messages.clearFilter }}</button>\n </div>\n\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"toggleLock(column)\">{{ column.locked ? messages.unlockColumn : messages.lockColumn }}</button>\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"hideColumn(column)\">{{ messages.hideColumn }}</button>\n </div>\n </th>\n\n <th *ngIf=\"showCommandColumn\" class=\"mb-grid__header-cell mb-grid__command-cell\">{{ effectiveCommandColumnTitle }}</th>\n </tr>\n\n <tr *ngIf=\"hasFilterRow\" class=\"mb-grid__filter-row\">\n <th *ngIf=\"expandable\" class=\"mb-grid__select-cell\"></th>\n <th *ngIf=\"selectable\" class=\"mb-grid__select-cell\"></th>\n <th *ngFor=\"let column of visibleColumns; trackBy: trackColumn\" class=\"mb-grid__filter-cell\" [ngClass]=\"getColumnClass(column)\" [ngStyle]=\"getColumnStyle(column)\">\n <div *ngIf=\"column.filterable !== false\" class=\"mb-grid__filter-control\">\n <select\n class=\"mb-grid__filter-operator\"\n [ngModel]=\"filtersByField[column.field.toString()].operator\"\n (ngModelChange)=\"setFilterOperator(column, $event)\">\n <option *ngFor=\"let operator of getOperators(column)\" [ngValue]=\"operator\">{{ getOperatorLabel(operator) }}</option>\n </select>\n <input\n class=\"mb-grid__filter-input\"\n [type]=\"column.type === 'number' ? 'number' : column.type === 'date' ? 'date' : 'text'\"\n [placeholder]=\"column.title\"\n [ngModel]=\"filtersByField[column.field.toString()].value\"\n (ngModelChange)=\"setFilterValue(column, $event)\" />\n </div>\n </th>\n <th *ngIf=\"showCommandColumn\" class=\"mb-grid__command-cell\"></th>\n </tr>\n </thead>\n\n <tbody>\n <tr *ngIf=\"!processed.data.length && !loading\" class=\"mb-grid__empty-row\">\n <td class=\"mb-grid__empty\" [attr.colspan]=\"columnSpan\">{{ noRecordsText || messages.noRecords }}</td>\n </tr>\n\n <tr *ngIf=\"isNewRowEditing() && editingModel\" class=\"mb-grid__row mb-grid__row--editing mb-grid__row--new\">\n <td *ngIf=\"expandable\" class=\"mb-grid__select-cell\"></td>\n <td *ngIf=\"selectable\" class=\"mb-grid__select-cell\"></td>\n <td *ngFor=\"let column of visibleColumns; trackBy: trackColumn\" class=\"mb-grid__cell\">\n <ng-container [ngTemplateOutlet]=\"editorTemplate\" [ngTemplateOutletContext]=\"{ column: column, row: editingModel, rowIndex: editingRowIndex }\"></ng-container>\n </td>\n <td *ngIf=\"showCommandColumn\" class=\"mb-grid__cell mb-grid__command-cell\">\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"saveEdit($event)\">{{ messages.save }}</button>\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"cancelEditRow($event)\">{{ messages.cancel }}</button>\n </td>\n </tr>\n\n <ng-container *ngFor=\"let row of processed.data; trackBy: trackRow\">\n <tr *ngIf=\"row.kind === 'group'\" class=\"mb-grid__group-row\" (click)=\"toggleGroupRow(row)\">\n <td class=\"mb-grid__group-cell\" [attr.colspan]=\"columnSpan\">\n <span class=\"mb-grid__group-toggle\">{{ row.expanded ? '\u25BE' : '\u25B8' }}</span>\n <span [style.padding-inline-start.px]=\"row.level * 18\"></span>\n <strong>{{ row.field }}:</strong>\n <span>{{ row.value }}</span>\n <small>({{ row.count }})</small>\n </td>\n </tr>\n\n <tr\n *ngIf=\"row.kind === 'data'\"\n class=\"mb-grid__row\"\n [class.mb-grid__row--selected]=\"isSelected(row.dataItem)\"\n [class.mb-grid__row--editing]=\"isEditing(row.dataItem)\"\n [ngClass]=\"getRowClass(row.dataItem, row.rowIndex)\"\n (click)=\"onRowClick(row.dataItem, row.rowIndex)\">\n <td *ngIf=\"expandable\" class=\"mb-grid__select-cell\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"mb-grid__expand-button\" (click)=\"toggleDetail(row.dataItem, row.rowIndex, $event)\">{{ isDetailExpanded(row.dataItem) ? '\u25BE' : '\u25B8' }}</button>\n </td>\n <td *ngIf=\"selectable\" class=\"mb-grid__select-cell\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row.dataItem)\"\n (change)=\"toggleRow(row.dataItem, $event)\"\n [attr.aria-label]=\"messages.selectRow\" />\n </td>\n\n <td\n *ngFor=\"let column of visibleColumns; trackBy: trackColumn\"\n class=\"mb-grid__cell\"\n [ngClass]=\"['mb-grid__cell--' + (column.align || 'start'), getCellClass(row.dataItem, column, row.rowIndex), getColumnClass(column)]\"\n [ngStyle]=\"getColumnStyle(column)\"\n (click)=\"onCellClick(row.dataItem, column, row.rowIndex)\">\n <ng-container *ngIf=\"isEditing(row.dataItem) && canEditColumn(column); else readonlyCell\">\n <ng-container [ngTemplateOutlet]=\"editorTemplate\" [ngTemplateOutletContext]=\"{ column: column, row: editingModel, rowIndex: row.rowIndex }\"></ng-container>\n </ng-container>\n <ng-template #readonlyCell>\n <ng-container *ngIf=\"getCellTemplate(column) as cellTpl; else defaultCell\">\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row.dataItem, dataItem: row.dataItem, column: column, value: getValue(row.dataItem, column, row.rowIndex), rowIndex: row.rowIndex, editing: isEditing(row.dataItem) }\">\n </ng-container>\n </ng-container>\n <ng-template #defaultCell>{{ formatCell(row.dataItem, column, row.rowIndex) }}</ng-template>\n </ng-template>\n </td>\n\n <td *ngIf=\"showCommandColumn\" class=\"mb-grid__cell mb-grid__command-cell\" (click)=\"$event.stopPropagation()\">\n <ng-container *ngIf=\"isEditing(row.dataItem); else readonlyCommands\">\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"saveEdit($event)\">{{ messages.save }}</button>\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"cancelEditRow($event)\">{{ messages.cancel }}</button>\n </ng-container>\n <ng-template #readonlyCommands>\n <button *ngIf=\"editable\" type=\"button\" class=\"mb-grid__command\" (click)=\"startEdit(row.dataItem, row.rowIndex, $event)\">{{ messages.edit }}</button>\n <button *ngIf=\"allowDelete\" type=\"button\" class=\"mb-grid__command mb-grid__command--danger\" (click)=\"removeRow(row.dataItem, row.rowIndex, $event)\">{{ messages.delete }}</button>\n </ng-template>\n </td>\n </tr>\n\n <tr *ngIf=\"row.kind === 'data' && isDetailExpanded(row.dataItem) && detailTemplate?.templateRef as detailTpl\" class=\"mb-grid__detail-row\">\n <td [attr.colspan]=\"columnSpan\">\n <ng-container\n [ngTemplateOutlet]=\"detailTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row.dataItem, dataItem: row.dataItem, rowIndex: row.rowIndex, expanded: isDetailExpanded(row.dataItem) }\">\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </tbody>\n\n <tfoot *ngIf=\"showFooter\">\n <tr class=\"mb-grid__footer-row\">\n <td *ngIf=\"expandable\" class=\"mb-grid__select-cell\"></td>\n <td *ngIf=\"selectable\" class=\"mb-grid__select-cell\"></td>\n <td *ngFor=\"let column of visibleColumns; trackBy: trackColumn\" class=\"mb-grid__footer-cell\">\n <ng-container *ngIf=\"getFooterTemplate(column) as footerTpl; else defaultFooter\">\n <ng-container [ngTemplateOutlet]=\"footerTpl\" [ngTemplateOutletContext]=\"{ $implicit: column, column: column, aggregates: processed.aggregates }\"></ng-container>\n </ng-container>\n <ng-template #defaultFooter>\n <span *ngIf=\"processed.aggregates[column.field.toString()] as aggs\">\n <ng-container *ngFor=\"let key of aggs | keyvalue\">{{ key.key }}: {{ key.value | number }} </ng-container>\n </span>\n </ng-template>\n </td>\n <td *ngIf=\"showCommandColumn\" class=\"mb-grid__command-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n\n <ng-template #editorTemplate let-column=\"column\" let-row=\"row\" let-rowIndex=\"rowIndex\">\n <ng-container *ngIf=\"column.editTemplate as editTpl; else defaultEditor\">\n <ng-container\n [ngTemplateOutlet]=\"editTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row, dataItem: row, column: column, value: getEditValue(column), rowIndex: rowIndex, setValue: setEditValue.bind(this, column), errors: validationErrors }\">\n </ng-container>\n </ng-container>\n <ng-template #defaultEditor>\n <select\n *ngIf=\"getEditorType(column) === 'select'; else nonSelectEditor\"\n class=\"mb-grid__editor\"\n [ngModel]=\"getEditValue(column)\"\n (ngModelChange)=\"setEditValue(column, $event)\">\n <option *ngFor=\"let option of column.editorOptions || []\" [ngValue]=\"option.value\">{{ option.label }}</option>\n </select>\n <ng-template #nonSelectEditor>\n <input\n *ngIf=\"getEditorType(column) !== 'checkbox'; else checkboxEditor\"\n class=\"mb-grid__editor\"\n [type]=\"getEditorType(column) === 'number' ? 'number' : getEditorType(column) === 'date' ? 'date' : 'text'\"\n [ngModel]=\"getEditValue(column)\"\n (ngModelChange)=\"setEditValue(column, $event)\" />\n <ng-template #checkboxEditor>\n <input type=\"checkbox\" [ngModel]=\"getEditValue(column)\" (ngModelChange)=\"setEditValue(column, $event)\" />\n </ng-template>\n </ng-template>\n <small *ngIf=\"validationErrors[column.field.toString()]\" class=\"mb-grid__error\">{{ validationErrors[column.field.toString()] }}</small>\n </ng-template>\n </ng-template>\n\n <div *ngIf=\"pageable\" class=\"mb-grid__pager\">\n <div class=\"mb-grid__pager-info\">{{ pagerInfoText() }}</div>\n <div class=\"mb-grid__pager-actions\">\n <select class=\"mb-grid__page-size\" [ngModel]=\"pageSize\" (ngModelChange)=\"changePageSize($event)\">\n <option *ngFor=\"let option of pageSizeOptions\" [ngValue]=\"option\">{{ option }}</option>\n </select>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex === 0\" (click)=\"changePage(0)\">{{ messages.pagerFirst }}</button>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex === 0\" (click)=\"changePage(pageIndex - 1)\">{{ messages.pagerPrevious }}</button>\n <span class=\"mb-grid__page-current\">{{ pageIndex + 1 }} / {{ pageCount }}</span>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex >= pageCount - 1\" (click)=\"changePage(pageIndex + 1)\">{{ messages.pagerNext }}</button>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex >= pageCount - 1\" (click)=\"changePage(pageCount - 1)\">{{ messages.pagerLast }}</button>\n </div>\n </div>\n</div>\n", styles: [".mb-grid{position:relative;display:flex;flex-direction:column;width:100%;min-height:180px;overflow:hidden;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-lg, 14px);background:var(--mb-surface, #fff);color:var(--mb-text, #0f172a);box-shadow:var(--mb-shadow-sm, 0 1px 2px rgba(15, 23, 42, .06));font-family:var(--mb-font-family, inherit)}.mb-grid--compact{--mb-grid-row-height: 36px;--mb-grid-cell-padding-y: 8px;--mb-grid-cell-padding-x: 10px}.mb-grid--comfortable{--mb-grid-row-height: 44px;--mb-grid-cell-padding-y: 11px;--mb-grid-cell-padding-x: 14px}.mb-grid--spacious{--mb-grid-row-height: 54px;--mb-grid-cell-padding-y: 15px;--mb-grid-cell-padding-x: 18px}.mb-grid__toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-block-end:1px solid var(--mb-border, #e2e8f0);background:color-mix(in srgb,var(--mb-surface, #fff) 88%,var(--mb-primary, #2563eb) 12%)}.mb-grid__toolbar-start,.mb-grid__toolbar-end{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.mb-grid__toolbar-end{margin-inline-start:auto}.mb-grid__group-panel{display:flex;align-items:center;gap:6px;flex-wrap:wrap;min-height:34px}.mb-grid__group-label,.mb-grid__group-hint{color:var(--mb-muted, #64748b);font-size:12px}.mb-grid__group-chip{border:1px solid var(--mb-primary, #2563eb);color:var(--mb-primary, #2563eb);background:#fff;padding:5px 10px;border-radius:999px;cursor:pointer}.mb-grid__search,.mb-grid__filter-input,.mb-grid__filter-operator,.mb-grid__page-size,.mb-grid__column-menu input,.mb-grid__column-menu select{min-height:34px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-md, 10px);background:var(--mb-input-bg, #fff);color:var(--mb-text, #0f172a);padding:0 10px;outline:none;font:inherit}.mb-grid__search{min-width:220px}.mb-grid__search:focus,.mb-grid__filter-input:focus,.mb-grid__filter-operator:focus,.mb-grid__page-size:focus{border-color:var(--mb-primary, #2563eb);box-shadow:0 0 0 3px color-mix(in srgb,var(--mb-primary, #2563eb) 15%,transparent)}.mb-grid__tool-button,.mb-grid__pager-button,.mb-grid__menu-action{min-height:34px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-md, 10px);background:var(--mb-surface, #fff);color:var(--mb-text, #0f172a);padding:0 12px;cursor:pointer;font:inherit;transition:background .15s ease,border-color .15s ease,transform .15s ease}.mb-grid__tool-button:hover,.mb-grid__pager-button:hover:not(:disabled),.mb-grid__menu-action:hover{border-color:color-mix(in srgb,var(--mb-primary, #2563eb) 45%,var(--mb-border, #e2e8f0));background:color-mix(in srgb,var(--mb-primary, #2563eb) 8%,#fff)}.mb-grid__pager-button:disabled{opacity:.45;cursor:not-allowed}.mb-grid__chooser{position:relative}.mb-grid__chooser-menu,.mb-grid__column-menu{position:absolute;z-index:20;inset-block-start:calc(100% + 6px);inset-inline-end:0;min-width:230px;padding:8px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-lg, 14px);background:var(--mb-surface, #fff);box-shadow:var(--mb-shadow-lg, 0 16px 40px rgba(15, 23, 42, .16))}.mb-grid__chooser-option{display:flex;align-items:center;gap:8px;padding:8px;border-radius:var(--mb-radius-md, 10px);cursor:pointer}.mb-grid__chooser-option:hover{background:var(--mb-hover, #f8fafc)}.mb-grid__scroll{flex:1;min-height:0;overflow:auto}.mb-grid__table{width:100%;min-width:max-content;border-collapse:separate;border-spacing:0;table-layout:fixed}.mb-grid__header-row,.mb-grid__filter-row,.mb-grid__footer-row{background:var(--mb-grid-header-bg, #f8fafc)}.mb-grid__header-cell,.mb-grid__filter-cell,.mb-grid__footer-cell,.mb-grid__cell,.mb-grid__select-cell{position:relative;border-block-end:1px solid var(--mb-border, #e2e8f0);border-inline-end:1px solid var(--mb-border-subtle, #eef2f7);padding:var(--mb-grid-cell-padding-y) var(--mb-grid-cell-padding-x);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;height:var(--mb-grid-row-height)}.mb-grid__cell--locked-start,.mb-grid__header-cell.mb-grid__cell--locked-start,.mb-grid__filter-cell.mb-grid__cell--locked-start,.mb-grid__footer-cell.mb-grid__cell--locked-start{background:var(--mb-grid-locked-bg, var(--mb-surface, #fff));box-shadow:4px 0 8px -4px #0f172a1f}.mb-grid__cell--locked-end,.mb-grid__header-cell.mb-grid__cell--locked-end,.mb-grid__filter-cell.mb-grid__cell--locked-end,.mb-grid__footer-cell.mb-grid__cell--locked-end{background:var(--mb-grid-locked-bg, var(--mb-surface, #fff));box-shadow:-4px 0 8px -4px #0f172a1f}.mb-grid__header-cell{position:sticky;inset-block-start:0;z-index:5;-webkit-user-select:none;user-select:none;font-weight:700;color:var(--mb-grid-header-text, #334155);background:var(--mb-grid-header-bg, #f8fafc)}.mb-grid__filter-cell{position:sticky;inset-block-start:var(--mb-grid-row-height);z-index:4;background:var(--mb-grid-header-bg, #f8fafc);padding:8px}.mb-grid__header-cell--sortable .mb-grid__header-content{cursor:pointer}.mb-grid__header-content{display:flex;align-items:center;gap:6px;min-width:0}.mb-grid__header-title{overflow:hidden;text-overflow:ellipsis}.mb-grid__sort{display:inline-flex;align-items:center;gap:2px;color:var(--mb-primary, #2563eb)}.mb-grid__sort small{font-size:10px}.mb-grid__column-menu-button{position:absolute;inset-inline-end:4px;inset-block-start:50%;transform:translateY(-50%);width:26px;height:26px;border:none;border-radius:8px;background:transparent;cursor:pointer;opacity:.55}.mb-grid__column-menu-button:hover{background:var(--mb-hover, #f1f5f9);opacity:1}.mb-grid__resize-handle{position:absolute;inset-block:8px;inset-inline-end:-2px;width:5px;cursor:col-resize;z-index:7}.mb-grid__resize-handle:hover{background:color-mix(in srgb,var(--mb-primary, #2563eb) 40%,transparent)}.mb-grid__column-menu{inset-block-start:calc(100% - 4px);inset-inline-end:6px;text-align:start}.mb-grid__menu-action{display:flex;align-items:center;width:100%;justify-content:flex-start;margin-block:4px}.mb-grid__menu-filter{display:grid;gap:8px;margin-block:8px;padding-block:8px;border-block:1px solid var(--mb-border, #e2e8f0)}.mb-grid__filter-control{display:grid;grid-template-columns:minmax(105px,.75fr) minmax(120px,1fr);gap:6px}.mb-grid__row{background:var(--mb-surface, #fff);transition:background .12s ease}.mb-grid__row:hover{background:var(--mb-hover, #f8fafc)}.mb-grid__row--selected{background:color-mix(in srgb,var(--mb-primary, #2563eb) 10%,#fff)}.mb-grid__cell--start{text-align:start}.mb-grid__cell--center{text-align:center}.mb-grid__cell--end{text-align:end}.mb-grid__select-cell{width:48px;min-width:48px;max-width:48px;text-align:center}.mb-grid__group-row{background:color-mix(in srgb,var(--mb-primary, #2563eb) 8%,#fff);cursor:pointer}.mb-grid__group-cell{padding:11px 14px;border-block-end:1px solid var(--mb-border, #e2e8f0);font-weight:600}.mb-grid__group-toggle{display:inline-flex;width:20px;justify-content:center;color:var(--mb-primary, #2563eb)}.mb-grid__detail-row td{padding:0;border-block-end:1px solid var(--mb-border, #e2e8f0);background:var(--mb-subtle, #f8fafc)}.mb-grid__empty{text-align:center;padding:36px 16px;color:var(--mb-muted, #64748b)}.mb-grid__footer-cell{font-weight:700;background:var(--mb-grid-footer-bg, #f8fafc)}.mb-grid__pager{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border-block-start:1px solid var(--mb-border, #e2e8f0);background:var(--mb-surface, #fff)}.mb-grid__pager-actions{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.mb-grid__pager-info,.mb-grid__page-current{color:var(--mb-muted, #64748b);font-size:13px}.mb-grid__loading{position:absolute;z-index:30;inset:0;display:flex;align-items:center;justify-content:center;gap:10px;background:#ffffffad;backdrop-filter:blur(2px)}.mb-grid__spinner{width:24px;height:24px;border-radius:50%;border:3px solid var(--mb-border, #e2e8f0);border-block-start-color:var(--mb-primary, #2563eb);animation:mb-grid-spin .8s linear infinite}.cdk-drag-preview{box-sizing:border-box;border-radius:var(--mb-radius-md, 10px);box-shadow:var(--mb-shadow-lg, 0 16px 40px rgba(15, 23, 42, .16));background:#fff;padding:10px 14px}.cdk-drag-placeholder{opacity:.25}@keyframes mb-grid-spin{to{transform:rotate(360deg)}}@media (max-width: 720px){.mb-grid__toolbar,.mb-grid__pager{align-items:stretch;flex-direction:column}.mb-grid__toolbar-end,.mb-grid__pager-actions{width:100%}.mb-grid__search{width:100%;min-width:0}}.mb-grid__tool-button--primary{background:var(--mb-primary, #2563eb);border-color:var(--mb-primary, #2563eb);color:#fff}.mb-grid__command-cell{width:1%;white-space:nowrap;text-align:center}.mb-grid__command{min-height:30px;margin-inline:2px;padding:0 10px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-sm, 8px);background:var(--mb-surface, #fff);color:var(--mb-text, #0f172a);cursor:pointer;font:inherit}.mb-grid__command:hover{border-color:var(--mb-primary, #2563eb);color:var(--mb-primary, #2563eb)}.mb-grid__command--danger:hover{border-color:var(--mb-danger, #dc2626);color:var(--mb-danger, #dc2626)}.mb-grid__row--editing{background:color-mix(in srgb,var(--mb-primary, #2563eb) 7%,var(--mb-surface, #fff))}.mb-grid__row--new{border-block-start:2px solid var(--mb-primary, #2563eb)}.mb-grid__editor{width:100%;min-height:34px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-sm, 8px);background:var(--mb-input-bg, #fff);color:var(--mb-text, #0f172a);padding-inline:8px;font:inherit;outline:none}.mb-grid__editor:focus{border-color:var(--mb-primary, #2563eb);box-shadow:0 0 0 3px color-mix(in srgb,var(--mb-primary, #2563eb) 15%,transparent)}.mb-grid__error{display:block;margin-block-start:4px;color:var(--mb-danger, #dc2626);font-size:11px}.mb-grid__expand-button{border:0;background:transparent;cursor:pointer;font-size:16px;color:var(--mb-muted, #64748b)}.mb-grid__detail-row td{padding:14px;background:color-mix(in srgb,var(--mb-surface, #fff) 92%,var(--mb-primary, #2563eb) 8%)}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: ScrollingModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
831
+ }
832
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MbGridComponent, decorators: [{
833
+ type: Component,
834
+ args: [{ selector: 'mb-grid', standalone: true, imports: [NgIf, NgFor, NgClass, NgStyle, NgTemplateOutlet, DecimalPipe, KeyValuePipe, FormsModule, DragDropModule, ScrollingModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mb-grid\" [attr.dir]=\"effectiveDir\" [ngClass]=\"['mb-grid--' + density, loading ? 'mb-grid--loading' : '']\" [ngStyle]=\"gridStyle\">\n <div *ngIf=\"showToolbar\" class=\"mb-grid__toolbar\">\n <ng-container *ngIf=\"toolbarTemplate?.templateRef as toolbarTpl; else defaultToolbar\">\n <ng-container [ngTemplateOutlet]=\"toolbarTpl\" [ngTemplateOutletContext]=\"toolbarContext\"></ng-container>\n </ng-container>\n\n <ng-template #defaultToolbar>\n <div class=\"mb-grid__toolbar-start\">\n <div *ngIf=\"groupable\" class=\"mb-grid__group-panel\">\n <span class=\"mb-grid__group-label\">{{ messages.groupLabel }}</span>\n <button\n *ngFor=\"let group of state.group\"\n type=\"button\"\n class=\"mb-grid__group-chip\"\n (click)=\"removeGroup(group)\">\n {{ group.field }} \u00D7\n </button>\n <span *ngIf=\"!state.group.length\" class=\"mb-grid__group-hint\">{{ messages.groupHint }}</span>\n </div>\n </div>\n\n <div class=\"mb-grid__toolbar-end\">\n <button *ngIf=\"editable && allowAdd\" type=\"button\" class=\"mb-grid__tool-button mb-grid__tool-button--primary\" (click)=\"createRow()\">{{ messages.addRow }}</button>\n <input\n *ngIf=\"showSearch\"\n class=\"mb-grid__search\"\n [ngModel]=\"globalSearch\"\n (ngModelChange)=\"applyGlobalSearch($event)\"\n [placeholder]=\"messages.searchPlaceholder\" />\n\n <div *ngIf=\"showColumnChooser\" class=\"mb-grid__chooser\">\n <button type=\"button\" class=\"mb-grid__tool-button\" (click)=\"openColumnMenuField = openColumnMenuField === '__chooser' ? '' : '__chooser'\">\n {{ messages.columns }}\n </button>\n <div *ngIf=\"openColumnMenuField === '__chooser'\" class=\"mb-grid__chooser-menu\" (click)=\"$event.stopPropagation()\">\n <label *ngFor=\"let column of internalColumns\" class=\"mb-grid__chooser-option\">\n <input type=\"checkbox\" [checked]=\"!column.hidden\" (change)=\"showColumn(column, $any($event.target).checked)\" />\n <span>{{ column.title }}</span>\n </label>\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"resetColumns()\">{{ messages.resetColumns }}</button>\n </div>\n </div>\n\n <button *ngIf=\"showExport\" type=\"button\" class=\"mb-grid__tool-button\" (click)=\"exportCsv()\">{{ messages.exportCsv }}</button>\n <button *ngIf=\"showExport && showExcelExport\" type=\"button\" class=\"mb-grid__tool-button\" (click)=\"exportExcel()\">{{ messages.exportExcel }}</button>\n <button *ngIf=\"showExport && showJsonExport\" type=\"button\" class=\"mb-grid__tool-button\" (click)=\"exportJson()\">{{ messages.exportJson }}</button>\n <button type=\"button\" class=\"mb-grid__tool-button\" (click)=\"resetState()\">{{ messages.reset }}</button>\n </div>\n </ng-template>\n </div>\n\n <div *ngIf=\"loading\" class=\"mb-grid__loading\" aria-live=\"polite\">\n <span class=\"mb-grid__spinner\"></span>\n <span>{{ loadingText || messages.loading }}</span>\n </div>\n\n <div class=\"mb-grid__scroll\">\n <table class=\"mb-grid__table\">\n <thead>\n <tr\n class=\"mb-grid__header-row\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListDisabled]=\"!reorderable\"\n [cdkDropListData]=\"visibleColumns\"\n (cdkDropListDropped)=\"dropColumn($event)\">\n <th *ngIf=\"expandable\" class=\"mb-grid__select-cell mb-grid__header-cell\"></th>\n <th *ngIf=\"selectable\" class=\"mb-grid__select-cell mb-grid__header-cell\">\n <input\n type=\"checkbox\"\n [checked]=\"allVisibleRowsSelected\"\n [indeterminate]=\"someVisibleRowsSelected\"\n (change)=\"toggleAllVisible($event)\"\n [attr.aria-label]=\"messages.selectAllRows\" />\n </th>\n\n <th\n *ngFor=\"let column of visibleColumns; let columnIndex = index; trackBy: trackColumn\"\n cdkDrag\n class=\"mb-grid__header-cell\"\n [ngClass]=\"['mb-grid__cell--' + (column.headerAlign || column.align || 'start'), column.sortable === false ? '' : 'mb-grid__header-cell--sortable', getColumnClass(column)]\"\n [ngStyle]=\"getColumnStyle(column)\">\n <div class=\"mb-grid__header-content\" (click)=\"toggleSort(column, $event)\">\n <ng-container *ngIf=\"getHeaderTemplate(column) as headerTpl; else defaultHeader\">\n <ng-container [ngTemplateOutlet]=\"headerTpl\" [ngTemplateOutletContext]=\"{ $implicit: column, column: column }\"></ng-container>\n </ng-container>\n <ng-template #defaultHeader>\n <span class=\"mb-grid__header-title\">{{ column.title }}</span>\n </ng-template>\n\n <span *ngIf=\"getSortDirection(column) as dir\" class=\"mb-grid__sort\">\n <span>{{ dir === 'asc' ? '\u2191' : '\u2193' }}</span>\n <small *ngIf=\"multiSort && getSortIndex(column) >= 0\">{{ getSortIndex(column) + 1 }}</small>\n </span>\n </div>\n\n <button\n *ngIf=\"hasColumnMenu && column.menu !== false\"\n type=\"button\"\n class=\"mb-grid__column-menu-button\"\n [attr.aria-label]=\"messages.columnMenu\"\n (click)=\"toggleColumnMenu(column, $event)\">\u22EE</button>\n\n <span\n *ngIf=\"resizable && column.resizable !== false\"\n class=\"mb-grid__resize-handle\"\n (mousedown)=\"startResize(column, $event)\"></span>\n\n <div *ngIf=\"openColumnMenuField === column.field.toString()\" class=\"mb-grid__column-menu\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"toggleSort(column)\">{{ messages.sort }}</button>\n <button *ngIf=\"groupable && column.groupable !== false\" type=\"button\" class=\"mb-grid__menu-action\" (click)=\"toggleGroup(column)\">\n {{ state.group.length && state.group[0].field === column.field ? messages.removeGroup : messages.groupByColumn }}\n </button>\n\n <div *ngIf=\"filterable && column.filterable !== false && (filterMode === 'menu' || filterMode === 'both')\" class=\"mb-grid__menu-filter\">\n <label>{{ messages.filter }}</label>\n <select [ngModel]=\"filtersByField[column.field.toString()].operator\" (ngModelChange)=\"setFilterOperator(column, $event)\">\n <option *ngFor=\"let operator of getOperators(column)\" [ngValue]=\"operator\">{{ getOperatorLabel(operator) }}</option>\n </select>\n <input\n [type]=\"column.type === 'number' ? 'number' : column.type === 'date' ? 'date' : 'text'\"\n [ngModel]=\"filtersByField[column.field.toString()].value\"\n (ngModelChange)=\"setFilterValue(column, $event)\"\n [placeholder]=\"messages.filterValuePlaceholder\" />\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"clearFilter(column)\">{{ messages.clearFilter }}</button>\n </div>\n\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"toggleLock(column)\">{{ column.locked ? messages.unlockColumn : messages.lockColumn }}</button>\n <button type=\"button\" class=\"mb-grid__menu-action\" (click)=\"hideColumn(column)\">{{ messages.hideColumn }}</button>\n </div>\n </th>\n\n <th *ngIf=\"showCommandColumn\" class=\"mb-grid__header-cell mb-grid__command-cell\">{{ effectiveCommandColumnTitle }}</th>\n </tr>\n\n <tr *ngIf=\"hasFilterRow\" class=\"mb-grid__filter-row\">\n <th *ngIf=\"expandable\" class=\"mb-grid__select-cell\"></th>\n <th *ngIf=\"selectable\" class=\"mb-grid__select-cell\"></th>\n <th *ngFor=\"let column of visibleColumns; trackBy: trackColumn\" class=\"mb-grid__filter-cell\" [ngClass]=\"getColumnClass(column)\" [ngStyle]=\"getColumnStyle(column)\">\n <div *ngIf=\"column.filterable !== false\" class=\"mb-grid__filter-control\">\n <select\n class=\"mb-grid__filter-operator\"\n [ngModel]=\"filtersByField[column.field.toString()].operator\"\n (ngModelChange)=\"setFilterOperator(column, $event)\">\n <option *ngFor=\"let operator of getOperators(column)\" [ngValue]=\"operator\">{{ getOperatorLabel(operator) }}</option>\n </select>\n <input\n class=\"mb-grid__filter-input\"\n [type]=\"column.type === 'number' ? 'number' : column.type === 'date' ? 'date' : 'text'\"\n [placeholder]=\"column.title\"\n [ngModel]=\"filtersByField[column.field.toString()].value\"\n (ngModelChange)=\"setFilterValue(column, $event)\" />\n </div>\n </th>\n <th *ngIf=\"showCommandColumn\" class=\"mb-grid__command-cell\"></th>\n </tr>\n </thead>\n\n <tbody>\n <tr *ngIf=\"!processed.data.length && !loading\" class=\"mb-grid__empty-row\">\n <td class=\"mb-grid__empty\" [attr.colspan]=\"columnSpan\">{{ noRecordsText || messages.noRecords }}</td>\n </tr>\n\n <tr *ngIf=\"isNewRowEditing() && editingModel\" class=\"mb-grid__row mb-grid__row--editing mb-grid__row--new\">\n <td *ngIf=\"expandable\" class=\"mb-grid__select-cell\"></td>\n <td *ngIf=\"selectable\" class=\"mb-grid__select-cell\"></td>\n <td *ngFor=\"let column of visibleColumns; trackBy: trackColumn\" class=\"mb-grid__cell\">\n <ng-container [ngTemplateOutlet]=\"editorTemplate\" [ngTemplateOutletContext]=\"{ column: column, row: editingModel, rowIndex: editingRowIndex }\"></ng-container>\n </td>\n <td *ngIf=\"showCommandColumn\" class=\"mb-grid__cell mb-grid__command-cell\">\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"saveEdit($event)\">{{ messages.save }}</button>\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"cancelEditRow($event)\">{{ messages.cancel }}</button>\n </td>\n </tr>\n\n <ng-container *ngFor=\"let row of processed.data; trackBy: trackRow\">\n <tr *ngIf=\"row.kind === 'group'\" class=\"mb-grid__group-row\" (click)=\"toggleGroupRow(row)\">\n <td class=\"mb-grid__group-cell\" [attr.colspan]=\"columnSpan\">\n <span class=\"mb-grid__group-toggle\">{{ row.expanded ? '\u25BE' : '\u25B8' }}</span>\n <span [style.padding-inline-start.px]=\"row.level * 18\"></span>\n <strong>{{ row.field }}:</strong>\n <span>{{ row.value }}</span>\n <small>({{ row.count }})</small>\n </td>\n </tr>\n\n <tr\n *ngIf=\"row.kind === 'data'\"\n class=\"mb-grid__row\"\n [class.mb-grid__row--selected]=\"isSelected(row.dataItem)\"\n [class.mb-grid__row--editing]=\"isEditing(row.dataItem)\"\n [ngClass]=\"getRowClass(row.dataItem, row.rowIndex)\"\n (click)=\"onRowClick(row.dataItem, row.rowIndex)\">\n <td *ngIf=\"expandable\" class=\"mb-grid__select-cell\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"mb-grid__expand-button\" (click)=\"toggleDetail(row.dataItem, row.rowIndex, $event)\">{{ isDetailExpanded(row.dataItem) ? '\u25BE' : '\u25B8' }}</button>\n </td>\n <td *ngIf=\"selectable\" class=\"mb-grid__select-cell\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row.dataItem)\"\n (change)=\"toggleRow(row.dataItem, $event)\"\n [attr.aria-label]=\"messages.selectRow\" />\n </td>\n\n <td\n *ngFor=\"let column of visibleColumns; trackBy: trackColumn\"\n class=\"mb-grid__cell\"\n [ngClass]=\"['mb-grid__cell--' + (column.align || 'start'), getCellClass(row.dataItem, column, row.rowIndex), getColumnClass(column)]\"\n [ngStyle]=\"getColumnStyle(column)\"\n (click)=\"onCellClick(row.dataItem, column, row.rowIndex)\">\n <ng-container *ngIf=\"isEditing(row.dataItem) && canEditColumn(column); else readonlyCell\">\n <ng-container [ngTemplateOutlet]=\"editorTemplate\" [ngTemplateOutletContext]=\"{ column: column, row: editingModel, rowIndex: row.rowIndex }\"></ng-container>\n </ng-container>\n <ng-template #readonlyCell>\n <ng-container *ngIf=\"getCellTemplate(column) as cellTpl; else defaultCell\">\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row.dataItem, dataItem: row.dataItem, column: column, value: getValue(row.dataItem, column, row.rowIndex), rowIndex: row.rowIndex, editing: isEditing(row.dataItem) }\">\n </ng-container>\n </ng-container>\n <ng-template #defaultCell>{{ formatCell(row.dataItem, column, row.rowIndex) }}</ng-template>\n </ng-template>\n </td>\n\n <td *ngIf=\"showCommandColumn\" class=\"mb-grid__cell mb-grid__command-cell\" (click)=\"$event.stopPropagation()\">\n <ng-container *ngIf=\"isEditing(row.dataItem); else readonlyCommands\">\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"saveEdit($event)\">{{ messages.save }}</button>\n <button type=\"button\" class=\"mb-grid__command\" (click)=\"cancelEditRow($event)\">{{ messages.cancel }}</button>\n </ng-container>\n <ng-template #readonlyCommands>\n <button *ngIf=\"editable\" type=\"button\" class=\"mb-grid__command\" (click)=\"startEdit(row.dataItem, row.rowIndex, $event)\">{{ messages.edit }}</button>\n <button *ngIf=\"allowDelete\" type=\"button\" class=\"mb-grid__command mb-grid__command--danger\" (click)=\"removeRow(row.dataItem, row.rowIndex, $event)\">{{ messages.delete }}</button>\n </ng-template>\n </td>\n </tr>\n\n <tr *ngIf=\"row.kind === 'data' && isDetailExpanded(row.dataItem) && detailTemplate?.templateRef as detailTpl\" class=\"mb-grid__detail-row\">\n <td [attr.colspan]=\"columnSpan\">\n <ng-container\n [ngTemplateOutlet]=\"detailTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row.dataItem, dataItem: row.dataItem, rowIndex: row.rowIndex, expanded: isDetailExpanded(row.dataItem) }\">\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </tbody>\n\n <tfoot *ngIf=\"showFooter\">\n <tr class=\"mb-grid__footer-row\">\n <td *ngIf=\"expandable\" class=\"mb-grid__select-cell\"></td>\n <td *ngIf=\"selectable\" class=\"mb-grid__select-cell\"></td>\n <td *ngFor=\"let column of visibleColumns; trackBy: trackColumn\" class=\"mb-grid__footer-cell\">\n <ng-container *ngIf=\"getFooterTemplate(column) as footerTpl; else defaultFooter\">\n <ng-container [ngTemplateOutlet]=\"footerTpl\" [ngTemplateOutletContext]=\"{ $implicit: column, column: column, aggregates: processed.aggregates }\"></ng-container>\n </ng-container>\n <ng-template #defaultFooter>\n <span *ngIf=\"processed.aggregates[column.field.toString()] as aggs\">\n <ng-container *ngFor=\"let key of aggs | keyvalue\">{{ key.key }}: {{ key.value | number }} </ng-container>\n </span>\n </ng-template>\n </td>\n <td *ngIf=\"showCommandColumn\" class=\"mb-grid__command-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n\n <ng-template #editorTemplate let-column=\"column\" let-row=\"row\" let-rowIndex=\"rowIndex\">\n <ng-container *ngIf=\"column.editTemplate as editTpl; else defaultEditor\">\n <ng-container\n [ngTemplateOutlet]=\"editTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row, dataItem: row, column: column, value: getEditValue(column), rowIndex: rowIndex, setValue: setEditValue.bind(this, column), errors: validationErrors }\">\n </ng-container>\n </ng-container>\n <ng-template #defaultEditor>\n <select\n *ngIf=\"getEditorType(column) === 'select'; else nonSelectEditor\"\n class=\"mb-grid__editor\"\n [ngModel]=\"getEditValue(column)\"\n (ngModelChange)=\"setEditValue(column, $event)\">\n <option *ngFor=\"let option of column.editorOptions || []\" [ngValue]=\"option.value\">{{ option.label }}</option>\n </select>\n <ng-template #nonSelectEditor>\n <input\n *ngIf=\"getEditorType(column) !== 'checkbox'; else checkboxEditor\"\n class=\"mb-grid__editor\"\n [type]=\"getEditorType(column) === 'number' ? 'number' : getEditorType(column) === 'date' ? 'date' : 'text'\"\n [ngModel]=\"getEditValue(column)\"\n (ngModelChange)=\"setEditValue(column, $event)\" />\n <ng-template #checkboxEditor>\n <input type=\"checkbox\" [ngModel]=\"getEditValue(column)\" (ngModelChange)=\"setEditValue(column, $event)\" />\n </ng-template>\n </ng-template>\n <small *ngIf=\"validationErrors[column.field.toString()]\" class=\"mb-grid__error\">{{ validationErrors[column.field.toString()] }}</small>\n </ng-template>\n </ng-template>\n\n <div *ngIf=\"pageable\" class=\"mb-grid__pager\">\n <div class=\"mb-grid__pager-info\">{{ pagerInfoText() }}</div>\n <div class=\"mb-grid__pager-actions\">\n <select class=\"mb-grid__page-size\" [ngModel]=\"pageSize\" (ngModelChange)=\"changePageSize($event)\">\n <option *ngFor=\"let option of pageSizeOptions\" [ngValue]=\"option\">{{ option }}</option>\n </select>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex === 0\" (click)=\"changePage(0)\">{{ messages.pagerFirst }}</button>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex === 0\" (click)=\"changePage(pageIndex - 1)\">{{ messages.pagerPrevious }}</button>\n <span class=\"mb-grid__page-current\">{{ pageIndex + 1 }} / {{ pageCount }}</span>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex >= pageCount - 1\" (click)=\"changePage(pageIndex + 1)\">{{ messages.pagerNext }}</button>\n <button type=\"button\" class=\"mb-grid__pager-button\" [disabled]=\"pageIndex >= pageCount - 1\" (click)=\"changePage(pageCount - 1)\">{{ messages.pagerLast }}</button>\n </div>\n </div>\n</div>\n", styles: [".mb-grid{position:relative;display:flex;flex-direction:column;width:100%;min-height:180px;overflow:hidden;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-lg, 14px);background:var(--mb-surface, #fff);color:var(--mb-text, #0f172a);box-shadow:var(--mb-shadow-sm, 0 1px 2px rgba(15, 23, 42, .06));font-family:var(--mb-font-family, inherit)}.mb-grid--compact{--mb-grid-row-height: 36px;--mb-grid-cell-padding-y: 8px;--mb-grid-cell-padding-x: 10px}.mb-grid--comfortable{--mb-grid-row-height: 44px;--mb-grid-cell-padding-y: 11px;--mb-grid-cell-padding-x: 14px}.mb-grid--spacious{--mb-grid-row-height: 54px;--mb-grid-cell-padding-y: 15px;--mb-grid-cell-padding-x: 18px}.mb-grid__toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-block-end:1px solid var(--mb-border, #e2e8f0);background:color-mix(in srgb,var(--mb-surface, #fff) 88%,var(--mb-primary, #2563eb) 12%)}.mb-grid__toolbar-start,.mb-grid__toolbar-end{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.mb-grid__toolbar-end{margin-inline-start:auto}.mb-grid__group-panel{display:flex;align-items:center;gap:6px;flex-wrap:wrap;min-height:34px}.mb-grid__group-label,.mb-grid__group-hint{color:var(--mb-muted, #64748b);font-size:12px}.mb-grid__group-chip{border:1px solid var(--mb-primary, #2563eb);color:var(--mb-primary, #2563eb);background:#fff;padding:5px 10px;border-radius:999px;cursor:pointer}.mb-grid__search,.mb-grid__filter-input,.mb-grid__filter-operator,.mb-grid__page-size,.mb-grid__column-menu input,.mb-grid__column-menu select{min-height:34px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-md, 10px);background:var(--mb-input-bg, #fff);color:var(--mb-text, #0f172a);padding:0 10px;outline:none;font:inherit}.mb-grid__search{min-width:220px}.mb-grid__search:focus,.mb-grid__filter-input:focus,.mb-grid__filter-operator:focus,.mb-grid__page-size:focus{border-color:var(--mb-primary, #2563eb);box-shadow:0 0 0 3px color-mix(in srgb,var(--mb-primary, #2563eb) 15%,transparent)}.mb-grid__tool-button,.mb-grid__pager-button,.mb-grid__menu-action{min-height:34px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-md, 10px);background:var(--mb-surface, #fff);color:var(--mb-text, #0f172a);padding:0 12px;cursor:pointer;font:inherit;transition:background .15s ease,border-color .15s ease,transform .15s ease}.mb-grid__tool-button:hover,.mb-grid__pager-button:hover:not(:disabled),.mb-grid__menu-action:hover{border-color:color-mix(in srgb,var(--mb-primary, #2563eb) 45%,var(--mb-border, #e2e8f0));background:color-mix(in srgb,var(--mb-primary, #2563eb) 8%,#fff)}.mb-grid__pager-button:disabled{opacity:.45;cursor:not-allowed}.mb-grid__chooser{position:relative}.mb-grid__chooser-menu,.mb-grid__column-menu{position:absolute;z-index:20;inset-block-start:calc(100% + 6px);inset-inline-end:0;min-width:230px;padding:8px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-lg, 14px);background:var(--mb-surface, #fff);box-shadow:var(--mb-shadow-lg, 0 16px 40px rgba(15, 23, 42, .16))}.mb-grid__chooser-option{display:flex;align-items:center;gap:8px;padding:8px;border-radius:var(--mb-radius-md, 10px);cursor:pointer}.mb-grid__chooser-option:hover{background:var(--mb-hover, #f8fafc)}.mb-grid__scroll{flex:1;min-height:0;overflow:auto}.mb-grid__table{width:100%;min-width:max-content;border-collapse:separate;border-spacing:0;table-layout:fixed}.mb-grid__header-row,.mb-grid__filter-row,.mb-grid__footer-row{background:var(--mb-grid-header-bg, #f8fafc)}.mb-grid__header-cell,.mb-grid__filter-cell,.mb-grid__footer-cell,.mb-grid__cell,.mb-grid__select-cell{position:relative;border-block-end:1px solid var(--mb-border, #e2e8f0);border-inline-end:1px solid var(--mb-border-subtle, #eef2f7);padding:var(--mb-grid-cell-padding-y) var(--mb-grid-cell-padding-x);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;height:var(--mb-grid-row-height)}.mb-grid__cell--locked-start,.mb-grid__header-cell.mb-grid__cell--locked-start,.mb-grid__filter-cell.mb-grid__cell--locked-start,.mb-grid__footer-cell.mb-grid__cell--locked-start{background:var(--mb-grid-locked-bg, var(--mb-surface, #fff));box-shadow:4px 0 8px -4px #0f172a1f}.mb-grid__cell--locked-end,.mb-grid__header-cell.mb-grid__cell--locked-end,.mb-grid__filter-cell.mb-grid__cell--locked-end,.mb-grid__footer-cell.mb-grid__cell--locked-end{background:var(--mb-grid-locked-bg, var(--mb-surface, #fff));box-shadow:-4px 0 8px -4px #0f172a1f}.mb-grid__header-cell{position:sticky;inset-block-start:0;z-index:5;-webkit-user-select:none;user-select:none;font-weight:700;color:var(--mb-grid-header-text, #334155);background:var(--mb-grid-header-bg, #f8fafc)}.mb-grid__filter-cell{position:sticky;inset-block-start:var(--mb-grid-row-height);z-index:4;background:var(--mb-grid-header-bg, #f8fafc);padding:8px}.mb-grid__header-cell--sortable .mb-grid__header-content{cursor:pointer}.mb-grid__header-content{display:flex;align-items:center;gap:6px;min-width:0}.mb-grid__header-title{overflow:hidden;text-overflow:ellipsis}.mb-grid__sort{display:inline-flex;align-items:center;gap:2px;color:var(--mb-primary, #2563eb)}.mb-grid__sort small{font-size:10px}.mb-grid__column-menu-button{position:absolute;inset-inline-end:4px;inset-block-start:50%;transform:translateY(-50%);width:26px;height:26px;border:none;border-radius:8px;background:transparent;cursor:pointer;opacity:.55}.mb-grid__column-menu-button:hover{background:var(--mb-hover, #f1f5f9);opacity:1}.mb-grid__resize-handle{position:absolute;inset-block:8px;inset-inline-end:-2px;width:5px;cursor:col-resize;z-index:7}.mb-grid__resize-handle:hover{background:color-mix(in srgb,var(--mb-primary, #2563eb) 40%,transparent)}.mb-grid__column-menu{inset-block-start:calc(100% - 4px);inset-inline-end:6px;text-align:start}.mb-grid__menu-action{display:flex;align-items:center;width:100%;justify-content:flex-start;margin-block:4px}.mb-grid__menu-filter{display:grid;gap:8px;margin-block:8px;padding-block:8px;border-block:1px solid var(--mb-border, #e2e8f0)}.mb-grid__filter-control{display:grid;grid-template-columns:minmax(105px,.75fr) minmax(120px,1fr);gap:6px}.mb-grid__row{background:var(--mb-surface, #fff);transition:background .12s ease}.mb-grid__row:hover{background:var(--mb-hover, #f8fafc)}.mb-grid__row--selected{background:color-mix(in srgb,var(--mb-primary, #2563eb) 10%,#fff)}.mb-grid__cell--start{text-align:start}.mb-grid__cell--center{text-align:center}.mb-grid__cell--end{text-align:end}.mb-grid__select-cell{width:48px;min-width:48px;max-width:48px;text-align:center}.mb-grid__group-row{background:color-mix(in srgb,var(--mb-primary, #2563eb) 8%,#fff);cursor:pointer}.mb-grid__group-cell{padding:11px 14px;border-block-end:1px solid var(--mb-border, #e2e8f0);font-weight:600}.mb-grid__group-toggle{display:inline-flex;width:20px;justify-content:center;color:var(--mb-primary, #2563eb)}.mb-grid__detail-row td{padding:0;border-block-end:1px solid var(--mb-border, #e2e8f0);background:var(--mb-subtle, #f8fafc)}.mb-grid__empty{text-align:center;padding:36px 16px;color:var(--mb-muted, #64748b)}.mb-grid__footer-cell{font-weight:700;background:var(--mb-grid-footer-bg, #f8fafc)}.mb-grid__pager{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border-block-start:1px solid var(--mb-border, #e2e8f0);background:var(--mb-surface, #fff)}.mb-grid__pager-actions{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.mb-grid__pager-info,.mb-grid__page-current{color:var(--mb-muted, #64748b);font-size:13px}.mb-grid__loading{position:absolute;z-index:30;inset:0;display:flex;align-items:center;justify-content:center;gap:10px;background:#ffffffad;backdrop-filter:blur(2px)}.mb-grid__spinner{width:24px;height:24px;border-radius:50%;border:3px solid var(--mb-border, #e2e8f0);border-block-start-color:var(--mb-primary, #2563eb);animation:mb-grid-spin .8s linear infinite}.cdk-drag-preview{box-sizing:border-box;border-radius:var(--mb-radius-md, 10px);box-shadow:var(--mb-shadow-lg, 0 16px 40px rgba(15, 23, 42, .16));background:#fff;padding:10px 14px}.cdk-drag-placeholder{opacity:.25}@keyframes mb-grid-spin{to{transform:rotate(360deg)}}@media (max-width: 720px){.mb-grid__toolbar,.mb-grid__pager{align-items:stretch;flex-direction:column}.mb-grid__toolbar-end,.mb-grid__pager-actions{width:100%}.mb-grid__search{width:100%;min-width:0}}.mb-grid__tool-button--primary{background:var(--mb-primary, #2563eb);border-color:var(--mb-primary, #2563eb);color:#fff}.mb-grid__command-cell{width:1%;white-space:nowrap;text-align:center}.mb-grid__command{min-height:30px;margin-inline:2px;padding:0 10px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-sm, 8px);background:var(--mb-surface, #fff);color:var(--mb-text, #0f172a);cursor:pointer;font:inherit}.mb-grid__command:hover{border-color:var(--mb-primary, #2563eb);color:var(--mb-primary, #2563eb)}.mb-grid__command--danger:hover{border-color:var(--mb-danger, #dc2626);color:var(--mb-danger, #dc2626)}.mb-grid__row--editing{background:color-mix(in srgb,var(--mb-primary, #2563eb) 7%,var(--mb-surface, #fff))}.mb-grid__row--new{border-block-start:2px solid var(--mb-primary, #2563eb)}.mb-grid__editor{width:100%;min-height:34px;border:1px solid var(--mb-border, #e2e8f0);border-radius:var(--mb-radius-sm, 8px);background:var(--mb-input-bg, #fff);color:var(--mb-text, #0f172a);padding-inline:8px;font:inherit;outline:none}.mb-grid__editor:focus{border-color:var(--mb-primary, #2563eb);box-shadow:0 0 0 3px color-mix(in srgb,var(--mb-primary, #2563eb) 15%,transparent)}.mb-grid__error{display:block;margin-block-start:4px;color:var(--mb-danger, #dc2626);font-size:11px}.mb-grid__expand-button{border:0;background:transparent;cursor:pointer;font-size:16px;color:var(--mb-muted, #64748b)}.mb-grid__detail-row td{padding:14px;background:color-mix(in srgb,var(--mb-surface, #fff) 92%,var(--mb-primary, #2563eb) 8%)}\n"] }]
835
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.MbGridStateService }, { type: undefined, decorators: [{
836
+ type: Inject,
837
+ args: [MB_UI_CONFIG]
838
+ }] }, { type: undefined, decorators: [{
839
+ type: Inject,
840
+ args: [MB_GRID_MESSAGES]
841
+ }] }], propDecorators: { data: [{
842
+ type: Input
843
+ }], columns: [{
844
+ type: Input
845
+ }], loading: [{
846
+ type: Input
847
+ }], dataMode: [{
848
+ type: Input
849
+ }], state: [{
850
+ type: Input
851
+ }], total: [{
852
+ type: Input
853
+ }], height: [{
854
+ type: Input
855
+ }], rowHeight: [{
856
+ type: Input
857
+ }], density: [{
858
+ type: Input
859
+ }], locale: [{
860
+ type: Input
861
+ }], dir: [{
862
+ type: Input
863
+ }], noRecordsText: [{
864
+ type: Input
865
+ }], loadingText: [{
866
+ type: Input
867
+ }], pageable: [{
868
+ type: Input
869
+ }], pageSizeOptions: [{
870
+ type: Input
871
+ }], sortable: [{
872
+ type: Input
873
+ }], multiSort: [{
874
+ type: Input
875
+ }], filterable: [{
876
+ type: Input
877
+ }], filterMode: [{
878
+ type: Input
879
+ }], groupable: [{
880
+ type: Input
881
+ }], selectable: [{
882
+ type: Input
883
+ }], selectionMode: [{
884
+ type: Input
885
+ }], rowKey: [{
886
+ type: Input
887
+ }], selectedKeys: [{
888
+ type: Input
889
+ }], resizable: [{
890
+ type: Input
891
+ }], reorderable: [{
892
+ type: Input
893
+ }], columnMenu: [{
894
+ type: Input
895
+ }], showToolbar: [{
896
+ type: Input
897
+ }], showSearch: [{
898
+ type: Input
899
+ }], showColumnChooser: [{
900
+ type: Input
901
+ }], showExport: [{
902
+ type: Input
903
+ }], showFooter: [{
904
+ type: Input
905
+ }], virtualScroll: [{
906
+ type: Input
907
+ }], exportFileName: [{
908
+ type: Input
909
+ }], excelFileName: [{
910
+ type: Input
911
+ }], jsonFileName: [{
912
+ type: Input
913
+ }], showExcelExport: [{
914
+ type: Input
915
+ }], showJsonExport: [{
916
+ type: Input
917
+ }], persistKey: [{
918
+ type: Input
919
+ }], autoPersist: [{
920
+ type: Input
921
+ }], editable: [{
922
+ type: Input
923
+ }], editMode: [{
924
+ type: Input
925
+ }], allowAdd: [{
926
+ type: Input
927
+ }], allowDelete: [{
928
+ type: Input
929
+ }], confirmDelete: [{
930
+ type: Input
931
+ }], commandColumnTitle: [{
932
+ type: Input
933
+ }], newItemFactory: [{
934
+ type: Input
935
+ }], expandable: [{
936
+ type: Input
937
+ }], detailInitiallyExpanded: [{
938
+ type: Input
939
+ }], rowClassName: [{
940
+ type: Input
941
+ }], responsiveColumns: [{
942
+ type: Input
943
+ }], stateChange: [{
944
+ type: Output
945
+ }], pageChange: [{
946
+ type: Output
947
+ }], sortChange: [{
948
+ type: Output
949
+ }], filterChange: [{
950
+ type: Output
951
+ }], groupChange: [{
952
+ type: Output
953
+ }], selectedKeysChange: [{
954
+ type: Output
955
+ }], columnResize: [{
956
+ type: Output
957
+ }], columnReorder: [{
958
+ type: Output
959
+ }], columnVisibilityChange: [{
960
+ type: Output
961
+ }], columnLockChange: [{
962
+ type: Output
963
+ }], selectionChange: [{
964
+ type: Output
965
+ }], edit: [{
966
+ type: Output
967
+ }], save: [{
968
+ type: Output
969
+ }], cancel: [{
970
+ type: Output
971
+ }], remove: [{
972
+ type: Output
973
+ }], detailToggle: [{
974
+ type: Output
975
+ }], rowClick: [{
976
+ type: Output
977
+ }], cellClick: [{
978
+ type: Output
979
+ }], cellTemplates: [{
980
+ type: ContentChildren,
981
+ args: [MbGridCellTemplateDirective]
982
+ }], headerTemplates: [{
983
+ type: ContentChildren,
984
+ args: [MbGridHeaderTemplateDirective]
985
+ }], editTemplates: [{
986
+ type: ContentChildren,
987
+ args: [MbGridEditTemplateDirective]
988
+ }], footerTemplates: [{
989
+ type: ContentChildren,
990
+ args: [MbGridFooterTemplateDirective]
991
+ }], toolbarTemplate: [{
992
+ type: ContentChild,
993
+ args: [MbGridToolbarTemplateDirective]
994
+ }], detailTemplate: [{
995
+ type: ContentChild,
996
+ args: [MbGridDetailTemplateDirective]
997
+ }] } });
998
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWItZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2dyaWQvbWItZ3JpZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2dyaWQvbWItZ3JpZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osZUFBZSxFQUNmLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUlMLE1BQU0sR0FJUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM3RyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFlLGNBQWMsRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUErQnpELE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsa0JBQWtCLEVBQ2xCLGVBQWUsRUFDZixpQkFBaUIsRUFDakIsY0FBYyxFQUNkLGFBQWEsR0FDZCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTNFLE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IsNkJBQTZCLEVBQzdCLDJCQUEyQixFQUMzQiw2QkFBNkIsRUFDN0IsNkJBQTZCLEVBQzdCLDhCQUE4QixHQUMvQixNQUFNLDhCQUE4QixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxZQUFZLEVBQWMsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQWtCLE1B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QXNCO3NCQUEvQixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxlQUFlO3NCQUF4QixNQUFNO2dCQUNHLElBQUk7c0JBQWIsTUFBTTtnQkFDRyxJQUFJO3NCQUFiLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFFBQVE7c0JBQWpCLE1BQU07Z0JBQ0csU0FBUztzQkFBbEIsTUFBTTtnQkFFdUMsYUFBYTtzQkFBMUQsZUFBZTt1QkFBQywyQkFBMkI7Z0JBQ0ksZUFBZTtzQkFBOUQsZUFBZTt1QkFBQyw2QkFBNkI7Z0JBQ0EsYUFBYTtzQkFBMUQsZUFBZTt1QkFBQywyQkFBMkI7Z0JBQ0ksZUFBZTtzQkFBOUQsZUFBZTt1QkFBQyw2QkFBNkI7Z0JBQ0EsZUFBZTtzQkFBNUQsWUFBWTt1QkFBQyw4QkFBOEI7Z0JBQ0MsY0FBYztzQkFBMUQsWUFBWTt1QkFBQyw2QkFBNkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERlY2ltYWxQaXBlLCBLZXlWYWx1ZVBpcGUsIE5nQ2xhc3MsIE5nRm9yLCBOZ0lmLCBOZ1N0eWxlLCBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQ2RrRHJhZ0Ryb3AsIERyYWdEcm9wTW9kdWxlLCBtb3ZlSXRlbUluQXJyYXkgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcbmltcG9ydCB7IFNjcm9sbGluZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHtcbiAgTWJHcmlkQ2VsbENsaWNrRXZlbnQsXG4gIE1iR3JpZENvbHVtbixcbiAgTWJHcmlkQ29sdW1uUmVvcmRlckV2ZW50LFxuICBNYkdyaWRDb2x1bW5SZXNpemVFdmVudCxcbiAgTWJHcmlkQ29tcG9zaXRlRmlsdGVyRGVzY3JpcHRvcixcbiAgTWJHcmlkRGF0YU1vZGUsXG4gIE1iR3JpZERlbnNpdHksXG4gIE1iR3JpZEZpbHRlck1vZGUsXG4gIE1iR3JpZEZpbHRlck9wZXJhdG9yLFxuICBNYkdyaWRFZGl0TW9kZSxcbiAgTWJHcmlkRWRpdEV2ZW50LFxuICBNYkdyaWRTYXZlRXZlbnQsXG4gIE1iR3JpZENhbmNlbEV2ZW50LFxuICBNYkdyaWRSZW1vdmVFdmVudCxcbiAgTWJHcmlkU2VsZWN0aW9uQ2hhbmdlRXZlbnQsXG4gIE1iR3JpZENvbHVtblZpc2liaWxpdHlFdmVudCxcbiAgTWJHcmlkQ29sdW1uTG9ja0V2ZW50LFxuICBNYkdyaWREZXRhaWxUb2dnbGVFdmVudCxcbiAgTWJHcmlkR3JvdXBDaGFuZ2VFdmVudCxcbiAgTWJHcmlkR3JvdXBEZXNjcmlwdG9yLFxuICBNYkdyaWRQYWdlQ2hhbmdlRXZlbnQsXG4gIE1iR3JpZFByb2Nlc3NlZFJlc3VsdCxcbiAgTWJHcmlkUmVuZGVyUm93LFxuICBNYkdyaWRSb3dDbGlja0V2ZW50LFxuICBNYkdyaWRTZWxlY3Rpb25Nb2RlLFxuICBNYkdyaWRTb3J0Q2hhbmdlRXZlbnQsXG4gIE1iR3JpZFNvcnREZXNjcmlwdG9yLFxuICBNYkdyaWRTdGF0ZSxcbn0gZnJvbSAnLi9tYi1ncmlkLnR5cGVzJztcbmltcG9ydCB7XG4gIG1iR3JpZEJ1aWxkRmlsdGVyLFxuICBtYkdyaWREZWZhdWx0U3RhdGUsXG4gIG1iR3JpZEV4cG9ydENzdixcbiAgbWJHcmlkRm9ybWF0VmFsdWUsXG4gIG1iR3JpZEdldFZhbHVlLFxuICBtYkdyaWRQcm9jZXNzLFxufSBmcm9tICcuL21iLWdyaWQtZGF0YSc7XG5pbXBvcnQgeyBtYkdyaWRFeHBvcnRFeGNlbEh0bWwsIG1iR3JpZEV4cG9ydEpzb24gfSBmcm9tICcuL21iLWdyaWQtZXhwb3J0JztcbmltcG9ydCB7IE1iR3JpZFN0YXRlU2VydmljZSB9IGZyb20gJy4vbWItZ3JpZC1zdGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIE1iR3JpZENlbGxUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgTWJHcmlkRGV0YWlsVGVtcGxhdGVEaXJlY3RpdmUsXG4gIE1iR3JpZEVkaXRUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgTWJHcmlkRm9vdGVyVGVtcGxhdGVEaXJlY3RpdmUsXG4gIE1iR3JpZEhlYWRlclRlbXBsYXRlRGlyZWN0aXZlLFxuICBNYkdyaWRUb29sYmFyVGVtcGxhdGVEaXJlY3RpdmUsXG59IGZyb20gJy4vbWItZ3JpZC10ZW1wbGF0ZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTUJfVUlfQ09ORklHLCBNYlVpQ29uZmlnIH0gZnJvbSAnLi4vdG9rZW5zL21iLXVpLWNvbmZpZy50b2tlbic7XG5pbXBvcnQgeyBNQl9HUklEX01FU1NBR0VTLCBNYkdyaWRNZXNzYWdlcyB9IGZyb20gJy4vbWItZ3JpZC1tZXNzYWdlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ21iLWdyaWQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbTmdJZiwgTmdGb3IsIE5nQ2xhc3MsIE5nU3R5bGUsIE5nVGVtcGxhdGVPdXRsZXQsIERlY2ltYWxQaXBlLCBLZXlWYWx1ZVBpcGUsIEZvcm1zTW9kdWxlLCBEcmFnRHJvcE1vZHVsZSwgU2Nyb2xsaW5nTW9kdWxlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL21iLWdyaWQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vbWItZ3JpZC5jb21wb25lbnQuc2NzcycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBNYkdyaWRDb21wb25lbnQ8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBSZWNvcmQ8c3RyaW5nLCBhbnk+PiBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBkYXRhOiBUW10gPSBbXTtcbiAgQElucHV0KCkgY29sdW1uczogTWJHcmlkQ29sdW1uPFQ+W10gPSBbXTtcbiAgQElucHV0KCkgbG9hZGluZyA9IGZhbHNlO1xuICBASW5wdXQoKSBkYXRhTW9kZTogTWJHcmlkRGF0YU1vZGUgPSAnY2xpZW50JztcbiAgQElucHV0KCkgc3RhdGU6IE1iR3JpZFN0YXRlPFQ+ID0gbWJHcmlkRGVmYXVsdFN0YXRlPFQ+KCk7XG4gIEBJbnB1dCgpIHRvdGFsID0gMDtcbiAgQElucHV0KCkgaGVpZ2h0OiBudW1iZXIgfCBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgcm93SGVpZ2h0ID0gNDQ7XG4gIEBJbnB1dCgpIGRlbnNpdHk6IE1iR3JpZERlbnNpdHkgPSAnY29tZm9ydGFibGUnO1xuICBASW5wdXQoKSBsb2NhbGU/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGRpcj86ICdydGwnIHwgJ2x0cic7XG4gIEBJbnB1dCgpIG5vUmVjb3Jkc1RleHQ/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGxvYWRpbmdUZXh0Pzogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHBhZ2VhYmxlID0gdHJ1ZTtcbiAgQElucHV0KCkgcGFnZVNpemVPcHRpb25zOiBudW1iZXJbXSA9IFsxMCwgMjAsIDUwLCAxMDBdO1xuICBASW5wdXQoKSBzb3J0YWJsZSA9IHRydWU7XG4gIEBJbnB1dCgpIG11bHRpU29ydCA9IGZhbHNlO1xuICBASW5wdXQoKSBmaWx0ZXJhYmxlID0gdHJ1ZTtcbiAgQElucHV0KCkgZmlsdGVyTW9kZTogTWJHcmlkRmlsdGVyTW9kZSA9ICdyb3cnO1xuICBASW5wdXQoKSBncm91cGFibGUgPSBmYWxzZTtcbiAgQElucHV0KCkgc2VsZWN0YWJsZSA9IGZhbHNlO1xuICBASW5wdXQoKSBzZWxlY3Rpb25Nb2RlOiBNYkdyaWRTZWxlY3Rpb25Nb2RlID0gJ211bHRpcGxlJztcbiAgQElucHV0KCkgcm93S2V5OiBrZXlvZiBUIHwgc3RyaW5nIHwgKChyb3c6IFQpID0+IHN0cmluZyB8IG51bWJlcikgPSAnaWQnO1xuICBASW5wdXQoKSBzZWxlY3RlZEtleXM6IEFycmF5PHN0cmluZyB8IG51bWJlcj4gPSBbXTtcbiAgQElucHV0KCkgcmVzaXphYmxlID0gdHJ1ZTtcbiAgQElucHV0KCkgcmVvcmRlcmFibGUgPSB0cnVlO1xuICBASW5wdXQoKSBjb2x1bW5NZW51ID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd1Rvb2xiYXIgPSB0cnVlO1xuICBASW5wdXQoKSBzaG93U2VhcmNoID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd0NvbHVtbkNob29zZXIgPSB0cnVlO1xuICBASW5wdXQoKSBzaG93RXhwb3J0ID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd0Zvb3RlciA9IGZhbHNlO1xuICBASW5wdXQoKSB2aXJ0dWFsU2Nyb2xsID0gZmFsc2U7XG4gIEBJbnB1dCgpIGV4cG9ydEZpbGVOYW1lID0gJ21iLWdyaWQtZXhwb3J0LmNzdic7XG4gIEBJbnB1dCgpIGV4Y2VsRmlsZU5hbWUgPSAnbWItZ3JpZC1leHBvcnQueGxzJztcbiAgQElucHV0KCkganNvbkZpbGVOYW1lID0gJ21iLWdyaWQtZXhwb3J0Lmpzb24nO1xuICBASW5wdXQoKSBzaG93RXhjZWxFeHBvcnQgPSB0cnVlO1xuICBASW5wdXQoKSBzaG93SnNvbkV4cG9ydCA9IHRydWU7XG4gIEBJbnB1dCgpIHBlcnNpc3RLZXkgPSAnJztcbiAgQElucHV0KCkgYXV0b1BlcnNpc3QgPSBmYWxzZTtcbiAgQElucHV0KCkgZWRpdGFibGUgPSBmYWxzZTtcbiAgQElucHV0KCkgZWRpdE1vZGU6IE1iR3JpZEVkaXRNb2RlID0gJ2lubGluZSc7XG4gIEBJbnB1dCgpIGFsbG93QWRkID0gZmFsc2U7XG4gIEBJbnB1dCgpIGFsbG93RGVsZXRlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNvbmZpcm1EZWxldGUgPSBmYWxzZTtcbiAgQElucHV0KCkgY29tbWFuZENvbHVtblRpdGxlPzogc3RyaW5nO1xuICBASW5wdXQoKSBuZXdJdGVtRmFjdG9yeT86ICgpID0+IFQ7XG4gIEBJbnB1dCgpIGV4cGFuZGFibGUgPSBmYWxzZTtcbiAgQElucHV0KCkgZGV0YWlsSW5pdGlhbGx5RXhwYW5kZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgcm93Q2xhc3NOYW1lPzogc3RyaW5nIHwgKChyb3c6IFQsIHJvd0luZGV4OiBudW1iZXIpID0+IHN0cmluZyB8IHN0cmluZ1tdIHwgUmVjb3JkPHN0cmluZywgYm9vbGVhbj4pO1xuICBASW5wdXQoKSByZXNwb25zaXZlQ29sdW1ucyA9IHRydWU7XG5cbiAgQE91dHB1dCgpIHN0YXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxNYkdyaWRTdGF0ZTxUPj4oKTtcbiAgQE91dHB1dCgpIHBhZ2VDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE1iR3JpZFBhZ2VDaGFuZ2VFdmVudD4oKTtcbiAgQE91dHB1dCgpIHNvcnRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE1iR3JpZFNvcnRDaGFuZ2VFdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIGZpbHRlckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBmaWx0ZXI/OiBNYkdyaWRDb21wb3NpdGVGaWx0ZXJEZXNjcmlwdG9yPFQ+IH0+KCk7XG4gIEBPdXRwdXQoKSBncm91cENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8TWJHcmlkR3JvdXBDaGFuZ2VFdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIHNlbGVjdGVkS2V5c0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8QXJyYXk8c3RyaW5nIHwgbnVtYmVyPj4oKTtcbiAgQE91dHB1dCgpIGNvbHVtblJlc2l6ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TWJHcmlkQ29sdW1uUmVzaXplRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBjb2x1bW5SZW9yZGVyID0gbmV3IEV2ZW50RW1pdHRlcjxNYkdyaWRDb2x1bW5SZW9yZGVyRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBjb2x1bW5WaXNpYmlsaXR5Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxNYkdyaWRDb2x1bW5WaXNpYmlsaXR5RXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBjb2x1bW5Mb2NrQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxNYkdyaWRDb2x1bW5Mb2NrRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBzZWxlY3Rpb25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE1iR3JpZFNlbGVjdGlvbkNoYW5nZUV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgZWRpdCA9IG5ldyBFdmVudEVtaXR0ZXI8TWJHcmlkRWRpdEV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgc2F2ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TWJHcmlkU2F2ZUV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgY2FuY2VsID0gbmV3IEV2ZW50RW1pdHRlcjxNYkdyaWRDYW5jZWxFdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIHJlbW92ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TWJHcmlkUmVtb3ZlRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBkZXRhaWxUb2dnbGUgPSBuZXcgRXZlbnRFbWl0dGVyPE1iR3JpZERldGFpbFRvZ2dsZUV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgcm93Q2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPE1iR3JpZFJvd0NsaWNrRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBjZWxsQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPE1iR3JpZENlbGxDbGlja0V2ZW50PFQ+PigpO1xuXG4gIEBDb250ZW50Q2hpbGRyZW4oTWJHcmlkQ2VsbFRlbXBsYXRlRGlyZWN0aXZlKSBjZWxsVGVtcGxhdGVzPzogUXVlcnlMaXN0PE1iR3JpZENlbGxUZW1wbGF0ZURpcmVjdGl2ZTxUPj47XG4gIEBDb250ZW50Q2hpbGRyZW4oTWJHcmlkSGVhZGVyVGVtcGxhdGVEaXJlY3RpdmUpIGhlYWRlclRlbXBsYXRlcz86IFF1ZXJ5TGlzdDxNYkdyaWRIZWFkZXJUZW1wbGF0ZURpcmVjdGl2ZTxUPj47XG4gIEBDb250ZW50Q2hpbGRyZW4oTWJHcmlkRWRpdFRlbXBsYXRlRGlyZWN0aXZlKSBlZGl0VGVtcGxhdGVzPzogUXVlcnlMaXN0PE1iR3JpZEVkaXRUZW1wbGF0ZURpcmVjdGl2ZTxUPj47XG4gIEBDb250ZW50Q2hpbGRyZW4oTWJHcmlkRm9vdGVyVGVtcGxhdGVEaXJlY3RpdmUpIGZvb3RlclRlbXBsYXRlcz86IFF1ZXJ5TGlzdDxNYkdyaWRGb290ZXJUZW1wbGF0ZURpcmVjdGl2ZTxUPj47XG4gIEBDb250ZW50Q2hpbGQoTWJHcmlkVG9vbGJhclRlbXBsYXRlRGlyZWN0aXZlKSB0b29sYmFyVGVtcGxhdGU/OiBNYkdyaWRUb29sYmFyVGVtcGxhdGVEaXJlY3RpdmU8VD47XG4gIEBDb250ZW50Q2hpbGQoTWJHcmlkRGV0YWlsVGVtcGxhdGVEaXJlY3RpdmUpIGRldGFpbFRlbXBsYXRlPzogTWJHcmlkRGV0YWlsVGVtcGxhdGVEaXJlY3RpdmU8VD47XG5cbiAgcHJvY2Vzc2VkOiBNYkdyaWRQcm9jZXNzZWRSZXN1bHQ8VD4gPSB7IGRhdGE6IFtdLCB0b3RhbDogMCwgYWdncmVnYXRlczoge30gfTtcbiAgaW50ZXJuYWxDb2x1bW5zOiBNYkdyaWRDb2x1bW48VD5bXSA9IFtdO1xuICBnbG9iYWxTZWFyY2ggPSAnJztcbiAgZmlsdGVyc0J5RmllbGQ6IFJlY29yZDxzdHJpbmcsIHsgb3BlcmF0b3I6IE1iR3JpZEZpbHRlck9wZXJhdG9yOyB2YWx1ZTogdW5rbm93biB9PiA9IHt9O1xuICBvcGVuQ29sdW1uTWVudUZpZWxkID0gJyc7XG4gIHJlc2l6aW5nPzogeyBmaWVsZDogc3RyaW5nOyBzdGFydFg6IG51bWJlcjsgc3RhcnRXaWR0aDogbnVtYmVyIH07XG4gIGV4cGFuZGVkR3JvdXBLZXlzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGV4cGFuZGVkRGV0YWlsS2V5cyA9IG5ldyBTZXQ8c3RyaW5nIHwgbnVtYmVyPigpO1xuICBlZGl0aW5nS2V5OiBzdHJpbmcgfCBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgZWRpdGluZ01vZGVsOiBUIHwgbnVsbCA9IG51bGw7XG4gIG9yaWdpbmFsTW9kZWw6IFQgfCBudWxsID0gbnVsbDtcbiAgZWRpdGluZ1Jvd0luZGV4ID0gLTE7XG4gIGVkaXRpbmdJc05ldyA9IGZhbHNlO1xuICB2YWxpZGF0aW9uRXJyb3JzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIHByaXZhdGUgcmVhZG9ubHkgbWVkaWFRdWVyeUxpc3RzID0gbmV3IE1hcDxzdHJpbmcsIE1lZGlhUXVlcnlMaXN0PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG1lZGlhTGlzdGVuZXJzID0gbmV3IE1hcDxzdHJpbmcsIChldmVudDogTWVkaWFRdWVyeUxpc3RFdmVudCkgPT4gdm9pZD4oKTtcblxuICByZWFkb25seSB0ZXh0T3BlcmF0b3JzOiBNYkdyaWRGaWx0ZXJPcGVyYXRvcltdID0gWydjb250YWlucycsICdkb2VzTm90Q29udGFpbicsICdzdGFydHNXaXRoJywgJ2VuZHNXaXRoJywgJ2VxJywgJ25lcScsICdpc0VtcHR5JywgJ2lzTm90RW1wdHknXTtcbiAgcmVhZG9ubHkgbnVtZXJpY09wZXJhdG9yczogTWJHcmlkRmlsdGVyT3BlcmF0b3JbXSA9IFsnZXEnLCAnbmVxJywgJ2d0JywgJ2d0ZScsICdsdCcsICdsdGUnLCAnYmV0d2VlbicsICdpc051bGwnLCAnaXNOb3ROdWxsJ107XG4gIHJlYWRvbmx5IGJvb2xlYW5PcGVyYXRvcnM6IE1iR3JpZEZpbHRlck9wZXJhdG9yW10gPSBbJ2VxJywgJ25lcSddO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0YXRlU3RvcmU6IE1iR3JpZFN0YXRlU2VydmljZSxcbiAgICBASW5qZWN0KE1CX1VJX0NPTkZJRykgcHJpdmF0ZSByZWFkb25seSB1aUNvbmZpZzogTWJVaUNvbmZpZyxcbiAgICBASW5qZWN0KE1CX0dSSURfTUVTU0FHRVMpIHJlYWRvbmx5IG1lc3NhZ2VzOiBNYkdyaWRNZXNzYWdlcyxcbiAgKSB7fVxuXG4gIGdldCBlZmZlY3RpdmVMb2NhbGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5sb2NhbGUgPz8gdGhpcy51aUNvbmZpZy5sb2NhbGU7XG4gIH1cblxuICBnZXQgZWZmZWN0aXZlRGlyKCk6ICdydGwnIHwgJ2x0cicge1xuICAgIHJldHVybiB0aGlzLmRpciA/PyB0aGlzLnVpQ29uZmlnLmRpcmVjdGlvbjtcbiAgfVxuXG4gIGdldCBlZmZlY3RpdmVDb21tYW5kQ29sdW1uVGl0bGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kQ29sdW1uVGl0bGUgPz8gdGhpcy5tZXNzYWdlcy5jb21tYW5kQ29sdW1uO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgZm9ybWF0T3B0aW9ucygpIHtcbiAgICByZXR1cm4geyBsb2NhbGU6IHRoaXMuZWZmZWN0aXZlTG9jYWxlLCB5ZXM6IHRoaXMubWVzc2FnZXMueWVzLCBubzogdGhpcy5tZXNzYWdlcy5ubyB9O1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zeW5jTWVkaWFRdWVyaWVzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IFtxdWVyeSwgbGlzdGVuZXJdIG9mIHRoaXMubWVkaWFMaXN0ZW5lcnMpIHtcbiAgICAgIHRoaXMubWVkaWFRdWVyeUxpc3RzLmdldChxdWVyeSk/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGxpc3RlbmVyKTtcbiAgICB9XG4gICAgdGhpcy5tZWRpYUxpc3RlbmVycy5jbGVhcigpO1xuICAgIHRoaXMubWVkaWFRdWVyeUxpc3RzLmNsZWFyKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ2NvbHVtbnMnXSkge1xuICAgICAgdGhpcy5pbnRlcm5hbENvbHVtbnMgPSAodGhpcy5jb2x1bW5zID8/IFtdKS5tYXAoKGNvbHVtbikgPT4gKHtcbiAgICAgICAgc29ydGFibGU6IHRydWUsXG4gICAgICAgIGZpbHRlcmFibGU6IHRydWUsXG4gICAgICAgIGdyb3VwYWJsZTogdHJ1ZSxcbiAgICAgICAgcmVzaXphYmxlOiB0cnVlLFxuICAgICAgICByZW9yZGVyYWJsZTogdHJ1ZSxcbiAgICAgICAgbWVudTogdHJ1ZSxcbiAgICAgICAgZXhwb3J0YWJsZTogdHJ1ZSxcbiAgICAgICAgLi4uY29sdW1uLFxuICAgICAgfSkpO1xuICAgICAgdGhpcy5hcHBseVByb2plY3RlZFRlbXBsYXRlcygpO1xuICAgICAgdGhpcy5lbnN1cmVGaWx0ZXJEZWZhdWx0cygpO1xuICAgICAgdGhpcy5yZXN0b3JlUGVyc2lzdGVkU3RhdGUoKTtcbiAgICAgIHRoaXMuc3luY01lZGlhUXVlcmllcygpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snc3RhdGUnXSAmJiAhdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IG1iR3JpZERlZmF1bHRTdGF0ZTxUPigpO1xuICAgIH1cbiAgICB0aGlzLnJlcHJvY2VzcygpO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuYXBwbHlQcm9qZWN0ZWRUZW1wbGF0ZXMoKTtcbiAgICB0aGlzLmNlbGxUZW1wbGF0ZXM/LmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHRoaXMuYXBwbHlQcm9qZWN0ZWRUZW1wbGF0ZXMoKSk7XG4gICAgdGhpcy5oZWFkZXJUZW1wbGF0ZXM/LmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHRoaXMuYXBwbHlQcm9qZWN0ZWRUZW1wbGF0ZXMoKSk7XG4gICAgdGhpcy5lZGl0VGVtcGxhdGVzPy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB0aGlzLmFwcGx5UHJvamVjdGVkVGVtcGxhdGVzKCkpO1xuICAgIHRoaXMuZm9vdGVyVGVtcGxhdGVzPy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB0aGlzLmFwcGx5UHJvamVjdGVkVGVtcGxhdGVzKCkpO1xuICAgIHRoaXMucmVwcm9jZXNzKCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBnZXQgdmlzaWJsZUNvbHVtbnMoKTogTWJHcmlkQ29sdW1uPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLmludGVybmFsQ29sdW1ucy5maWx0ZXIoKGNvbHVtbikgPT4gIWNvbHVtbi5oaWRkZW4gJiYgdGhpcy5tYXRjaGVzTWVkaWEoY29sdW1uKSk7XG4gIH1cblxuICBnZXQgbG9ja2VkU3RhcnRDb2x1bW5zKCk6IE1iR3JpZENvbHVtbjxUPltdIHtcbiAgICByZXR1cm4gdGhpcy52aXNpYmxlQ29sdW1ucy5maWx0ZXIoKGNvbHVtbikgPT4gdGhpcy5pc0xvY2tlZFN0YXJ0KGNvbHVtbikpO1xuICB9XG5cbiAgZ2V0IGxvY2tlZEVuZENvbHVtbnMoKTogTWJHcmlkQ29sdW1uPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLnZpc2libGVDb2x1bW5zLmZpbHRlcigoY29sdW1uKSA9PiB0aGlzLmlzTG9ja2VkRW5kKGNvbHVtbikpO1xuICB9XG5cbiAgZ2V0IGhhc0ZpbHRlclJvdygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJhYmxlICYmICh0aGlzLmZpbHRlck1vZGUgPT09ICdyb3cnIHx8IHRoaXMuZmlsdGVyTW9kZSA9PT0gJ2JvdGgnKTtcbiAgfVxuXG4gIGdldCBoYXNDb2x1bW5NZW51KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbHVtbk1lbnUgJiYgKHRoaXMuZmlsdGVyTW9kZSA9PT0gJ21lbnUnIHx8IHRoaXMuZmlsdGVyTW9kZSA9PT0gJ2JvdGgnIHx8IHRoaXMuc2hvd0NvbHVtbkNob29zZXIgfHwgdGhpcy5ncm91cGFibGUpO1xuICB9XG5cbiAgZ2V0IHBhZ2VJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLmZsb29yKCh0aGlzLnN0YXRlPy5za2lwID8/IDApIC8gKHRoaXMuc3RhdGU/LnRha2UgfHwgMSkpO1xuICB9XG5cbiAgZ2V0IHBhZ2VTaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGU/LnRha2UgPz8gMTA7XG4gIH1cblxuICBnZXQgZWZmZWN0aXZlVG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhTW9kZSA9PT0gJ3NlcnZlcicgPyB0aGlzLnRvdGFsIDogdGhpcy5wcm9jZXNzZWQudG90YWw7XG4gIH1cblxuICBnZXQgcGFnZUNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDEsIE1hdGguY2VpbCh0aGlzLmVmZmVjdGl2ZVRvdGFsIC8gdGhpcy5wYWdlU2l6ZSkpO1xuICB9XG5cbiAgZ2V0IGZyb20oKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuZWZmZWN0aXZlVG90YWwpIHJldHVybiAwO1xuICAgIHJldHVybiB0aGlzLnBhZ2VJbmRleCAqIHRoaXMucGFnZVNpemUgKyAxO1xuICB9XG5cbiAgZ2V0IHRvKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgubWluKCh0aGlzLnBhZ2VJbmRleCArIDEpICogdGhpcy5wYWdlU2l6ZSwgdGhpcy5lZmZlY3RpdmVUb3RhbCk7XG4gIH1cblxuICBnZXQgZ3JpZFN0eWxlKCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bGw+IHtcbiAgICByZXR1cm4geyBoZWlnaHQ6IHR5cGVvZiB0aGlzLmhlaWdodCA9PT0gJ251bWJlcicgPyBgJHt0aGlzLmhlaWdodH1weGAgOiB0aGlzLmhlaWdodCB9O1xuICB9XG5cbiAgZ2V0IGFsbFZpc2libGVSb3dzU2VsZWN0ZWQoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGF0YVJvd3MgPSB0aGlzLmRhdGFSb3dzRnJvbVJlbmRlcmVkKCk7XG4gICAgcmV0dXJuIGRhdGFSb3dzLmxlbmd0aCA+IDAgJiYgZGF0YVJvd3MuZXZlcnkoKHJvdykgPT4gdGhpcy5zZWxlY3RlZEtleXMuaW5jbHVkZXModGhpcy5nZXRSb3dLZXkocm93KSkpO1xuICB9XG5cbiAgZ2V0IHNvbWVWaXNpYmxlUm93c1NlbGVjdGVkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRhdGFSb3dzID0gdGhpcy5kYXRhUm93c0Zyb21SZW5kZXJlZCgpO1xuICAgIHJldHVybiBkYXRhUm93cy5zb21lKChyb3cpID0+IHRoaXMuc2VsZWN0ZWRLZXlzLmluY2x1ZGVzKHRoaXMuZ2V0Um93S2V5KHJvdykpKSAmJiAhdGhpcy5hbGxWaXNpYmxlUm93c1NlbGVjdGVkO1xuICB9XG5cbiAgZ2V0IHRvb2xiYXJDb250ZXh0KCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0ZTogdGhpcy5zdGF0ZSxcbiAgICAgIHRvdGFsOiB0aGlzLmVmZmVjdGl2ZVRvdGFsLFxuICAgICAgc2VsZWN0ZWRLZXlzOiB0aGlzLnNlbGVjdGVkS2V5cyxcbiAgICAgIHNlbGVjdGVkUm93czogdGhpcy5zZWxlY3RlZFJvd3MsXG4gICAgICBhZGQ6ICgpID0+IHRoaXMuY3JlYXRlUm93KCksXG4gICAgICBleHBvcnRDc3Y6ICgpID0+IHRoaXMuZXhwb3J0Q3N2KCksXG4gICAgICBleHBvcnRFeGNlbDogKCkgPT4gdGhpcy5leHBvcnRFeGNlbCgpLFxuICAgICAgcmVzZXQ6ICgpID0+IHRoaXMucmVzZXRTdGF0ZSgpLFxuICAgIH07XG4gIH1cblxuICBnZXQgc2VsZWN0ZWRSb3dzKCk6IFRbXSB7XG4gICAgY29uc3QgYWxsUm93cyA9IHRoaXMuZGF0YSA/PyBbXTtcbiAgICByZXR1cm4gYWxsUm93cy5maWx0ZXIoKHJvdykgPT4gdGhpcy5zZWxlY3RlZEtleXMuaW5jbHVkZXModGhpcy5nZXRSb3dLZXkocm93KSkpO1xuICB9XG5cbiAgZ2V0IGNvbHVtblNwYW4oKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy52aXNpYmxlQ29sdW1ucy5sZW5ndGggKyAodGhpcy5zZWxlY3RhYmxlID8gMSA6IDApICsgKHRoaXMuZXhwYW5kYWJsZSA/IDEgOiAwKSArICh0aGlzLnNob3dDb21tYW5kQ29sdW1uID8gMSA6IDApO1xuICB9XG5cbiAgZ2V0IHNob3dDb21tYW5kQ29sdW1uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVkaXRhYmxlIHx8IHRoaXMuYWxsb3dEZWxldGU7XG4gIH1cblxuICBnZXRPcGVyYXRvckxhYmVsKG9wZXJhdG9yOiBNYkdyaWRGaWx0ZXJPcGVyYXRvcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZXMub3BlcmF0b3JMYWJlbHNbb3BlcmF0b3JdID8/IG9wZXJhdG9yO1xuICB9XG5cbiAgZ2V0T3BlcmF0b3JzKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogTWJHcmlkRmlsdGVyT3BlcmF0b3JbXSB7XG4gICAgaWYgKGNvbHVtbi50eXBlID09PSAnbnVtYmVyJyB8fCBjb2x1bW4udHlwZSA9PT0gJ2RhdGUnKSByZXR1cm4gdGhpcy5udW1lcmljT3BlcmF0b3JzO1xuICAgIGlmIChjb2x1bW4udHlwZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gdGhpcy5ib29sZWFuT3BlcmF0b3JzO1xuICAgIHJldHVybiB0aGlzLnRleHRPcGVyYXRvcnM7XG4gIH1cblxuXG4gIGdldENvbHVtblN0eWxlKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IGxvY2tlZFN0YXJ0ID0gdGhpcy5pc0xvY2tlZFN0YXJ0KGNvbHVtbik7XG4gICAgY29uc3QgbG9ja2VkRW5kID0gdGhpcy5pc0xvY2tlZEVuZChjb2x1bW4pO1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogdGhpcy50b0Nzc1NpemUoY29sdW1uLndpZHRoKSxcbiAgICAgIG1pbldpZHRoOiB0aGlzLnRvQ3NzU2l6ZShjb2x1bW4ubWluV2lkdGgpLFxuICAgICAgbWF4V2lkdGg6IHRoaXMudG9Dc3NTaXplKGNvbHVtbi5tYXhXaWR0aCksXG4gICAgICBwb3NpdGlvbjogbG9ja2VkU3RhcnQgfHwgbG9ja2VkRW5kID8gJ3N0aWNreScgOiBudWxsLFxuICAgICAgaW5zZXRJbmxpbmVTdGFydDogbG9ja2VkU3RhcnQgPyBgJHt0aGlzLmdldExvY2tlZE9mZnNldChjb2x1bW4sICdzdGFydCcpfXB4YCA6IG51bGwsXG4gICAgICBpbnNldElubGluZUVuZDogbG9ja2VkRW5kID8gYCR7dGhpcy5nZXRMb2NrZWRPZmZzZXQoY29sdW1uLCAnZW5kJyl9cHhgIDogbnVsbCxcbiAgICAgIHpJbmRleDogbG9ja2VkU3RhcnQgfHwgbG9ja2VkRW5kID8gJzYnIDogbnVsbCxcbiAgICB9O1xuICB9XG5cbiAgZ2V0Q29sdW1uQ2xhc3MoY29sdW1uOiBNYkdyaWRDb2x1bW48VD4pOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdtYi1ncmlkX19jZWxsLS1sb2NrZWQtc3RhcnQnOiB0aGlzLmlzTG9ja2VkU3RhcnQoY29sdW1uKSxcbiAgICAgICdtYi1ncmlkX19jZWxsLS1sb2NrZWQtZW5kJzogdGhpcy5pc0xvY2tlZEVuZChjb2x1bW4pLFxuICAgIH07XG4gIH1cblxuICBpc0xvY2tlZFN0YXJ0KGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhY29sdW1uLmxvY2tlZCB8fCBjb2x1bW4uc3RpY2t5ID09PSAnc3RhcnQnO1xuICB9XG5cbiAgaXNMb2NrZWRFbmQoY29sdW1uOiBNYkdyaWRDb2x1bW48VD4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gY29sdW1uLnN0aWNreSA9PT0gJ2VuZCc7XG4gIH1cblxuICBtYXRjaGVzTWVkaWEoY29sdW1uOiBNYkdyaWRDb2x1bW48VD4pOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMucmVzcG9uc2l2ZUNvbHVtbnMgfHwgIWNvbHVtbi5tZWRpYSB8fCB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLm1lZGlhUXVlcnlMaXN0cy5nZXQoY29sdW1uLm1lZGlhKT8ubWF0Y2hlcyA/PyB0cnVlO1xuICB9XG5cbiAgcGFnZXJJbmZvVGV4dCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm1lc3NhZ2VzLnBhZ2VySW5mbyh0aGlzLmZyb20sIHRoaXMudG8sIHRoaXMuZWZmZWN0aXZlVG90YWwpO1xuICB9XG5cbiAgZ2V0U29ydEluZGV4KGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMuc3RhdGUuc29ydCA/PyBbXSkuZmluZEluZGV4KChpdGVtKSA9PiBTdHJpbmcoaXRlbS5maWVsZCkgPT09IFN0cmluZyhjb2x1bW4uZmllbGQpKTtcbiAgfVxuXG4gIGdldFNvcnREaXJlY3Rpb24oY29sdW1uOiBNYkdyaWRDb2x1bW48VD4pOiAnJyB8ICdhc2MnIHwgJ2Rlc2MnIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5zb3J0Py5maW5kKChpdGVtKSA9PiBTdHJpbmcoaXRlbS5maWVsZCkgPT09IFN0cmluZyhjb2x1bW4uZmllbGQpKT8uZGlyID8/ICcnO1xuICB9XG5cbiAgZ2V0VmFsdWUocm93OiBULCBjb2x1bW46IE1iR3JpZENvbHVtbjxUPiwgcm93SW5kZXggPSAtMSk6IHVua25vd24ge1xuICAgIHJldHVybiBjb2x1bW4udmFsdWVHZXR0ZXIgPyBjb2x1bW4udmFsdWVHZXR0ZXIocm93LCByb3dJbmRleCkgOiBtYkdyaWRHZXRWYWx1ZShyb3csIGNvbHVtbi5maWVsZCk7XG4gIH1cblxuICBmb3JtYXRDZWxsKHJvdzogVCwgY29sdW1uOiBNYkdyaWRDb2x1bW48VD4sIHJvd0luZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBtYkdyaWRGb3JtYXRWYWx1ZShyb3csIGNvbHVtbiwgcm93SW5kZXgsIHRoaXMuZm9ybWF0T3B0aW9ucyk7XG4gIH1cblxuXG4gIGdldENlbGxDbGFzcyhyb3c6IFQsIGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+LCByb3dJbmRleDogbnVtYmVyKTogc3RyaW5nIHwgc3RyaW5nW10gfCBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiB8IG51bGwge1xuICAgIGlmICghY29sdW1uLmNsYXNzTmFtZSkgcmV0dXJuIG51bGw7XG4gICAgaWYgKHR5cGVvZiBjb2x1bW4uY2xhc3NOYW1lID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gY29sdW1uLmNsYXNzTmFtZShyb3csIHRoaXMuZ2V0VmFsdWUocm93LCBjb2x1bW4sIHJvd0luZGV4KSwgcm93SW5kZXgpIGFzIGFueTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbHVtbi5jbGFzc05hbWUgYXMgYW55O1xuICB9XG5cbiAgZ2V0Q2VsbFRlbXBsYXRlKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwge1xuICAgIHJldHVybiBjb2x1bW4uY2VsbFRlbXBsYXRlID8/IG51bGw7XG4gIH1cblxuICBnZXRIZWFkZXJUZW1wbGF0ZShjb2x1bW46IE1iR3JpZENvbHVtbjxUPik6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsIHtcbiAgICByZXR1cm4gY29sdW1uLmhlYWRlclRlbXBsYXRlID8/IG51bGw7XG4gIH1cblxuICBnZXRGb290ZXJUZW1wbGF0ZShjb2x1bW46IE1iR3JpZENvbHVtbjxUPik6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsIHtcbiAgICByZXR1cm4gY29sdW1uLmZvb3RlclRlbXBsYXRlID8/IG51bGw7XG4gIH1cblxuICBnZXRSb3dLZXkocm93OiBUKTogc3RyaW5nIHwgbnVtYmVyIHtcbiAgICBpZiAodHlwZW9mIHRoaXMucm93S2V5ID09PSAnZnVuY3Rpb24nKSByZXR1cm4gdGhpcy5yb3dLZXkocm93KTtcbiAgICByZXR1cm4gbWJHcmlkR2V0VmFsdWUocm93LCB0aGlzLnJvd0tleSkgYXMgc3RyaW5nIHwgbnVtYmVyO1xuICB9XG5cbiAgdG9nZ2xlU29ydChjb2x1bW46IE1iR3JpZENvbHVtbjxUPiwgZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNvcnRhYmxlIHx8IGNvbHVtbi5zb3J0YWJsZSA9PT0gZmFsc2UpIHJldHVybjtcbiAgICBjb25zdCBmaWVsZCA9IFN0cmluZyhjb2x1bW4uZmllbGQpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBbLi4uKHRoaXMuc3RhdGUuc29ydCA/PyBbXSldO1xuICAgIGNvbnN0IGluZGV4ID0gY3VycmVudC5maW5kSW5kZXgoKGl0ZW0pID0+IFN0cmluZyhpdGVtLmZpZWxkKSA9PT0gZmllbGQpO1xuICAgIGNvbnN0IGlzTXVsdGkgPSB0aGlzLm11bHRpU29ydCAmJiAhIWV2ZW50Py5zaGlmdEtleTtcbiAgICBjb25zdCBiYXNlID0gaXNNdWx0aSA/IGN1cnJlbnQgOiBpbmRleCA+PSAwID8gW2N1cnJlbnRbaW5kZXhdXSA6IFtdO1xuICAgIGNvbnN0IHRhcmdldEluZGV4ID0gYmFzZS5maW5kSW5kZXgoKGl0ZW0pID0+IFN0cmluZyhpdGVtLmZpZWxkKSA9PT0gZmllbGQpO1xuXG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCkge1xuICAgICAgYmFzZS5wdXNoKHsgZmllbGQ6IGNvbHVtbi5maWVsZCwgZGlyOiAnYXNjJyB9KTtcbiAgICB9IGVsc2UgaWYgKGJhc2VbdGFyZ2V0SW5kZXhdLmRpciA9PT0gJ2FzYycpIHtcbiAgICAgIGJhc2VbdGFyZ2V0SW5kZXhdID0geyAuLi5iYXNlW3RhcmdldEluZGV4XSwgZGlyOiAnZGVzYycgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgYmFzZS5zcGxpY2UodGFyZ2V0SW5kZXgsIDEpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLnN0YXRlLCBzb3J0OiBiYXNlLCBza2lwOiAwIH0pO1xuICAgIHRoaXMuc29ydENoYW5nZS5lbWl0KHsgc29ydDogYmFzZSB9KTtcbiAgfVxuXG4gIHNldEZpbHRlclZhbHVlKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+LCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIGNvbnN0IGZpZWxkID0gU3RyaW5nKGNvbHVtbi5maWVsZCk7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuZmlsdGVyc0J5RmllbGRbZmllbGRdID8/IHsgb3BlcmF0b3I6IHRoaXMuZGVmYXVsdE9wZXJhdG9yKGNvbHVtbiksIHZhbHVlOiAnJyB9O1xuICAgIHRoaXMuZmlsdGVyc0J5RmllbGQgPSB7IC4uLnRoaXMuZmlsdGVyc0J5RmllbGQsIFtmaWVsZF06IHsgLi4uY3VycmVudCwgdmFsdWUgfSB9O1xuICAgIHRoaXMuYXBwbHlGaWx0ZXJzKCk7XG4gIH1cblxuICBzZXRGaWx0ZXJPcGVyYXRvcihjb2x1bW46IE1iR3JpZENvbHVtbjxUPiwgb3BlcmF0b3I6IE1iR3JpZEZpbHRlck9wZXJhdG9yKTogdm9pZCB7XG4gICAgY29uc3QgZmllbGQgPSBTdHJpbmcoY29sdW1uLmZpZWxkKTtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5maWx0ZXJzQnlGaWVsZFtmaWVsZF0gPz8geyBvcGVyYXRvciwgdmFsdWU6ICcnIH07XG4gICAgdGhpcy5maWx0ZXJzQnlGaWVsZCA9IHsgLi4udGhpcy5maWx0ZXJzQnlGaWVsZCwgW2ZpZWxkXTogeyAuLi5jdXJyZW50LCBvcGVyYXRvciB9IH07XG4gICAgdGhpcy5hcHBseUZpbHRlcnMoKTtcbiAgfVxuXG4gIGNsZWFyRmlsdGVyKGNvbHVtbj86IE1iR3JpZENvbHVtbjxUPik6IHZvaWQge1xuICAgIGlmICghY29sdW1uKSB7XG4gICAgICB0aGlzLmZpbHRlcnNCeUZpZWxkID0ge307XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNsb25lID0geyAuLi50aGlzLmZpbHRlcnNCeUZpZWxkIH07XG4gICAgICBkZWxldGUgY2xvbmVbU3RyaW5nKGNvbHVtbi5maWVsZCldO1xuICAgICAgdGhpcy5maWx0ZXJzQnlGaWVsZCA9IGNsb25lO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5RmlsdGVycygpO1xuICB9XG5cbiAgYXBwbHlHbG9iYWxTZWFyY2godmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZ2xvYmFsU2VhcmNoID0gdmFsdWU7XG4gICAgY29uc3QgZmlsdGVycyA9IHRoaXMudmlzaWJsZUNvbHVtbnNcbiAgICAgIC5maWx0ZXIoKGNvbHVtbikgPT4gY29sdW1uLmZpbHRlcmFibGUgIT09IGZhbHNlICYmIGNvbHVtbi50eXBlICE9PSAnY3VzdG9tJylcbiAgICAgIC5tYXAoKGNvbHVtbikgPT4gKHsgZmllbGQ6IGNvbHVtbi5maWVsZCwgb3BlcmF0b3I6ICdjb250YWlucycgYXMgY29uc3QsIHZhbHVlLCBpZ25vcmVDYXNlOiB0cnVlIH0pKTtcblxuICAgIGNvbnN0IGNvbHVtbkZpbHRlciA9IG1iR3JpZEJ1aWxkRmlsdGVyPFQ+KHRoaXMuZmlsdGVyc0J5RmllbGQpO1xuICAgIGNvbnN0IGdsb2JhbEZpbHRlcjogTWJHcmlkQ29tcG9zaXRlRmlsdGVyRGVzY3JpcHRvcjxUPiB8IHVuZGVmaW5lZCA9IHZhbHVlPy50cmltKClcbiAgICAgID8geyBsb2dpYzogJ29yJywgZmlsdGVycyB9XG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBmaWx0ZXI6IE1iR3JpZENvbXBvc2l0ZUZpbHRlckRlc2NyaXB0b3I8VD4gfCB1bmRlZmluZWQgPSBjb2x1bW5GaWx0ZXIgJiYgZ2xvYmFsRmlsdGVyXG4gICAgICA/IHsgbG9naWM6ICdhbmQnLCBmaWx0ZXJzOiBbY29sdW1uRmlsdGVyLCBnbG9iYWxGaWx0ZXJdIH1cbiAgICAgIDogY29sdW1uRmlsdGVyID8/IGdsb2JhbEZpbHRlcjtcblxuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLnN0YXRlLCBmaWx0ZXIsIHNraXA6IDAgfSk7XG4gICAgdGhpcy5maWx0ZXJDaGFuZ2UuZW1pdCh7IGZpbHRlciB9KTtcbiAgfVxuXG4gIGNoYW5nZVBhZ2UocGFnZUluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0UGFnZSA9IE1hdGgubWluKE1hdGgubWF4KHBhZ2VJbmRleCwgMCksIHRoaXMucGFnZUNvdW50IC0gMSk7XG4gICAgY29uc3Qgc3RhdGUgPSB7IC4uLnRoaXMuc3RhdGUsIHNraXA6IG5leHRQYWdlICogdGhpcy5wYWdlU2l6ZSB9O1xuICAgIHRoaXMuc2V0U3RhdGUoc3RhdGUpO1xuICAgIHRoaXMucGFnZUNoYW5nZS5lbWl0KHsgcGFnZUluZGV4OiBuZXh0UGFnZSwgcGFnZVNpemU6IHRoaXMucGFnZVNpemUsIHNraXA6IHN0YXRlLnNraXAsIHRha2U6IHN0YXRlLnRha2UgfSk7XG4gIH1cblxuICBjaGFuZ2VQYWdlU2l6ZSh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdGFrZSA9IE51bWJlcih2YWx1ZSk7XG4gICAgY29uc3Qgc3RhdGUgPSB7IC4uLnRoaXMuc3RhdGUsIHNraXA6IDAsIHRha2UgfTtcbiAgICB0aGlzLnNldFN0YXRlKHN0YXRlKTtcbiAgICB0aGlzLnBhZ2VDaGFuZ2UuZW1pdCh7IHBhZ2VJbmRleDogMCwgcGFnZVNpemU6IHRha2UsIHNraXA6IDAsIHRha2UgfSk7XG4gIH1cblxuICB0b2dnbGVSb3cocm93OiBULCBldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0Um93S2V5KHJvdyk7XG4gICAgY29uc3QgZXhpc3RzID0gdGhpcy5zZWxlY3RlZEtleXMuaW5jbHVkZXMoa2V5KTtcbiAgICBjb25zdCBuZXh0ID0gdGhpcy5zZWxlY3Rpb25Nb2RlID09PSAnc2luZ2xlJ1xuICAgICAgPyBleGlzdHMgPyBbXSA6IFtrZXldXG4gICAgICA6IGV4aXN0cyA/IHRoaXMuc2VsZWN0ZWRLZXlzLmZpbHRlcigoaXRlbSkgPT4gaXRlbSAhPT0ga2V5KSA6IFsuLi50aGlzLnNlbGVjdGVkS2V5cywga2V5XTtcbiAgICB0aGlzLnNlbGVjdGVkS2V5cyA9IG5leHQ7XG4gICAgdGhpcy5zZWxlY3RlZEtleXNDaGFuZ2UuZW1pdChuZXh0KTtcbiAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KHsgc2VsZWN0ZWRLZXlzOiBuZXh0LCBzZWxlY3RlZFJvd3M6IHRoaXMuc2VsZWN0ZWRSb3dzIH0pO1xuICB9XG5cbiAgdG9nZ2xlQWxsVmlzaWJsZShldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IHZpc2libGUgPSB0aGlzLmRhdGFSb3dzRnJvbVJlbmRlcmVkKCkubWFwKChyb3cpID0+IHRoaXMuZ2V0Um93S2V5KHJvdykpO1xuICAgIGNvbnN0IGFsbFNlbGVjdGVkID0gdmlzaWJsZS5ldmVyeSgoa2V5KSA9PiB0aGlzLnNlbGVjdGVkS2V5cy5pbmNsdWRlcyhrZXkpKTtcbiAgICB0aGlzLnNlbGVjdGVkS2V5cyA9IGFsbFNlbGVjdGVkXG4gICAgICA/IHRoaXMuc2VsZWN0ZWRLZXlzLmZpbHRlcigoa2V5KSA9PiAhdmlzaWJsZS5pbmNsdWRlcyhrZXkpKVxuICAgICAgOiBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLnRoaXMuc2VsZWN0ZWRLZXlzLCAuLi52aXNpYmxlXSkpO1xuICAgIHRoaXMuc2VsZWN0ZWRLZXlzQ2hhbmdlLmVtaXQodGhpcy5zZWxlY3RlZEtleXMpO1xuICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQoeyBzZWxlY3RlZEtleXM6IHRoaXMuc2VsZWN0ZWRLZXlzLCBzZWxlY3RlZFJvd3M6IHRoaXMuc2VsZWN0ZWRSb3dzIH0pO1xuICB9XG5cbiAgaXNTZWxlY3RlZChyb3c6IFQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEtleXMuaW5jbHVkZXModGhpcy5nZXRSb3dLZXkocm93KSk7XG4gIH1cblxuICBvblJvd0NsaWNrKHJvdzogVCwgcm93SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucm93Q2xpY2suZW1pdCh7IHJvdywgcm93SW5kZXggfSk7XG4gIH1cblxuICBvbkNlbGxDbGljayhyb3c6IFQsIGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+LCByb3dJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jZWxsQ2xpY2suZW1pdCh7IHJvdywgY29sdW1uLCB2YWx1ZTogdGhpcy5nZXRWYWx1ZShyb3csIGNvbHVtbiwgcm93SW5kZXgpLCByb3dJbmRleCB9KTtcbiAgfVxuXG4gIHRvZ2dsZUNvbHVtbk1lbnUoY29sdW1uOiBNYkdyaWRDb2x1bW48VD4sIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgZmllbGQgPSBTdHJpbmcoY29sdW1uLmZpZWxkKTtcbiAgICB0aGlzLm9wZW5Db2x1bW5NZW51RmllbGQgPSB0aGlzLm9wZW5Db2x1bW5NZW51RmllbGQgPT09IGZpZWxkID8gJycgOiBmaWVsZDtcbiAgfVxuXG4gIGhpZGVDb2x1bW4oY29sdW1uOiBNYkdyaWRDb2x1bW48VD4pOiB2b2lkIHtcbiAgICBjb2x1bW4uaGlkZGVuID0gdHJ1ZTtcbiAgICB0aGlzLm9wZW5Db2x1bW5NZW51RmllbGQgPSAnJztcbiAgICB0aGlzLmNvbHVtblZpc2liaWxpdHlDaGFuZ2UuZW1pdCh7IGNvbHVtbiwgZmllbGQ6IGNvbHVtbi5maWVsZCwgdmlzaWJsZTogZmFsc2UsIGNvbHVtbnM6IHRoaXMuaW50ZXJuYWxDb2x1bW5zIH0pO1xuICAgIHRoaXMucGVyc2lzdFN0YXRlKCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBzaG93Q29sdW1uKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+LCB2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29sdW1uLmhpZGRlbiA9ICF2aXNpYmxlO1xuICAgIHRoaXMuY29sdW1uVmlzaWJpbGl0eUNoYW5nZS5lbWl0KHsgY29sdW1uLCBmaWVsZDogY29sdW1uLmZpZWxkLCB2aXNpYmxlLCBjb2x1bW5zOiB0aGlzLmludGVybmFsQ29sdW1ucyB9KTtcbiAgICB0aGlzLnBlcnNpc3RTdGF0ZSgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgdG9nZ2xlTG9jayhjb2x1bW46IE1iR3JpZENvbHVtbjxUPik6IHZvaWQge1xuICAgIGNvbHVtbi5sb2NrZWQgPSAhY29sdW1uLmxvY2tlZDtcbiAgICBjb2x1bW4uc3RpY2t5ID0gY29sdW1uLmxvY2tlZCA/ICdzdGFydCcgOiBmYWxzZTtcbiAgICB0aGlzLmNvbHVtbkxvY2tDaGFuZ2UuZW1pdCh7IGNvbHVtbiwgZmllbGQ6IGNvbHVtbi5maWVsZCwgbG9ja2VkOiAhIWNvbHVtbi5sb2NrZWQsIGNvbHVtbnM6IHRoaXMuaW50ZXJuYWxDb2x1bW5zIH0pO1xuICAgIHRoaXMucGVyc2lzdFN0YXRlKCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICByZXNldENvbHVtbnMoKTogdm9pZCB7XG4gICAgdGhpcy5pbnRlcm5hbENvbHVtbnMgPSAodGhpcy5jb2x1bW5zID8/IFtdKS5tYXAoKGNvbHVtbikgPT4gKHsgLi4uY29sdW1uIH0pKTtcbiAgICB0aGlzLmFwcGx5UHJvamVjdGVkVGVtcGxhdGVzKCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICB0b2dnbGVHcm91cChjb2x1bW46IE1iR3JpZENvbHVtbjxUPik6IHZvaWQge1xuICAgIGlmICghdGhpcy5ncm91cGFibGUgfHwgY29sdW1uLmdyb3VwYWJsZSA9PT0gZmFsc2UpIHJldHVybjtcbiAgICBjb25zdCBmaWVsZCA9IFN0cmluZyhjb2x1bW4uZmllbGQpO1xuICAgIGNvbnN0IGV4aXN0cyA9IHRoaXMuc3RhdGUuZ3JvdXA/LnNvbWUoKGdyb3VwKSA9PiBTdHJpbmcoZ3JvdXAuZmllbGQpID09PSBmaWVsZCk7XG4gICAgY29uc3QgZ3JvdXAgPSBleGlzdHNcbiAgICAgID8gdGhpcy5zdGF0ZS5ncm91cC5maWx0ZXIoKGl0ZW0pID0+IFN0cmluZyhpdGVtLmZpZWxkKSAhPT0gZmllbGQpXG4gICAgICA6IFsuLi4odGhpcy5zdGF0ZS5ncm91cCA/PyBbXSksIHsgZmllbGQ6IGNvbHVtbi5maWVsZCwgZGlyOiAnYXNjJyBhcyBjb25zdCB9XTtcbiAgICB0aGlzLnNldFN0YXRlKHsgLi4udGhpcy5zdGF0ZSwgZ3JvdXAsIHNraXA6IDAgfSk7XG4gICAgdGhpcy5ncm91cENoYW5nZS5lbWl0KHsgZ3JvdXAgfSk7XG4gICAgdGhpcy5vcGVuQ29sdW1uTWVudUZpZWxkID0gJyc7XG4gIH1cblxuICByZW1vdmVHcm91cChncm91cDogTWJHcmlkR3JvdXBEZXNjcmlwdG9yPFQ+KTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IHRoaXMuc3RhdGUuZ3JvdXAuZmlsdGVyKChpdGVtKSA9PiBTdHJpbmcoaXRlbS5maWVsZCkgIT09IFN0cmluZyhncm91cC5maWVsZCkpO1xuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLnN0YXRlLCBncm91cDogbmV4dCwgc2tpcDogMCB9KTtcbiAgICB0aGlzLmdyb3VwQ2hhbmdlLmVtaXQoeyBncm91cDogbmV4dCB9KTtcbiAgfVxuXG4gIHRvZ2dsZUdyb3VwUm93KHJvdzogTWJHcmlkUmVuZGVyUm93PFQ+KTogdm9pZCB7XG4gICAgaWYgKHJvdy5raW5kICE9PSAnZ3JvdXAnKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZXhwYW5kZWRHcm91cEtleXMuaGFzKHJvdy5rZXkpKSB0aGlzLmV4cGFuZGVkR3JvdXBLZXlzLmRlbGV0ZShyb3cua2V5KTtcbiAgICBlbHNlIHRoaXMuZXhwYW5kZWRHcm91cEtleXMuYWRkKHJvdy5rZXkpO1xuICAgIHRoaXMucmVwcm9jZXNzKCk7XG4gIH1cblxuICBzdGFydFJlc2l6ZShjb2x1bW46IE1iR3JpZENvbHVtbjxUPiwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVzaXphYmxlIHx8IGNvbHVtbi5yZXNpemFibGUgPT09IGZhbHNlKSByZXR1cm47XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBoZWFkZXIgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KCd0aCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICB0aGlzLnJlc2l6aW5nID0geyBmaWVsZDogU3RyaW5nKGNvbHVtbi5maWVsZCksIHN0YXJ0WDogZXZlbnQuY2xpZW50WCwgc3RhcnRXaWR0aDogaGVhZGVyPy5vZmZzZXRXaWR0aCA/PyAxMjAgfTtcbiAgICBjb25zdCBtb3ZlID0gKG1vdmVFdmVudDogTW91c2VFdmVudCkgPT4gdGhpcy5yZXNpemVDb2x1bW4obW92ZUV2ZW50KTtcbiAgICBjb25zdCB1cCA9ICgpID0+IHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG1vdmUpO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHVwKTtcbiAgICAgIHRoaXMucmVzaXppbmcgPSB1bmRlZmluZWQ7XG4gICAgfTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBtb3ZlKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdXApO1xuICB9XG5cbiAgZHJvcENvbHVtbihldmVudDogQ2RrRHJhZ0Ryb3A8TWJHcmlkQ29sdW1uPFQ+W10+KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlb3JkZXJhYmxlIHx8IGV2ZW50LnByZXZpb3VzSW5kZXggPT09IGV2ZW50LmN1cnJlbnRJbmRleCkgcmV0dXJuO1xuICAgIG1vdmVJdGVtSW5BcnJheSh0aGlzLmludGVybmFsQ29sdW1ucywgZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcbiAgICB0aGlzLmNvbHVtblJlb3JkZXIuZW1pdCh7IHByZXZpb3VzSW5kZXg6IGV2ZW50LnByZXZpb3VzSW5kZXgsIGN1cnJlbnRJbmRleDogZXZlbnQuY3VycmVudEluZGV4LCBjb2x1bW5zOiB0aGlzLmludGVybmFsQ29sdW1ucyB9KTtcbiAgICB0aGlzLnBlcnNpc3RTdGF0ZSgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgZXhwb3J0Q3N2KCk6IHZvaWQge1xuICAgIGNvbnN0IHJvd3MgPSB0aGlzLmV4cG9ydFJvd3MoKTtcbiAgICBtYkdyaWRFeHBvcnRDc3Yocm93cywgdGhpcy52aXNpYmxlQ29sdW1ucywgdGhpcy5leHBvcnRGaWxlTmFtZSwgdGhpcy5mb3JtYXRPcHRpb25zKTtcbiAgfVxuXG4gIGV4cG9ydEV4Y2VsKCk6IHZvaWQge1xuICAgIG1iR3JpZEV4cG9ydEV4Y2VsSHRtbCh0aGlzLmV4cG9ydFJvd3MoKSwgdGhpcy52aXNpYmxlQ29sdW1ucywgdGhpcy5leGNlbEZpbGVOYW1lLCB0aGlzLmZvcm1hdE9wdGlvbnMsIHRoaXMuZWZmZWN0aXZlRGlyKTtcbiAgfVxuXG4gIGV4cG9ydEpzb24oKTogdm9pZCB7XG4gICAgbWJHcmlkRXhwb3J0SnNvbih0aGlzLmV4cG9ydFJvd3MoKSwgdGhpcy52aXNpYmxlQ29sdW1ucywgdGhpcy5qc29uRmlsZU5hbWUpO1xuICB9XG5cbiAgcmVzZXRTdGF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmdsb2JhbFNlYXJjaCA9ICcnO1xuICAgIHRoaXMuZmlsdGVyc0J5RmllbGQgPSB7fTtcbiAgICB0aGlzLmV4cGFuZGVkR3JvdXBLZXlzLmNsZWFyKCk7XG4gICAgdGhpcy5leHBhbmRlZERldGFpbEtleXMuY2xlYXIoKTtcbiAgICB0aGlzLmNhbmNlbEVkaXRJbnRlcm5hbChmYWxzZSk7XG4gICAgdGhpcy5zZXRTdGF0ZShtYkdyaWREZWZhdWx0U3RhdGU8VD4odGhpcy5wYWdlU2l6ZSkpO1xuICB9XG5cblxuICBjcmVhdGVSb3coKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRhYmxlIHx8ICF0aGlzLmFsbG93QWRkKSByZXR1cm47XG4gICAgY29uc3Qgcm93ID0gdGhpcy5uZXdJdGVtRmFjdG9yeSA/IHRoaXMubmV3SXRlbUZhY3RvcnkoKSA6ICh7fSBhcyBUKTtcbiAgICBjb25zdCBrZXkgPSBgX19uZXdfJHtEYXRlLm5vdygpfWA7XG4gICAgdGhpcy5lZGl0aW5nS2V5ID0ga2V5O1xuICAgIHRoaXMuZWRpdGluZ01vZGVsID0gdGhpcy5jbG9uZVJvdyhyb3cpO1xuICAgIHRoaXMub3JpZ2luYWxNb2RlbCA9IG51bGw7XG4gICAgdGhpcy5lZGl0aW5nUm93SW5kZXggPSAwO1xuICAgIHRoaXMuZWRpdGluZ0lzTmV3ID0gdHJ1ZTtcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnMgPSB7fTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHN0YXJ0RWRpdChyb3c6IFQsIHJvd0luZGV4OiBudW1iZXIsIGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmVkaXRhYmxlIHx8IHRoaXMuZWRpdE1vZGUgPT09ICdub25lJykgcmV0dXJuO1xuICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0Um93S2V5KHJvdyk7XG4gICAgdGhpcy5lZGl0aW5nS2V5ID0ga2V5O1xuICAgIHRoaXMuZWRpdGluZ01vZGVsID0gdGhpcy5jbG9uZVJvdyhyb3cpO1xuICAgIHRoaXMub3JpZ2luYWxNb2RlbCA9IHRoaXMuY2xvbmVSb3cocm93KTtcbiAgICB0aGlzLmVkaXRpbmdSb3dJbmRleCA9IHJvd0luZGV4O1xuICAgIHRoaXMuZWRpdGluZ0lzTmV3ID0gZmFsc2U7XG4gICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzID0ge307XG4gICAgdGhpcy5lZGl0LmVtaXQoeyByb3csIHJvd0luZGV4LCBrZXkgfSk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBzYXZlRWRpdChldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICghdGhpcy5lZGl0aW5nTW9kZWwgfHwgdGhpcy5lZGl0aW5nS2V5ID09PSBudWxsKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLnZhbGlkYXRlRWRpdGluZ01vZGVsKCkpIHtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByb3cgPSB0aGlzLmNsb25lUm93KHRoaXMuZWRpdGluZ01vZGVsKTtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmVkaXRpbmdLZXk7XG4gICAgdGhpcy5zYXZlLmVtaXQoeyByb3csIG9yaWdpbmFsUm93OiB0aGlzLm9yaWdpbmFsTW9kZWwsIHJvd0luZGV4OiB0aGlzLmVkaXRpbmdSb3dJbmRleCwga2V5LCBpc05ldzogdGhpcy5lZGl0aW5nSXNOZXcgfSk7XG4gICAgdGhpcy5jYW5jZWxFZGl0SW50ZXJuYWwoZmFsc2UpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgY2FuY2VsRWRpdFJvdyhldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICghdGhpcy5lZGl0aW5nTW9kZWwgfHwgdGhpcy5lZGl0aW5nS2V5ID09PSBudWxsKSByZXR1cm47XG4gICAgdGhpcy5jYW5jZWwuZW1pdCh7IHJvdzogdGhpcy5lZGl0aW5nTW9kZWwsIG9yaWdpbmFsUm93OiB0aGlzLm9yaWdpbmFsTW9kZWwsIHJvd0luZGV4OiB0aGlzLmVkaXRpbmdSb3dJbmRleCwga2V5OiB0aGlzLmVkaXRpbmdLZXksIGlzTmV3OiB0aGlzLmVkaXRpbmdJc05ldyB9KTtcbiAgICB0aGlzLmNhbmNlbEVkaXRJbnRlcm5hbCh0cnVlKTtcbiAgfVxuXG4gIHJlbW92ZVJvdyhyb3c6IFQsIHJvd0luZGV4OiBudW1iZXIsIGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKHRoaXMuY29uZmlybURlbGV0ZSAmJiAhY29uZmlybSh0aGlzLm1lc3NhZ2VzLmRlbGV0ZUNvbmZpcm0pKSByZXR1cm47XG4gICAgdGhpcy5yZW1vdmUuZW1pdCh7IHJvdywgcm93SW5kZXgsIGtleTogdGhpcy5nZXRSb3dLZXkocm93KSB9KTtcbiAgfVxuXG4gIGlzRWRpdGluZyhyb3c6IFQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZGl0aW5nS2V5ICE9PSBudWxsICYmIHRoaXMuZ2V0Um93S2V5KHJvdykgPT09IHRoaXMuZWRpdGluZ0tleTtcbiAgfVxuXG4gIGlzTmV3Um93RWRpdGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZGl0aW5nSXNOZXcgJiYgISF0aGlzLmVkaXRpbmdNb2RlbDtcbiAgfVxuXG4gIHNldEVkaXRWYWx1ZShjb2x1bW46IE1iR3JpZENvbHVtbjxUPiwgdmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdGluZ01vZGVsKSByZXR1cm47XG4gICAgaWYgKGNvbHVtbi52YWx1ZVNldHRlcikge1xuICAgICAgdGhpcy5lZGl0aW5nTW9kZWwgPSBjb2x1bW4udmFsdWVTZXR0ZXIodGhpcy5lZGl0aW5nTW9kZWwsIHZhbHVlLCB0aGlzLmVkaXRpbmdSb3dJbmRleCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0TmVzdGVkVmFsdWUodGhpcy5lZGl0aW5nTW9kZWwsIFN0cmluZyhjb2x1bW4uZmllbGQpLCB2YWx1ZSk7XG4gICAgfVxuICAgIGRlbGV0ZSB0aGlzLnZhbGlkYXRpb25FcnJvcnNbU3RyaW5nKGNvbHVtbi5maWVsZCldO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgZ2V0RWRpdFZhbHVlKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogdW5rbm93biB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdGluZ01vZGVsID8gdGhpcy5nZXRWYWx1ZSh0aGlzLmVkaXRpbmdNb2RlbCwgY29sdW1uLCB0aGlzLmVkaXRpbmdSb3dJbmRleCkgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBjYW5FZGl0Q29sdW1uKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdGFibGUgJiYgY29sdW1uLmVkaXRhYmxlICE9PSBmYWxzZSAmJiBjb2x1bW4udHlwZSAhPT0gJ2N1c3RvbSc7XG4gIH1cblxuICBnZXRFZGl0b3JUeXBlKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogc3RyaW5nIHtcbiAgICBpZiAoY29sdW1uLmVkaXRvcikgcmV0dXJuIGNvbHVtbi5lZGl0b3I7XG4gICAgaWYgKGNvbHVtbi50eXBlID09PSAnbnVtYmVyJykgcmV0dXJuICdudW1iZXInO1xuICAgIGlmIChjb2x1bW4udHlwZSA9PT0gJ2RhdGUnKSByZXR1cm4gJ2RhdGUnO1xuICAgIGlmIChjb2x1bW4udHlwZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gJ2NoZWNrYm94JztcbiAgICBpZiAoY29sdW1uLnR5cGUgPT09ICdlbnVtJykgcmV0dXJuICdzZWxlY3QnO1xuICAgIHJldHVybiAndGV4dCc7XG4gIH1cblxuICB0b2dnbGVEZXRhaWwocm93OiBULCByb3dJbmRleDogbnVtYmVyLCBldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0Um93S2V5KHJvdyk7XG4gICAgY29uc3QgZXhwYW5kZWQgPSAhdGhpcy5leHBhbmRlZERldGFpbEtleXMuaGFzKGtleSk7XG4gICAgaWYgKGV4cGFuZGVkKSB0aGlzLmV4cGFuZGVkRGV0YWlsS2V5cy5hZGQoa2V5KTtcbiAgICBlbHNlIHRoaXMuZXhwYW5kZWREZXRhaWxLZXlzLmRlbGV0ZShrZXkpO1xuICAgIHRoaXMuZGV0YWlsVG9nZ2xlLmVtaXQoeyByb3csIHJvd0luZGV4LCBrZXksIGV4cGFuZGVkIH0pO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgaXNEZXRhaWxFeHBhbmRlZChyb3c6IFQpOiBib29sZWFuIHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmdldFJvd0tleShyb3cpO1xuICAgIHJldHVybiB0aGlzLmRldGFpbEluaXRpYWxseUV4cGFuZGVkIHx8IHRoaXMuZXhwYW5kZWREZXRhaWxLZXlzLmhhcyhrZXkpO1xuICB9XG5cbiAgZ2V0Um93Q2xhc3Mocm93OiBULCByb3dJbmRleDogbnVtYmVyKTogc3RyaW5nIHwgc3RyaW5nW10gfCBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiB8IG51bGwge1xuICAgIGlmICghdGhpcy5yb3dDbGFzc05hbWUpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB0eXBlb2YgdGhpcy5yb3dDbGFzc05hbWUgPT09ICdmdW5jdGlvbicgPyB0aGlzLnJvd0NsYXNzTmFtZShyb3csIHJvd0luZGV4KSBhcyBhbnkgOiB0aGlzLnJvd0NsYXNzTmFtZSBhcyBhbnk7XG4gIH1cblxuICB0cmFja0NvbHVtbihfOiBudW1iZXIsIGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogc3RyaW5nIHtcbiAgICByZXR1cm4gU3RyaW5nKGNvbHVtbi5maWVsZCk7XG4gIH1cblxuICB0cmFja1JvdyhfOiBudW1iZXIsIHJvdzogTWJHcmlkUmVuZGVyUm93PFQ+KTogc3RyaW5nIHwgbnVtYmVyIHtcbiAgICByZXR1cm4gcm93LmtpbmQgPT09ICdncm91cCcgPyByb3cua2V5IDogdGhpcy5nZXRSb3dLZXkocm93LmRhdGFJdGVtKTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSB0b0Nzc1NpemUodmFsdWU6IG51bWJlciB8IHN0cmluZyB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSAnJykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgPyBgJHt2YWx1ZX1weGAgOiB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TG9ja2VkT2Zmc2V0KGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+LCBzaWRlOiAnc3RhcnQnIHwgJ2VuZCcpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvbHVtbnMgPSBzaWRlID09PSAnc3RhcnQnID8gdGhpcy5sb2NrZWRTdGFydENvbHVtbnMgOiB0aGlzLmxvY2tlZEVuZENvbHVtbnM7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGNvbHVtbnMpIHtcbiAgICAgIGlmIChTdHJpbmcoaXRlbS5maWVsZCkgPT09IFN0cmluZyhjb2x1bW4uZmllbGQpKSBicmVhaztcbiAgICAgIG9mZnNldCArPSB0aGlzLnJlc29sdmVDb2x1bW5XaWR0aChpdGVtKTtcbiAgICB9XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUNvbHVtbldpZHRoKGNvbHVtbjogTWJHcmlkQ29sdW1uPFQ+KTogbnVtYmVyIHtcbiAgICBpZiAodHlwZW9mIGNvbHVtbi53aWR0aCA9PT0gJ251bWJlcicpIHJldHVybiBjb2x1bW4ud2lkdGg7XG4gICAgaWYgKHR5cGVvZiBjb2x1bW4ud2lkdGggPT09ICdzdHJpbmcnICYmIGNvbHVtbi53aWR0aC5lbmRzV2l0aCgncHgnKSkge1xuICAgICAgcmV0dXJuIE51bWJlci5wYXJzZUZsb2F0KGNvbHVtbi53aWR0aCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgY29sdW1uLm1pbldpZHRoID09PSAnbnVtYmVyJykgcmV0dXJuIGNvbHVtbi5taW5XaWR0aDtcbiAgICByZXR1cm4gMTIwO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jTWVkaWFRdWVyaWVzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5yZXNwb25zaXZlQ29sdW1ucyB8fCB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuXG4gICAgY29uc3QgcXVlcmllcyA9IG5ldyBTZXQoXG4gICAgICB0aGlzLmludGVybmFsQ29sdW1uc1xuICAgICAgICAubWFwKChjb2x1bW4pID0+IGNvbHVtbi5tZWRpYSlcbiAgICAgICAgLmZpbHRlcigobWVkaWEpOiBtZWRpYSBpcyBzdHJpbmcgPT4gISFtZWRpYSksXG4gICAgKTtcblxuICAgIGZvciAoY29uc3QgcXVlcnkgb2YgcXVlcmllcykge1xuICAgICAgaWYgKHRoaXMubWVkaWFRdWVyeUxpc3RzLmhhcyhxdWVyeSkpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgbWVkaWFRdWVyeUxpc3QgPSB3aW5kb3cubWF0Y2hNZWRpYShxdWVyeSk7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9O1xuICAgICAgbWVkaWFRdWVyeUxpc3QuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgbGlzdGVuZXIpO1xuICAgICAgdGhpcy5tZWRpYVF1ZXJ5TGlzdHMuc2V0KHF1ZXJ5LCBtZWRpYVF1ZXJ5TGlzdCk7XG4gICAgICB0aGlzLm1lZGlhTGlzdGVuZXJzLnNldChxdWVyeSwgbGlzdGVuZXIpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U3RhdGUoc3RhdGU6IE1iR3JpZFN0YXRlPFQ+KTogdm9pZCB7XG4gICAgdGhpcy5zdGF0ZSA9IHsgLi4uc3RhdGUsIHNvcnQ6IHN0YXRlLnNvcnQgPz8gW10sIGdyb3VwOiBzdGF0ZS5ncm91cCA/PyBbXSB9O1xuICAgIHRoaXMuc3RhdGVDaGFuZ2UuZW1pdCh0aGlzLnN0YXRlKTtcbiAgICB0aGlzLnBlcnNpc3RTdGF0ZSgpO1xuICAgIHRoaXMucmVwcm9jZXNzKCk7XG4gIH1cblxuICBwcml2YXRlIHJlcHJvY2VzcygpOiB2b2lkIHtcbiAgICBjb25zdCBzYWZlU3RhdGUgPSB0aGlzLnN0YXRlID8/IG1iR3JpZERlZmF1bHRTdGF0ZTxUPigpO1xuICAgIGlmICh0aGlzLmRhdGFNb2RlID09PSAnc2VydmVyJykge1xuICAgICAgdGhpcy5wcm9jZXNzZWQgPSB7XG4gICAgICAgIGRhdGE6ICh0aGlzLmRhdGEgPz8gW10pLm1hcCgoZGF0YUl0ZW0sIHJvd0luZGV4KSA9PiAoeyBraW5kOiAnZGF0YScsIGRhdGFJdGVtLCByb3dJbmRleDogc2FmZVN0YXRlLnNraXAgKyByb3dJbmRleCB9KSksXG4gICAgICAgIHRvdGFsOiB0aGlzLnRvdGFsLFxuICAgICAgICBhZ2dyZWdhdGVzOiB7fSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvY2Vzc2VkID0gbWJHcmlkUHJvY2Vzcyh0aGlzLmRhdGEgPz8gW10sIHNhZmVTdGF0ZSwgdGhpcy5pbnRlcm5hbENvbHVtbnMsIHRoaXMuZXhwYW5kZWRHcm91cEtleXMpO1xuICAgIH1cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlGaWx0ZXJzKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbkZpbHRlciA9IG1iR3JpZEJ1aWxkRmlsdGVyPFQ+KHRoaXMuZmlsdGVyc0J5RmllbGQpO1xuICAgIGlmICh0aGlzLmdsb2JhbFNlYXJjaCkge1xuICAgICAgdGhpcy5hcHBseUdsb2JhbFNlYXJjaCh0aGlzLmdsb2JhbFNlYXJjaCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc2V0U3RhdGUoeyAuLi50aGlzLnN0YXRlLCBmaWx0ZXI6IGNvbHVtbkZpbHRlciwgc2tpcDogMCB9KTtcbiAgICB0aGlzLmZpbHRlckNoYW5nZS5lbWl0KHsgZmlsdGVyOiBjb2x1bW5GaWx0ZXIgfSk7XG4gIH1cblxuICBwcml2YXRlIGRlZmF1bHRPcGVyYXRvcihjb2x1bW46IE1iR3JpZENvbHVtbjxUPik6IE1iR3JpZEZpbHRlck9wZXJhdG9yIHtcbiAgICBpZiAoY29sdW1uLnR5cGUgPT09ICdudW1iZXInIHx8IGNvbHVtbi50eXBlID09PSAnZGF0ZScgfHwgY29sdW1uLnR5cGUgPT09ICdib29sZWFuJykgcmV0dXJuICdlcSc7XG4gICAgcmV0dXJuICdjb250YWlucyc7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUZpbHRlckRlZmF1bHRzKCk6IHZvaWQge1xuICAgIGNvbnN0IG5leHQgPSB7IC4uLnRoaXMuZmlsdGVyc0J5RmllbGQgfTtcbiAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiB0aGlzLmludGVybmFsQ29sdW1ucykge1xuICAgICAgY29uc3QgZmllbGQgPSBTdHJpbmcoY29sdW1uLmZpZWxkKTtcbiAgICAgIG5leHRbZmllbGRdID8/PSB7IG9wZXJhdG9yOiB0aGlzLmRlZmF1bHRPcGVyYXRvcihjb2x1bW4pLCB2YWx1ZTogJycgfTtcbiAgICB9XG4gICAgdGhpcy5maWx0ZXJzQnlGaWVsZCA9IG5leHQ7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5UHJvamVjdGVkVGVtcGxhdGVzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIHRoaXMuaW50ZXJuYWxDb2x1bW5zKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IFN0cmluZyhjb2x1bW4uZmllbGQpO1xuICAgICAgY29uc3QgY2VsbCA9IHRoaXMuY2VsbFRlbXBsYXRlcz8uZmluZCgoaXRlbSkgPT4gaXRlbS5maWVsZCA9PT0gZmllbGQpO1xuICAgICAgY29uc3QgaGVhZGVyID0gdGhpcy5oZWFkZXJUZW1wbGF0ZXM/LmZpbmQoKGl0ZW0pID0+IGl0ZW0uZmllbGQgPT09IGZpZWxkKTtcbiAgICAgIGNvbnN0IGZvb3RlciA9IHRoaXMuZm9vdGVyVGVtcGxhdGVzPy5maW5kKChpdGVtKSA9PiBpdGVtLmZpZWxkID09PSBmaWVsZCk7XG4gICAgICBjb25zdCBlZGl0ID0gdGhpcy5lZGl0VGVtcGxhdGVzPy5maW5kKChpdGVtKSA9PiBpdGVtLmZpZWxkID09PSBmaWVsZCk7XG4gICAgICBpZiAoY2VsbCkgY29sdW1uLmNlbGxUZW1wbGF0ZSA9IGNlbGwudGVtcGxhdGVSZWY7XG4gICAgICBpZiAoaGVhZGVyKSBjb2x1bW4uaGVhZGVyVGVtcGxhdGUgPSBoZWFkZXIudGVtcGxhdGVSZWY7XG4gICAgICBpZiAoZm9vdGVyKSBjb2x1bW4uZm9vdGVyVGVtcGxhdGUgPSBmb290ZXIudGVtcGxhdGVSZWY7XG4gICAgICBpZiAoZWRpdCkgY29sdW1uLmVkaXRUZW1wbGF0ZSA9IGVkaXQudGVtcGxhdGVSZWY7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZXNpemVDb2x1bW4oZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVzaXppbmcpIHJldHVybjtcbiAgICBjb25zdCBkZWx0YSA9IHRoaXMuZWZmZWN0aXZlRGlyID09PSAncnRsJyA/IHRoaXMucmVzaXppbmcuc3RhcnRYIC0gZXZlbnQuY2xpZW50WCA6IGV2ZW50LmNsaWVudFggLSB0aGlzLnJlc2l6aW5nLnN0YXJ0WDtcbiAgICBjb25zdCB3aWR0aCA9IE1hdGgubWF4KDU2LCB0aGlzLnJlc2l6aW5nLnN0YXJ0V2lkdGggKyBkZWx0YSk7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5pbnRlcm5hbENvbHVtbnMuZmluZCgoaXRlbSkgPT4gU3RyaW5nKGl0ZW0uZmllbGQpID09PSB0aGlzLnJlc2l6aW5nPy5maWVsZCk7XG4gICAgaWYgKCFjb2x1bW4pIHJldHVybjtcbiAgICBjb2x1bW4ud2lkdGggPSB3aWR0aDtcbiAgICB0aGlzLmNvbHVtblJlc2l6ZS5lbWl0KHsgY29sdW1uLCBmaWVsZDogY29sdW1uLmZpZWxkLCB3aWR0aCB9KTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSBleHBvcnRSb3dzKCk6IFRbXSB7XG4gICAgaWYgKHRoaXMuZGF0YU1vZGUgPT09ICdzZXJ2ZXInKSByZXR1cm4gdGhpcy5kYXRhID8/IFtdO1xuICAgIGNvbnN0IHNhZmVTdGF0ZSA9IHsgLi4udGhpcy5zdGF0ZSwgc2tpcDogMCwgdGFrZTogTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfTtcbiAgICByZXR1cm4gbWJHcmlkUHJvY2Vzcyh0aGlzLmRhdGEgPz8gW10sIHNhZmVTdGF0ZSwgdGhpcy5pbnRlcm5hbENvbHVtbnMsIHRoaXMuZXhwYW5kZWRHcm91cEtleXMpXG4gICAgICAuZGF0YVxuICAgICAgLmZpbHRlcigocm93KTogcm93IGlzIEV4dHJhY3Q8TWJHcmlkUmVuZGVyUm93PFQ+LCB7IGtpbmQ6ICdkYXRhJyB9PiA9PiByb3cua2luZCA9PT0gJ2RhdGEnKVxuICAgICAgLm1hcCgocm93KSA9PiByb3cuZGF0YUl0ZW0pO1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUVkaXRpbmdNb2RlbCgpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuZWRpdGluZ01vZGVsKSByZXR1cm4gdHJ1ZTtcbiAgICBjb25zdCBlcnJvcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiB0aGlzLnZpc2libGVDb2x1bW5zKSB7XG4gICAgICBpZiAoIXRoaXMuY2FuRWRpdENvbHVtbihjb2x1bW4pKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRWYWx1ZSh0aGlzLmVkaXRpbmdNb2RlbCwgY29sdW1uLCB0aGlzLmVkaXRpbmdSb3dJbmRleCk7XG4gICAgICBjb25zdCBmaWVsZCA9IFN0cmluZyhjb2x1bW4uZmllbGQpO1xuICAgICAgaWYgKGNvbHVtbi5yZXF1aXJlZCAmJiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCBTdHJpbmcodmFsdWUpLnRyaW0oKSA9PT0gJycpKSB7XG4gICAgICAgIGVycm9yc1tmaWVsZF0gPSB0aGlzLm1lc3NhZ2VzLmZpZWxkUmVxdWlyZWQoY29sdW1uLnRpdGxlKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXN0b20gPSBjb2x1bW4udmFsaWRhdG9yPy4odmFsdWUsIHRoaXMuZWRpdGluZ01vZGVsLCBjb2x1bW4pO1xuICAgICAgaWYgKGN1c3RvbSkgZXJyb3JzW2ZpZWxkXSA9IGN1c3RvbTtcbiAgICB9XG4gICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzID0gZXJyb3JzO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhlcnJvcnMpLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIHByaXZhdGUgY2xvbmVSb3cocm93OiBUKTogVCB7XG4gICAgaWYgKHR5cGVvZiBzdHJ1Y3R1cmVkQ2xvbmUgPT09ICdmdW5jdGlvbicpIHJldHVybiBzdHJ1Y3R1cmVkQ2xvbmUocm93KTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyb3cpKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0TmVzdGVkVmFsdWUocm93OiBULCBwYXRoOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgY29uc3QgcGFydHMgPSBwYXRoLnNwbGl0KCcuJyk7XG4gICAgbGV0IGN1cnNvcjogYW55ID0gcm93O1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwYXJ0cy5sZW5ndGggLSAxOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBwYXJ0ID0gcGFydHNbaW5kZXhdO1xuICAgICAgY3Vyc29yW3BhcnRdID8/PSB7fTtcbiAgICAgIGN1cnNvciA9IGN1cnNvcltwYXJ0XTtcbiAgICB9XG4gICAgY3Vyc29yW3BhcnRzW3BhcnRzLmxlbmd0aCAtIDFdXSA9IHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjYW5jZWxFZGl0SW50ZXJuYWwobWFyayA9IHRydWUpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRpbmdLZXkgPSBudWxsO1xuICAgIHRoaXMuZWRpdGluZ01vZGVsID0gbnVsbDtcbiAgICB0aGlzLm9yaWdpbmFsTW9kZWwgPSBudWxsO1xuICAgIHRoaXMuZWRpdGluZ1Jvd0luZGV4ID0gLTE7XG4gICAgdGhpcy5lZGl0aW5nSXNOZXcgPSBmYWxzZTtcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnMgPSB7fTtcbiAgICBpZiAobWFyaykgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIHJlc3RvcmVQZXJzaXN0ZWRTdGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucGVyc2lzdEtleSkgcmV0dXJuO1xuICAgIGNvbnN0IHNhdmVkID0gdGhpcy5zdGF0ZVN0b3JlLmxvYWQ8VD4odGhpcy5wZXJzaXN0S2V5KTtcbiAgICBpZiAoIXNhdmVkKSByZXR1cm47XG4gICAgdGhpcy5zdGF0ZSA9IHNhdmVkLnN0YXRlID8/IHRoaXMuc3RhdGU7XG4gICAgdGhpcy5zZWxlY3RlZEtleXMgPSBzYXZlZC5zZWxlY3RlZEtleXMgPz8gdGhpcy5zZWxlY3RlZEtleXM7XG4gICAgZm9yIChjb25zdCBzYXZlZENvbHVtbiBvZiBzYXZlZC5jb2x1bW5zID8/IFtdKSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmludGVybmFsQ29sdW1ucy5maW5kKChjb2x1bW4pID0+IFN0cmluZyhjb2x1bW4uZmllbGQpID09PSBTdHJpbmcoc2F2ZWRDb2x1bW4uZmllbGQpKTtcbiAgICAgIGlmICghdGFyZ2V0KSBjb250aW51ZTtcbiAgICAgIHRhcmdldC53aWR0aCA9IHNhdmVkQ29sdW1uLndpZHRoID8/IHRhcmdldC53aWR0aDtcbiAgICAgIHRhcmdldC5oaWRkZW4gPSBzYXZlZENvbHVtbi5oaWRkZW4gPz8gdGFyZ2V0LmhpZGRlbjtcbiAgICAgIHRhcmdldC5sb2NrZWQgPSBzYXZlZENvbHVtbi5sb2NrZWQgPz8gdGFyZ2V0LmxvY2tlZDtcbiAgICAgIHRhcmdldC5zdGlja3kgPSBzYXZlZENvbHVtbi5zdGlja3kgPz8gdGFyZ2V0LnN0aWNreTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBlcnNpc3RTdGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYXV0b1BlcnNpc3QgfHwgIXRoaXMucGVyc2lzdEtleSkgcmV0dXJuO1xuICAgIHRoaXMuc3RhdGVTdG9yZS5zYXZlKHRoaXMucGVyc2lzdEtleSwgdGhpcy5zdGF0ZSwgdGhpcy5pbnRlcm5hbENvbHVtbnMsIHRoaXMuc2VsZWN0ZWRLZXlzKTtcbiAgfVxuXG4gIHByaXZhdGUgZGF0YVJvd3NGcm9tUmVuZGVyZWQoKTogVFtdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzZWQuZGF0YS5maWx0ZXIoKHJvdyk6IHJvdyBpcyBFeHRyYWN0PE1iR3JpZFJlbmRlclJvdzxUPiwgeyBraW5kOiAnZGF0YScgfT4gPT4gcm93LmtpbmQgPT09ICdkYXRhJykubWFwKChyb3cpID0+IHJvdy5kYXRhSXRlbSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtYi1ncmlkXCIgW2F0dHIuZGlyXT1cImVmZmVjdGl2ZURpclwiIFtuZ0NsYXNzXT1cIlsnbWItZ3JpZC0tJyArIGRlbnNpdHksIGxvYWRpbmcgPyAnbWItZ3JpZC0tbG9hZGluZycgOiAnJ11cIiBbbmdTdHlsZV09XCJncmlkU3R5bGVcIj5cbiAgPGRpdiAqbmdJZj1cInNob3dUb29sYmFyXCIgY2xhc3M9XCJtYi1ncmlkX190b29sYmFyXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRvb2xiYXJUZW1wbGF0ZT8udGVtcGxhdGVSZWYgYXMgdG9vbGJhclRwbDsgZWxzZSBkZWZhdWx0VG9vbGJhclwiPlxuICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJ0b29sYmFyVHBsXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInRvb2xiYXJDb250ZXh0XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRUb29sYmFyPlxuICAgICAgPGRpdiBjbGFzcz1cIm1iLWdyaWRfX3Rvb2xiYXItc3RhcnRcIj5cbiAgICAgICAgPGRpdiAqbmdJZj1cImdyb3VwYWJsZVwiIGNsYXNzPVwibWItZ3JpZF9fZ3JvdXAtcGFuZWxcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1iLWdyaWRfX2dyb3VwLWxhYmVsXCI+e3sgbWVzc2FnZXMuZ3JvdXBMYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgZ3JvdXAgb2Ygc3RhdGUuZ3JvdXBcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cIm1iLWdyaWRfX2dyb3VwLWNoaXBcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUdyb3VwKGdyb3VwKVwiPlxuICAgICAgICAgICAge3sgZ3JvdXAuZmllbGQgfX0gw5dcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFzdGF0ZS5ncm91cC5sZW5ndGhcIiBjbGFzcz1cIm1iLWdyaWRfX2dyb3VwLWhpbnRcIj57eyBtZXNzYWdlcy5ncm91cEhpbnQgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJtYi1ncmlkX190b29sYmFyLWVuZFwiPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiZWRpdGFibGUgJiYgYWxsb3dBZGRcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX190b29sLWJ1dHRvbiBtYi1ncmlkX190b29sLWJ1dHRvbi0tcHJpbWFyeVwiIChjbGljayk9XCJjcmVhdGVSb3coKVwiPnt7IG1lc3NhZ2VzLmFkZFJvdyB9fTwvYnV0dG9uPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICAqbmdJZj1cInNob3dTZWFyY2hcIlxuICAgICAgICAgIGNsYXNzPVwibWItZ3JpZF9fc2VhcmNoXCJcbiAgICAgICAgICBbbmdNb2RlbF09XCJnbG9iYWxTZWFyY2hcIlxuICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImFwcGx5R2xvYmFsU2VhcmNoKCRldmVudClcIlxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJtZXNzYWdlcy5zZWFyY2hQbGFjZWhvbGRlclwiIC8+XG5cbiAgICAgICAgPGRpdiAqbmdJZj1cInNob3dDb2x1bW5DaG9vc2VyXCIgY2xhc3M9XCJtYi1ncmlkX19jaG9vc2VyXCI+XG4gICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX190b29sLWJ1dHRvblwiIChjbGljayk9XCJvcGVuQ29sdW1uTWVudUZpZWxkID0gb3BlbkNvbHVtbk1lbnVGaWVsZCA9PT0gJ19fY2hvb3NlcicgPyAnJyA6ICdfX2Nob29zZXInXCI+XG4gICAgICAgICAgICB7eyBtZXNzYWdlcy5jb2x1bW5zIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cIm9wZW5Db2x1bW5NZW51RmllbGQgPT09ICdfX2Nob29zZXInXCIgY2xhc3M9XCJtYi1ncmlkX19jaG9vc2VyLW1lbnVcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICA8bGFiZWwgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBpbnRlcm5hbENvbHVtbnNcIiBjbGFzcz1cIm1iLWdyaWRfX2Nob29zZXItb3B0aW9uXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCIhY29sdW1uLmhpZGRlblwiIChjaGFuZ2UpPVwic2hvd0NvbHVtbihjb2x1bW4sICRhbnkoJGV2ZW50LnRhcmdldCkuY2hlY2tlZClcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj57eyBjb2x1bW4udGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX19tZW51LWFjdGlvblwiIChjbGljayk9XCJyZXNldENvbHVtbnMoKVwiPnt7IG1lc3NhZ2VzLnJlc2V0Q29sdW1ucyB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwic2hvd0V4cG9ydFwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX3Rvb2wtYnV0dG9uXCIgKGNsaWNrKT1cImV4cG9ydENzdigpXCI+e3sgbWVzc2FnZXMuZXhwb3J0Q3N2IH19PC9idXR0b24+XG4gICAgICAgIDxidXR0b24gKm5nSWY9XCJzaG93RXhwb3J0ICYmIHNob3dFeGNlbEV4cG9ydFwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX3Rvb2wtYnV0dG9uXCIgKGNsaWNrKT1cImV4cG9ydEV4Y2VsKClcIj57eyBtZXNzYWdlcy5leHBvcnRFeGNlbCB9fTwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwic2hvd0V4cG9ydCAmJiBzaG93SnNvbkV4cG9ydFwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX3Rvb2wtYnV0dG9uXCIgKGNsaWNrKT1cImV4cG9ydEpzb24oKVwiPnt7IG1lc3NhZ2VzLmV4cG9ydEpzb24gfX08L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX190b29sLWJ1dHRvblwiIChjbGljayk9XCJyZXNldFN0YXRlKClcIj57eyBtZXNzYWdlcy5yZXNldCB9fTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG5cbiAgPGRpdiAqbmdJZj1cImxvYWRpbmdcIiBjbGFzcz1cIm1iLWdyaWRfX2xvYWRpbmdcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm1iLWdyaWRfX3NwaW5uZXJcIj48L3NwYW4+XG4gICAgPHNwYW4+e3sgbG9hZGluZ1RleHQgfHwgbWVzc2FnZXMubG9hZGluZyB9fTwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cIm1iLWdyaWRfX3Njcm9sbFwiPlxuICAgIDx0YWJsZSBjbGFzcz1cIm1iLWdyaWRfX3RhYmxlXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0clxuICAgICAgICAgIGNsYXNzPVwibWItZ3JpZF9faGVhZGVyLXJvd1wiXG4gICAgICAgICAgY2RrRHJvcExpc3RcbiAgICAgICAgICBjZGtEcm9wTGlzdE9yaWVudGF0aW9uPVwiaG9yaXpvbnRhbFwiXG4gICAgICAgICAgW2Nka0Ryb3BMaXN0RGlzYWJsZWRdPVwiIXJlb3JkZXJhYmxlXCJcbiAgICAgICAgICBbY2RrRHJvcExpc3REYXRhXT1cInZpc2libGVDb2x1bW5zXCJcbiAgICAgICAgICAoY2RrRHJvcExpc3REcm9wcGVkKT1cImRyb3BDb2x1bW4oJGV2ZW50KVwiPlxuICAgICAgICAgIDx0aCAqbmdJZj1cImV4cGFuZGFibGVcIiBjbGFzcz1cIm1iLWdyaWRfX3NlbGVjdC1jZWxsIG1iLWdyaWRfX2hlYWRlci1jZWxsXCI+PC90aD5cbiAgICAgICAgICAgIDx0aCAqbmdJZj1cInNlbGVjdGFibGVcIiBjbGFzcz1cIm1iLWdyaWRfX3NlbGVjdC1jZWxsIG1iLWdyaWRfX2hlYWRlci1jZWxsXCI+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiYWxsVmlzaWJsZVJvd3NTZWxlY3RlZFwiXG4gICAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cInNvbWVWaXNpYmxlUm93c1NlbGVjdGVkXCJcbiAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ0b2dnbGVBbGxWaXNpYmxlKCRldmVudClcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIm1lc3NhZ2VzLnNlbGVjdEFsbFJvd3NcIiAvPlxuICAgICAgICAgIDwvdGg+XG5cbiAgICAgICAgICA8dGhcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgdmlzaWJsZUNvbHVtbnM7IGxldCBjb2x1bW5JbmRleCA9IGluZGV4OyB0cmFja0J5OiB0cmFja0NvbHVtblwiXG4gICAgICAgICAgICBjZGtEcmFnXG4gICAgICAgICAgICBjbGFzcz1cIm1iLWdyaWRfX2hlYWRlci1jZWxsXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cIlsnbWItZ3JpZF9fY2VsbC0tJyArIChjb2x1bW4uaGVhZGVyQWxpZ24gfHwgY29sdW1uLmFsaWduIHx8ICdzdGFydCcpLCBjb2x1bW4uc29ydGFibGUgPT09IGZhbHNlID8gJycgOiAnbWItZ3JpZF9faGVhZGVyLWNlbGwtLXNvcnRhYmxlJywgZ2V0Q29sdW1uQ2xhc3MoY29sdW1uKV1cIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0Q29sdW1uU3R5bGUoY29sdW1uKVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLWdyaWRfX2hlYWRlci1jb250ZW50XCIgKGNsaWNrKT1cInRvZ2dsZVNvcnQoY29sdW1uLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRIZWFkZXJUZW1wbGF0ZShjb2x1bW4pIGFzIGhlYWRlclRwbDsgZWxzZSBkZWZhdWx0SGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWFkZXJUcGxcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IGNvbHVtbiwgY29sdW1uOiBjb2x1bW4gfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0SGVhZGVyPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWItZ3JpZF9faGVhZGVyLXRpdGxlXCI+e3sgY29sdW1uLnRpdGxlIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZ2V0U29ydERpcmVjdGlvbihjb2x1bW4pIGFzIGRpclwiIGNsYXNzPVwibWItZ3JpZF9fc29ydFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGRpciA9PT0gJ2FzYycgPyAn4oaRJyA6ICfihpMnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzbWFsbCAqbmdJZj1cIm11bHRpU29ydCAmJiBnZXRTb3J0SW5kZXgoY29sdW1uKSA+PSAwXCI+e3sgZ2V0U29ydEluZGV4KGNvbHVtbikgKyAxIH19PC9zbWFsbD5cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgKm5nSWY9XCJoYXNDb2x1bW5NZW51ICYmIGNvbHVtbi5tZW51ICE9PSBmYWxzZVwiXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cIm1iLWdyaWRfX2NvbHVtbi1tZW51LWJ1dHRvblwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwibWVzc2FnZXMuY29sdW1uTWVudVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDb2x1bW5NZW51KGNvbHVtbiwgJGV2ZW50KVwiPuKLrjwvYnV0dG9uPlxuXG4gICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAqbmdJZj1cInJlc2l6YWJsZSAmJiBjb2x1bW4ucmVzaXphYmxlICE9PSBmYWxzZVwiXG4gICAgICAgICAgICAgIGNsYXNzPVwibWItZ3JpZF9fcmVzaXplLWhhbmRsZVwiXG4gICAgICAgICAgICAgIChtb3VzZWRvd24pPVwic3RhcnRSZXNpemUoY29sdW1uLCAkZXZlbnQpXCI+PC9zcGFuPlxuXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwib3BlbkNvbHVtbk1lbnVGaWVsZCA9PT0gY29sdW1uLmZpZWxkLnRvU3RyaW5nKClcIiBjbGFzcz1cIm1iLWdyaWRfX2NvbHVtbi1tZW51XCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX21lbnUtYWN0aW9uXCIgKGNsaWNrKT1cInRvZ2dsZVNvcnQoY29sdW1uKVwiPnt7IG1lc3NhZ2VzLnNvcnQgfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImdyb3VwYWJsZSAmJiBjb2x1bW4uZ3JvdXBhYmxlICE9PSBmYWxzZVwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX21lbnUtYWN0aW9uXCIgKGNsaWNrKT1cInRvZ2dsZUdyb3VwKGNvbHVtbilcIj5cbiAgICAgICAgICAgICAgICB7eyBzdGF0ZS5ncm91cC5sZW5ndGggJiYgc3RhdGUuZ3JvdXBbMF0uZmllbGQgPT09IGNvbHVtbi5maWVsZCA/IG1lc3NhZ2VzLnJlbW92ZUdyb3VwIDogbWVzc2FnZXMuZ3JvdXBCeUNvbHVtbiB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmlsdGVyYWJsZSAmJiBjb2x1bW4uZmlsdGVyYWJsZSAhPT0gZmFsc2UgJiYgKGZpbHRlck1vZGUgPT09ICdtZW51JyB8fCBmaWx0ZXJNb2RlID09PSAnYm90aCcpXCIgY2xhc3M9XCJtYi1ncmlkX19tZW51LWZpbHRlclwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbD57eyBtZXNzYWdlcy5maWx0ZXIgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nTW9kZWxdPVwiZmlsdGVyc0J5RmllbGRbY29sdW1uLmZpZWxkLnRvU3RyaW5nKCldLm9wZXJhdG9yXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0RmlsdGVyT3BlcmF0b3IoY29sdW1uLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcGVyYXRvciBvZiBnZXRPcGVyYXRvcnMoY29sdW1uKVwiIFtuZ1ZhbHVlXT1cIm9wZXJhdG9yXCI+e3sgZ2V0T3BlcmF0b3JMYWJlbChvcGVyYXRvcikgfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIFt0eXBlXT1cImNvbHVtbi50eXBlID09PSAnbnVtYmVyJyA/ICdudW1iZXInIDogY29sdW1uLnR5cGUgPT09ICdkYXRlJyA/ICdkYXRlJyA6ICd0ZXh0J1wiXG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmaWx0ZXJzQnlGaWVsZFtjb2x1bW4uZmllbGQudG9TdHJpbmcoKV0udmFsdWVcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0RmlsdGVyVmFsdWUoY29sdW1uLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJtZXNzYWdlcy5maWx0ZXJWYWx1ZVBsYWNlaG9sZGVyXCIgLz5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX21lbnUtYWN0aW9uXCIgKGNsaWNrKT1cImNsZWFyRmlsdGVyKGNvbHVtbilcIj57eyBtZXNzYWdlcy5jbGVhckZpbHRlciB9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX21lbnUtYWN0aW9uXCIgKGNsaWNrKT1cInRvZ2dsZUxvY2soY29sdW1uKVwiPnt7IGNvbHVtbi5sb2NrZWQgPyBtZXNzYWdlcy51bmxvY2tDb2x1bW4gOiBtZXNzYWdlcy5sb2NrQ29sdW1uIH19PC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibWItZ3JpZF9fbWVudS1hY3Rpb25cIiAoY2xpY2spPVwiaGlkZUNvbHVtbihjb2x1bW4pXCI+e3sgbWVzc2FnZXMuaGlkZUNvbHVtbiB9fTwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90aD5cblxuICAgICAgICAgIDx0aCAqbmdJZj1cInNob3dDb21tYW5kQ29sdW1uXCIgY2xhc3M9XCJtYi1ncmlkX19oZWFkZXItY2VsbCBtYi1ncmlkX19jb21tYW5kLWNlbGxcIj57eyBlZmZlY3RpdmVDb21tYW5kQ29sdW1uVGl0bGUgfX08L3RoPlxuICAgICAgICA8L3RyPlxuXG4gICAgICAgIDx0ciAqbmdJZj1cImhhc0ZpbHRlclJvd1wiIGNsYXNzPVwibWItZ3JpZF9fZmlsdGVyLXJvd1wiPlxuICAgICAgICAgIDx0aCAqbmdJZj1cImV4cGFuZGFibGVcIiBjbGFzcz1cIm1iLWdyaWRfX3NlbGVjdC1jZWxsXCI+PC90aD5cbiAgICAgICAgICA8dGggKm5nSWY9XCJzZWxlY3RhYmxlXCIgY2xhc3M9XCJtYi1ncmlkX19zZWxlY3QtY2VsbFwiPjwvdGg+XG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgdmlzaWJsZUNvbHVtbnM7IHRyYWNrQnk6IHRyYWNrQ29sdW1uXCIgY2xhc3M9XCJtYi1ncmlkX19maWx0ZXItY2VsbFwiIFtuZ0NsYXNzXT1cImdldENvbHVtbkNsYXNzKGNvbHVtbilcIiBbbmdTdHlsZV09XCJnZXRDb2x1bW5TdHlsZShjb2x1bW4pXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29sdW1uLmZpbHRlcmFibGUgIT09IGZhbHNlXCIgY2xhc3M9XCJtYi1ncmlkX19maWx0ZXItY29udHJvbFwiPlxuICAgICAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICAgICAgY2xhc3M9XCJtYi1ncmlkX19maWx0ZXItb3BlcmF0b3JcIlxuICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImZpbHRlcnNCeUZpZWxkW2NvbHVtbi5maWVsZC50b1N0cmluZygpXS5vcGVyYXRvclwiXG4gICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0RmlsdGVyT3BlcmF0b3IoY29sdW1uLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3BlcmF0b3Igb2YgZ2V0T3BlcmF0b3JzKGNvbHVtbilcIiBbbmdWYWx1ZV09XCJvcGVyYXRvclwiPnt7IGdldE9wZXJhdG9yTGFiZWwob3BlcmF0b3IpIH19PC9vcHRpb24+XG4gICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm1iLWdyaWRfX2ZpbHRlci1pbnB1dFwiXG4gICAgICAgICAgICAgICAgW3R5cGVdPVwiY29sdW1uLnR5cGUgPT09ICdudW1iZXInID8gJ251bWJlcicgOiBjb2x1bW4udHlwZSA9PT0gJ2RhdGUnID8gJ2RhdGUnIDogJ3RleHQnXCJcbiAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiY29sdW1uLnRpdGxlXCJcbiAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmaWx0ZXJzQnlGaWVsZFtjb2x1bW4uZmllbGQudG9TdHJpbmcoKV0udmFsdWVcIlxuICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldEZpbHRlclZhbHVlKGNvbHVtbiwgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aCAqbmdJZj1cInNob3dDb21tYW5kQ29sdW1uXCIgY2xhc3M9XCJtYi1ncmlkX19jb21tYW5kLWNlbGxcIj48L3RoPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90aGVhZD5cblxuICAgICAgPHRib2R5PlxuICAgICAgICA8dHIgKm5nSWY9XCIhcHJvY2Vzc2VkLmRhdGEubGVuZ3RoICYmICFsb2FkaW5nXCIgY2xhc3M9XCJtYi1ncmlkX19lbXB0eS1yb3dcIj5cbiAgICAgICAgICA8dGQgY2xhc3M9XCJtYi1ncmlkX19lbXB0eVwiIFthdHRyLmNvbHNwYW5dPVwiY29sdW1uU3BhblwiPnt7IG5vUmVjb3Jkc1RleHQgfHwgbWVzc2FnZXMubm9SZWNvcmRzIH19PC90ZD5cbiAgICAgICAgPC90cj5cblxuICAgICAgICA8dHIgKm5nSWY9XCJpc05ld1Jvd0VkaXRpbmcoKSAmJiBlZGl0aW5nTW9kZWxcIiBjbGFzcz1cIm1iLWdyaWRfX3JvdyBtYi1ncmlkX19yb3ctLWVkaXRpbmcgbWItZ3JpZF9fcm93LS1uZXdcIj5cbiAgICAgICAgICA8dGQgKm5nSWY9XCJleHBhbmRhYmxlXCIgY2xhc3M9XCJtYi1ncmlkX19zZWxlY3QtY2VsbFwiPjwvdGQ+XG4gICAgICAgICAgPHRkICpuZ0lmPVwic2VsZWN0YWJsZVwiIGNsYXNzPVwibWItZ3JpZF9fc2VsZWN0LWNlbGxcIj48L3RkPlxuICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHZpc2libGVDb2x1bW5zOyB0cmFja0J5OiB0cmFja0NvbHVtblwiIGNsYXNzPVwibWItZ3JpZF9fY2VsbFwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJlZGl0b3JUZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IGNvbHVtbjogY29sdW1uLCByb3c6IGVkaXRpbmdNb2RlbCwgcm93SW5kZXg6IGVkaXRpbmdSb3dJbmRleCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQgKm5nSWY9XCJzaG93Q29tbWFuZENvbHVtblwiIGNsYXNzPVwibWItZ3JpZF9fY2VsbCBtYi1ncmlkX19jb21tYW5kLWNlbGxcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibWItZ3JpZF9fY29tbWFuZFwiIChjbGljayk9XCJzYXZlRWRpdCgkZXZlbnQpXCI+e3sgbWVzc2FnZXMuc2F2ZSB9fTwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX19jb21tYW5kXCIgKGNsaWNrKT1cImNhbmNlbEVkaXRSb3coJGV2ZW50KVwiPnt7IG1lc3NhZ2VzLmNhbmNlbCB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcm93IG9mIHByb2Nlc3NlZC5kYXRhOyB0cmFja0J5OiB0cmFja1Jvd1wiPlxuICAgICAgICAgIDx0ciAqbmdJZj1cInJvdy5raW5kID09PSAnZ3JvdXAnXCIgY2xhc3M9XCJtYi1ncmlkX19ncm91cC1yb3dcIiAoY2xpY2spPVwidG9nZ2xlR3JvdXBSb3cocm93KVwiPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwibWItZ3JpZF9fZ3JvdXAtY2VsbFwiIFthdHRyLmNvbHNwYW5dPVwiY29sdW1uU3BhblwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1iLWdyaWRfX2dyb3VwLXRvZ2dsZVwiPnt7IHJvdy5leHBhbmRlZCA/ICfilr4nIDogJ+KWuCcgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIFtzdHlsZS5wYWRkaW5nLWlubGluZS1zdGFydC5weF09XCJyb3cubGV2ZWwgKiAxOFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHN0cm9uZz57eyByb3cuZmllbGQgfX06PC9zdHJvbmc+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IHJvdy52YWx1ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNtYWxsPih7eyByb3cuY291bnQgfX0pPC9zbWFsbD5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPC90cj5cblxuICAgICAgICAgIDx0clxuICAgICAgICAgICAgKm5nSWY9XCJyb3cua2luZCA9PT0gJ2RhdGEnXCJcbiAgICAgICAgICAgIGNsYXNzPVwibWItZ3JpZF9fcm93XCJcbiAgICAgICAgICAgIFtjbGFzcy5tYi1ncmlkX19yb3ctLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQocm93LmRhdGFJdGVtKVwiXG4gICAgICAgICAgICBbY2xhc3MubWItZ3JpZF9fcm93LS1lZGl0aW5nXT1cImlzRWRpdGluZyhyb3cuZGF0YUl0ZW0pXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldFJvd0NsYXNzKHJvdy5kYXRhSXRlbSwgcm93LnJvd0luZGV4KVwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25Sb3dDbGljayhyb3cuZGF0YUl0ZW0sIHJvdy5yb3dJbmRleClcIj5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cImV4cGFuZGFibGVcIiBjbGFzcz1cIm1iLWdyaWRfX3NlbGVjdC1jZWxsXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX2V4cGFuZC1idXR0b25cIiAoY2xpY2spPVwidG9nZ2xlRGV0YWlsKHJvdy5kYXRhSXRlbSwgcm93LnJvd0luZGV4LCAkZXZlbnQpXCI+e3sgaXNEZXRhaWxFeHBhbmRlZChyb3cuZGF0YUl0ZW0pID8gJ+KWvicgOiAn4pa4JyB9fTwvYnV0dG9uPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cInNlbGVjdGFibGVcIiBjbGFzcz1cIm1iLWdyaWRfX3NlbGVjdC1jZWxsXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImlzU2VsZWN0ZWQocm93LmRhdGFJdGVtKVwiXG4gICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ0b2dnbGVSb3cocm93LmRhdGFJdGVtLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIm1lc3NhZ2VzLnNlbGVjdFJvd1wiIC8+XG4gICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiB2aXNpYmxlQ29sdW1uczsgdHJhY2tCeTogdHJhY2tDb2x1bW5cIlxuICAgICAgICAgICAgICBjbGFzcz1cIm1iLWdyaWRfX2NlbGxcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJbJ21iLWdyaWRfX2NlbGwtLScgKyAoY29sdW1uLmFsaWduIHx8ICdzdGFydCcpLCBnZXRDZWxsQ2xhc3Mocm93LmRhdGFJdGVtLCBjb2x1bW4sIHJvdy5yb3dJbmRleCksIGdldENvbHVtbkNsYXNzKGNvbHVtbildXCJcbiAgICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0Q29sdW1uU3R5bGUoY29sdW1uKVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJvbkNlbGxDbGljayhyb3cuZGF0YUl0ZW0sIGNvbHVtbiwgcm93LnJvd0luZGV4KVwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNFZGl0aW5nKHJvdy5kYXRhSXRlbSkgJiYgY2FuRWRpdENvbHVtbihjb2x1bW4pOyBlbHNlIHJlYWRvbmx5Q2VsbFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiZWRpdG9yVGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBjb2x1bW46IGNvbHVtbiwgcm93OiBlZGl0aW5nTW9kZWwsIHJvd0luZGV4OiByb3cucm93SW5kZXggfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNyZWFkb25seUNlbGw+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENlbGxUZW1wbGF0ZShjb2x1bW4pIGFzIGNlbGxUcGw7IGVsc2UgZGVmYXVsdENlbGxcIj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY2VsbFRwbFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogcm93LmRhdGFJdGVtLCBkYXRhSXRlbTogcm93LmRhdGFJdGVtLCBjb2x1bW46IGNvbHVtbiwgdmFsdWU6IGdldFZhbHVlKHJvdy5kYXRhSXRlbSwgY29sdW1uLCByb3cucm93SW5kZXgpLCByb3dJbmRleDogcm93LnJvd0luZGV4LCBlZGl0aW5nOiBpc0VkaXRpbmcocm93LmRhdGFJdGVtKSB9XCI+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRDZWxsPnt7IGZvcm1hdENlbGwocm93LmRhdGFJdGVtLCBjb2x1bW4sIHJvdy5yb3dJbmRleCkgfX08L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC90ZD5cblxuICAgICAgICAgICAgPHRkICpuZ0lmPVwic2hvd0NvbW1hbmRDb2x1bW5cIiBjbGFzcz1cIm1iLWdyaWRfX2NlbGwgbWItZ3JpZF9fY29tbWFuZC1jZWxsXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNFZGl0aW5nKHJvdy5kYXRhSXRlbSk7IGVsc2UgcmVhZG9ubHlDb21tYW5kc1wiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibWItZ3JpZF9fY29tbWFuZFwiIChjbGljayk9XCJzYXZlRWRpdCgkZXZlbnQpXCI+e3sgbWVzc2FnZXMuc2F2ZSB9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibWItZ3JpZF9fY29tbWFuZFwiIChjbGljayk9XCJjYW5jZWxFZGl0Um93KCRldmVudClcIj57eyBtZXNzYWdlcy5jYW5jZWwgfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcmVhZG9ubHlDb21tYW5kcz5cbiAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiZWRpdGFibGVcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX19jb21tYW5kXCIgKGNsaWNrKT1cInN0YXJ0RWRpdChyb3cuZGF0YUl0ZW0sIHJvdy5yb3dJbmRleCwgJGV2ZW50KVwiPnt7IG1lc3NhZ2VzLmVkaXQgfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiYWxsb3dEZWxldGVcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX19jb21tYW5kIG1iLWdyaWRfX2NvbW1hbmQtLWRhbmdlclwiIChjbGljayk9XCJyZW1vdmVSb3cocm93LmRhdGFJdGVtLCByb3cucm93SW5kZXgsICRldmVudClcIj57eyBtZXNzYWdlcy5kZWxldGUgfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPC90cj5cblxuICAgICAgICAgIDx0ciAqbmdJZj1cInJvdy5raW5kID09PSAnZGF0YScgJiYgaXNEZXRhaWxFeHBhbmRlZChyb3cuZGF0YUl0ZW0pICYmIGRldGFpbFRlbXBsYXRlPy50ZW1wbGF0ZVJlZiBhcyBkZXRhaWxUcGxcIiBjbGFzcz1cIm1iLWdyaWRfX2RldGFpbC1yb3dcIj5cbiAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHVtblNwYW5cIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRldGFpbFRwbFwiXG4gICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiByb3cuZGF0YUl0ZW0sIGRhdGFJdGVtOiByb3cuZGF0YUl0ZW0sIHJvd0luZGV4OiByb3cucm93SW5kZXgsIGV4cGFuZGVkOiBpc0RldGFpbEV4cGFuZGVkKHJvdy5kYXRhSXRlbSkgfVwiPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3Rib2R5PlxuXG4gICAgICA8dGZvb3QgKm5nSWY9XCJzaG93Rm9vdGVyXCI+XG4gICAgICAgIDx0ciBjbGFzcz1cIm1iLWdyaWRfX2Zvb3Rlci1yb3dcIj5cbiAgICAgICAgICA8dGQgKm5nSWY9XCJleHBhbmRhYmxlXCIgY2xhc3M9XCJtYi1ncmlkX19zZWxlY3QtY2VsbFwiPjwvdGQ+XG4gICAgICAgICAgPHRkICpuZ0lmPVwic2VsZWN0YWJsZVwiIGNsYXNzPVwibWItZ3JpZF9fc2VsZWN0LWNlbGxcIj48L3RkPlxuICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIHZpc2libGVDb2x1bW5zOyB0cmFja0J5OiB0cmFja0NvbHVtblwiIGNsYXNzPVwibWItZ3JpZF9fZm9vdGVyLWNlbGxcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRGb290ZXJUZW1wbGF0ZShjb2x1bW4pIGFzIGZvb3RlclRwbDsgZWxzZSBkZWZhdWx0Rm9vdGVyXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiZm9vdGVyVHBsXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiBjb2x1bW4sIGNvbHVtbjogY29sdW1uLCBhZ2dyZWdhdGVzOiBwcm9jZXNzZWQuYWdncmVnYXRlcyB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEZvb3Rlcj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJwcm9jZXNzZWQuYWdncmVnYXRlc1tjb2x1bW4uZmllbGQudG9TdHJpbmcoKV0gYXMgYWdnc1wiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGtleSBvZiBhZ2dzIHwga2V5dmFsdWVcIj57eyBrZXkua2V5IH19OiB7eyBrZXkudmFsdWUgfCBudW1iZXIgfX0gPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQgKm5nSWY9XCJzaG93Q29tbWFuZENvbHVtblwiIGNsYXNzPVwibWItZ3JpZF9fY29tbWFuZC1jZWxsXCI+PC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGZvb3Q+XG4gICAgPC90YWJsZT5cbiAgPC9kaXY+XG5cblxuICA8bmctdGVtcGxhdGUgI2VkaXRvclRlbXBsYXRlIGxldC1jb2x1bW49XCJjb2x1bW5cIiBsZXQtcm93PVwicm93XCIgbGV0LXJvd0luZGV4PVwicm93SW5kZXhcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29sdW1uLmVkaXRUZW1wbGF0ZSBhcyBlZGl0VHBsOyBlbHNlIGRlZmF1bHRFZGl0b3JcIj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiZWRpdFRwbFwiXG4gICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogcm93LCBkYXRhSXRlbTogcm93LCBjb2x1bW46IGNvbHVtbiwgdmFsdWU6IGdldEVkaXRWYWx1ZShjb2x1bW4pLCByb3dJbmRleDogcm93SW5kZXgsIHNldFZhbHVlOiBzZXRFZGl0VmFsdWUuYmluZCh0aGlzLCBjb2x1bW4pLCBlcnJvcnM6IHZhbGlkYXRpb25FcnJvcnMgfVwiPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RWRpdG9yPlxuICAgICAgPHNlbGVjdFxuICAgICAgICAqbmdJZj1cImdldEVkaXRvclR5cGUoY29sdW1uKSA9PT0gJ3NlbGVjdCc7IGVsc2Ugbm9uU2VsZWN0RWRpdG9yXCJcbiAgICAgICAgY2xhc3M9XCJtYi1ncmlkX19lZGl0b3JcIlxuICAgICAgICBbbmdNb2RlbF09XCJnZXRFZGl0VmFsdWUoY29sdW1uKVwiXG4gICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldEVkaXRWYWx1ZShjb2x1bW4sICRldmVudClcIj5cbiAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGNvbHVtbi5lZGl0b3JPcHRpb25zIHx8IFtdXCIgW25nVmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICA8L3NlbGVjdD5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjbm9uU2VsZWN0RWRpdG9yPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICAqbmdJZj1cImdldEVkaXRvclR5cGUoY29sdW1uKSAhPT0gJ2NoZWNrYm94JzsgZWxzZSBjaGVja2JveEVkaXRvclwiXG4gICAgICAgICAgY2xhc3M9XCJtYi1ncmlkX19lZGl0b3JcIlxuICAgICAgICAgIFt0eXBlXT1cImdldEVkaXRvclR5cGUoY29sdW1uKSA9PT0gJ251bWJlcicgPyAnbnVtYmVyJyA6IGdldEVkaXRvclR5cGUoY29sdW1uKSA9PT0gJ2RhdGUnID8gJ2RhdGUnIDogJ3RleHQnXCJcbiAgICAgICAgICBbbmdNb2RlbF09XCJnZXRFZGl0VmFsdWUoY29sdW1uKVwiXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0RWRpdFZhbHVlKGNvbHVtbiwgJGV2ZW50KVwiIC8+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjY2hlY2tib3hFZGl0b3I+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtuZ01vZGVsXT1cImdldEVkaXRWYWx1ZShjb2x1bW4pXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0RWRpdFZhbHVlKGNvbHVtbiwgJGV2ZW50KVwiIC8+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPHNtYWxsICpuZ0lmPVwidmFsaWRhdGlvbkVycm9yc1tjb2x1bW4uZmllbGQudG9TdHJpbmcoKV1cIiBjbGFzcz1cIm1iLWdyaWRfX2Vycm9yXCI+e3sgdmFsaWRhdGlvbkVycm9yc1tjb2x1bW4uZmllbGQudG9TdHJpbmcoKV0gfX08L3NtYWxsPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPGRpdiAqbmdJZj1cInBhZ2VhYmxlXCIgY2xhc3M9XCJtYi1ncmlkX19wYWdlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJtYi1ncmlkX19wYWdlci1pbmZvXCI+e3sgcGFnZXJJbmZvVGV4dCgpIH19PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm1iLWdyaWRfX3BhZ2VyLWFjdGlvbnNcIj5cbiAgICAgIDxzZWxlY3QgY2xhc3M9XCJtYi1ncmlkX19wYWdlLXNpemVcIiBbbmdNb2RlbF09XCJwYWdlU2l6ZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoYW5nZVBhZ2VTaXplKCRldmVudClcIj5cbiAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHBhZ2VTaXplT3B0aW9uc1wiIFtuZ1ZhbHVlXT1cIm9wdGlvblwiPnt7IG9wdGlvbiB9fTwvb3B0aW9uPlxuICAgICAgPC9zZWxlY3Q+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm1iLWdyaWRfX3BhZ2VyLWJ1dHRvblwiIFtkaXNhYmxlZF09XCJwYWdlSW5kZXggPT09IDBcIiAoY2xpY2spPVwiY2hhbmdlUGFnZSgwKVwiPnt7IG1lc3NhZ2VzLnBhZ2VyRmlyc3QgfX08L2J1dHRvbj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibWItZ3JpZF9fcGFnZXItYnV0dG9uXCIgW2Rpc2FibGVkXT1cInBhZ2VJbmRleCA9PT0gMFwiIChjbGljayk9XCJjaGFuZ2VQYWdlKHBhZ2VJbmRleCAtIDEpXCI+e3sgbWVzc2FnZXMucGFnZXJQcmV2aW91cyB9fTwvYnV0dG9uPlxuICAgICAgPHNwYW4gY2xhc3M9XCJtYi1ncmlkX19wYWdlLWN1cnJlbnRcIj57eyBwYWdlSW5kZXggKyAxIH19IC8ge3sgcGFnZUNvdW50IH19PC9zcGFuPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX19wYWdlci1idXR0b25cIiBbZGlzYWJsZWRdPVwicGFnZUluZGV4ID49IHBhZ2VDb3VudCAtIDFcIiAoY2xpY2spPVwiY2hhbmdlUGFnZShwYWdlSW5kZXggKyAxKVwiPnt7IG1lc3NhZ2VzLnBhZ2VyTmV4dCB9fTwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJtYi1ncmlkX19wYWdlci1idXR0b25cIiBbZGlzYWJsZWRdPVwicGFnZUluZGV4ID49IHBhZ2VDb3VudCAtIDFcIiAoY2xpY2spPVwiY2hhbmdlUGFnZShwYWdlQ291bnQgLSAxKVwiPnt7IG1lc3NhZ2VzLnBhZ2VyTGFzdCB9fTwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19