@aquera/ngx-smart-table 0.0.2-alpha
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.
- package/README.md +152 -0
- package/aquera-ngx-smart-table.d.ts +5 -0
- package/esm2020/aquera-ngx-smart-table.mjs +5 -0
- package/esm2020/lib/builder/components/builder-preview/builder-preview.component.mjs +63 -0
- package/esm2020/lib/builder/components/builder-toolbar/builder-toolbar.component.mjs +115 -0
- package/esm2020/lib/builder/components/column-editor/column-editor.component.mjs +206 -0
- package/esm2020/lib/builder/components/column-list/column-list.component.mjs +125 -0
- package/esm2020/lib/builder/components/definition-builder/definition-builder.component.mjs +105 -0
- package/esm2020/lib/builder/components/table-config-editor/table-config-editor.component.mjs +132 -0
- package/esm2020/lib/builder/definition-builder.module.mjs +70 -0
- package/esm2020/lib/builder/models/builder-state.interface.mjs +5 -0
- package/esm2020/lib/builder/services/definition-builder.service.mjs +251 -0
- package/esm2020/lib/builder/services/definition-export.service.mjs +167 -0
- package/esm2020/lib/builder/services/definition-import.service.mjs +193 -0
- package/esm2020/lib/builder/services/sample-data-generator.service.mjs +126 -0
- package/esm2020/lib/builder/utils/config-validator.util.mjs +165 -0
- package/esm2020/lib/builder/utils/typescript-generator.util.mjs +206 -0
- package/esm2020/lib/editors/index.mjs +9 -0
- package/esm2020/lib/editors/nile-autocomplete-editor.mjs +228 -0
- package/esm2020/lib/editors/nile-calendar-editor.mjs +214 -0
- package/esm2020/lib/editors/nile-date-picker-editor.mjs +227 -0
- package/esm2020/lib/editors/nile-input-editor.mjs +235 -0
- package/esm2020/lib/editors/nile-select-editor.mjs +317 -0
- package/esm2020/lib/factories/column-config.factory.mjs +231 -0
- package/esm2020/lib/models/autosave-config.interface.mjs +8 -0
- package/esm2020/lib/models/base-column-config.class.mjs +253 -0
- package/esm2020/lib/models/cell-strategies.interface.mjs +6 -0
- package/esm2020/lib/models/cell-types.mjs +147 -0
- package/esm2020/lib/models/column-action.interface.mjs +6 -0
- package/esm2020/lib/models/column-config.interface.mjs +43 -0
- package/esm2020/lib/models/column-config.utils.mjs +101 -0
- package/esm2020/lib/models/row-action.interface.mjs +5 -0
- package/esm2020/lib/models/row-validator.interface.mjs +2 -0
- package/esm2020/lib/models/schema-validation.interface.mjs +2 -0
- package/esm2020/lib/models/sheet-action.interface.mjs +5 -0
- package/esm2020/lib/models/sheet-config.interface.mjs +5 -0
- package/esm2020/lib/models/table-config.interface.mjs +106 -0
- package/esm2020/lib/models/table-validator.interface.mjs +2 -0
- package/esm2020/lib/models/workbook-action.interface.mjs +5 -0
- package/esm2020/lib/models/workbook-config.interface.mjs +5 -0
- package/esm2020/lib/renderer/components/st-add-column-button/st-add-column-button.component.mjs +24 -0
- package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +391 -0
- package/esm2020/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.mjs +103 -0
- package/esm2020/lib/renderer/components/st-column-filter/st-column-filter.component.mjs +383 -0
- package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +232 -0
- package/esm2020/lib/renderer/components/st-column-visibility/st-column-visibility.component.mjs +97 -0
- package/esm2020/lib/renderer/components/st-header/st-header.component.mjs +157 -0
- package/esm2020/lib/renderer/components/st-pagination/st-pagination.component.mjs +87 -0
- package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +167 -0
- package/esm2020/lib/renderer/components/st-sheet/st-sheet.component.mjs +165 -0
- package/esm2020/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.mjs +112 -0
- package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +1246 -0
- package/esm2020/lib/renderer/components/st-table-actions/st-table-actions.component.mjs +171 -0
- package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +489 -0
- package/esm2020/lib/renderer/directives/click-outside.directive.mjs +28 -0
- package/esm2020/lib/renderer/directives/st-column-resize.directive.mjs +108 -0
- package/esm2020/lib/renderer/directives/st-keyboard-navigation.directive.mjs +73 -0
- package/esm2020/lib/renderer/models/cell-state.interface.mjs +66 -0
- package/esm2020/lib/renderer/models/cell.class.mjs +389 -0
- package/esm2020/lib/renderer/models/row-validation-state.interface.mjs +7 -0
- package/esm2020/lib/renderer/models/sheet-state.class.mjs +90 -0
- package/esm2020/lib/renderer/models/sheet-state.interface.mjs +5 -0
- package/esm2020/lib/renderer/models/table-state.class.mjs +841 -0
- package/esm2020/lib/renderer/models/table-state.interface.mjs +5 -0
- package/esm2020/lib/renderer/models/table-types.mjs +29 -0
- package/esm2020/lib/renderer/models/table-validation-state.interface.mjs +7 -0
- package/esm2020/lib/renderer/models/workbook-state.class.mjs +174 -0
- package/esm2020/lib/renderer/models/workbook-state.interface.mjs +5 -0
- package/esm2020/lib/renderer/models/z-index.enum.mjs +55 -0
- package/esm2020/lib/schemas/table-config.schema.mjs +472 -0
- package/esm2020/lib/services/autosave.service.mjs +92 -0
- package/esm2020/lib/services/custom-validation-rules.util.mjs +124 -0
- package/esm2020/lib/services/json-schema-validator.service.mjs +216 -0
- package/esm2020/lib/services/row-validation.service.mjs +42 -0
- package/esm2020/lib/services/validation-logger.service.mjs +177 -0
- package/esm2020/lib/services/virtual-scroll.service.mjs +52 -0
- package/esm2020/lib/shared/shared-table-components.module.mjs +35 -0
- package/esm2020/lib/smart-table.module.mjs +124 -0
- package/esm2020/lib/strategies/default-editors.mjs +433 -0
- package/esm2020/lib/strategies/default-formatters.mjs +238 -0
- package/esm2020/lib/strategies/default-validators.mjs +327 -0
- package/esm2020/public-api.mjs +146 -0
- package/fesm2015/aquera-ngx-smart-table.mjs +11860 -0
- package/fesm2015/aquera-ngx-smart-table.mjs.map +1 -0
- package/fesm2020/aquera-ngx-smart-table.mjs +11897 -0
- package/fesm2020/aquera-ngx-smart-table.mjs.map +1 -0
- package/lib/builder/components/builder-preview/builder-preview.component.d.ts +31 -0
- package/lib/builder/components/builder-toolbar/builder-toolbar.component.d.ts +53 -0
- package/lib/builder/components/column-editor/column-editor.component.d.ts +69 -0
- package/lib/builder/components/column-list/column-list.component.d.ts +65 -0
- package/lib/builder/components/definition-builder/definition-builder.component.d.ts +58 -0
- package/lib/builder/components/table-config-editor/table-config-editor.component.d.ts +32 -0
- package/lib/builder/definition-builder.module.d.ts +15 -0
- package/lib/builder/models/builder-state.interface.d.ts +93 -0
- package/lib/builder/services/definition-builder.service.d.ts +80 -0
- package/lib/builder/services/definition-export.service.d.ts +59 -0
- package/lib/builder/services/definition-import.service.d.ts +31 -0
- package/lib/builder/services/sample-data-generator.service.d.ts +41 -0
- package/lib/builder/utils/config-validator.util.d.ts +32 -0
- package/lib/builder/utils/typescript-generator.util.d.ts +29 -0
- package/lib/editors/index.d.ts +8 -0
- package/lib/editors/nile-autocomplete-editor.d.ts +102 -0
- package/lib/editors/nile-calendar-editor.d.ts +89 -0
- package/lib/editors/nile-date-picker-editor.d.ts +95 -0
- package/lib/editors/nile-input-editor.d.ts +67 -0
- package/lib/editors/nile-select-editor.d.ts +109 -0
- package/lib/factories/column-config.factory.d.ts +73 -0
- package/lib/models/autosave-config.interface.d.ts +23 -0
- package/lib/models/base-column-config.class.d.ts +115 -0
- package/lib/models/cell-strategies.interface.d.ts +181 -0
- package/lib/models/cell-types.d.ts +337 -0
- package/lib/models/column-action.interface.d.ts +86 -0
- package/lib/models/column-config.interface.d.ts +272 -0
- package/lib/models/column-config.utils.d.ts +37 -0
- package/lib/models/row-action.interface.d.ts +86 -0
- package/lib/models/row-validator.interface.d.ts +37 -0
- package/lib/models/schema-validation.interface.d.ts +42 -0
- package/lib/models/sheet-action.interface.d.ts +59 -0
- package/lib/models/sheet-config.interface.d.ts +41 -0
- package/lib/models/table-config.interface.d.ts +245 -0
- package/lib/models/table-validator.interface.d.ts +40 -0
- package/lib/models/workbook-action.interface.d.ts +90 -0
- package/lib/models/workbook-config.interface.d.ts +107 -0
- package/lib/renderer/components/st-add-column-button/st-add-column-button.component.d.ts +9 -0
- package/lib/renderer/components/st-cell/st-cell.component.d.ts +69 -0
- package/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.d.ts +39 -0
- package/lib/renderer/components/st-column-filter/st-column-filter.component.d.ts +139 -0
- package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +81 -0
- package/lib/renderer/components/st-column-visibility/st-column-visibility.component.d.ts +44 -0
- package/lib/renderer/components/st-header/st-header.component.d.ts +93 -0
- package/lib/renderer/components/st-pagination/st-pagination.component.d.ts +42 -0
- package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +67 -0
- package/lib/renderer/components/st-sheet/st-sheet.component.d.ts +98 -0
- package/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.d.ts +58 -0
- package/lib/renderer/components/st-table/st-table.component.d.ts +349 -0
- package/lib/renderer/components/st-table-actions/st-table-actions.component.d.ts +77 -0
- package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +235 -0
- package/lib/renderer/directives/click-outside.directive.d.ts +10 -0
- package/lib/renderer/directives/st-column-resize.directive.d.ts +44 -0
- package/lib/renderer/directives/st-keyboard-navigation.directive.d.ts +15 -0
- package/lib/renderer/models/cell-state.interface.d.ts +118 -0
- package/lib/renderer/models/cell.class.d.ts +174 -0
- package/lib/renderer/models/row-validation-state.interface.d.ts +27 -0
- package/lib/renderer/models/sheet-state.class.d.ts +67 -0
- package/lib/renderer/models/sheet-state.interface.d.ts +55 -0
- package/lib/renderer/models/table-state.class.d.ts +313 -0
- package/lib/renderer/models/table-state.interface.d.ts +18 -0
- package/lib/renderer/models/table-types.d.ts +228 -0
- package/lib/renderer/models/table-validation-state.interface.d.ts +34 -0
- package/lib/renderer/models/workbook-state.class.d.ts +117 -0
- package/lib/renderer/models/workbook-state.interface.d.ts +71 -0
- package/lib/renderer/models/z-index.enum.d.ts +44 -0
- package/lib/schemas/table-config.schema.d.ts +455 -0
- package/lib/services/autosave.service.d.ts +73 -0
- package/lib/services/custom-validation-rules.util.d.ts +12 -0
- package/lib/services/json-schema-validator.service.d.ts +49 -0
- package/lib/services/row-validation.service.d.ts +17 -0
- package/lib/services/validation-logger.service.d.ts +87 -0
- package/lib/services/virtual-scroll.service.d.ts +44 -0
- package/lib/shared/shared-table-components.module.d.ts +9 -0
- package/lib/smart-table.module.d.ts +26 -0
- package/lib/strategies/default-editors.d.ts +109 -0
- package/lib/strategies/default-formatters.d.ts +116 -0
- package/lib/strategies/default-validators.d.ts +113 -0
- package/package.json +42 -0
- package/public-api.d.ts +70 -0
- package/src/lib/builder/README.md +30 -0
- package/src/lib/editors/README.md +303 -0
- package/src/lib/renderer/components/st-column-filter/README.md +286 -0
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TableState - Reactive state management for table operations
|
|
3
|
+
* Event-driven architecture: tracks state, emits events, consumer handles async data operations
|
|
4
|
+
*/
|
|
5
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
6
|
+
import { map, distinctUntilChanged } from 'rxjs/operators';
|
|
7
|
+
import { SortDirection, FilterOperator } from './table-types';
|
|
8
|
+
import { NavigationDirection } from '../../models/cell-types';
|
|
9
|
+
/**
|
|
10
|
+
* TableState class - Column-driven, event-emitting state management
|
|
11
|
+
* NO data manipulation - only state tracking and event emission
|
|
12
|
+
*/
|
|
13
|
+
export class TableState {
|
|
14
|
+
/**
|
|
15
|
+
* Constructor
|
|
16
|
+
* @param columns Reference to columns array
|
|
17
|
+
* @param config Initial configuration
|
|
18
|
+
*/
|
|
19
|
+
constructor(columns, config) {
|
|
20
|
+
// Row number column width for sticky offset calculation
|
|
21
|
+
this._rowNumberWidth = 0;
|
|
22
|
+
// Settings column width for sticky offset calculation
|
|
23
|
+
this._settingsColumnWidth = 0;
|
|
24
|
+
// Dimensions for boundary checking
|
|
25
|
+
this._rowCount = 0;
|
|
26
|
+
this._columnCount = 0;
|
|
27
|
+
this._columns = columns;
|
|
28
|
+
this._initialConfig = {
|
|
29
|
+
initialPage: config?.initialPage ?? 0,
|
|
30
|
+
pageSize: config?.pageSize ?? 25
|
|
31
|
+
};
|
|
32
|
+
// Initialize pagination state
|
|
33
|
+
this._pagination$ = new BehaviorSubject({
|
|
34
|
+
currentPage: this._initialConfig.initialPage,
|
|
35
|
+
pageSize: this._initialConfig.pageSize,
|
|
36
|
+
totalItems: 0,
|
|
37
|
+
totalPages: 0
|
|
38
|
+
});
|
|
39
|
+
// Initialize state change subject
|
|
40
|
+
this._stateChange$ = new Subject();
|
|
41
|
+
// Initialize focus and editing position tracking
|
|
42
|
+
this._focusedCellPosition$ = new BehaviorSubject(null);
|
|
43
|
+
this.focusedCellPosition$ = this._focusedCellPosition$.asObservable();
|
|
44
|
+
this._editingCellPosition$ = new BehaviorSubject(null);
|
|
45
|
+
this.editingCellPosition$ = this._editingCellPosition$.asObservable();
|
|
46
|
+
// Initialize validation state
|
|
47
|
+
this._tableValidationState$ = new BehaviorSubject({
|
|
48
|
+
isValid: true,
|
|
49
|
+
totalRows: 0,
|
|
50
|
+
validRows: 0,
|
|
51
|
+
invalidRows: 0,
|
|
52
|
+
rowStates: new Map(),
|
|
53
|
+
lastUpdated: new Date()
|
|
54
|
+
});
|
|
55
|
+
this.tableValidationState$ = this._tableValidationState$.asObservable();
|
|
56
|
+
this._columnCount = columns.filter(c => c.visible !== false).length;
|
|
57
|
+
// Setup observables
|
|
58
|
+
this.paginationChange$ = this._pagination$.asObservable().pipe(distinctUntilChanged((a, b) => a.currentPage === b.currentPage &&
|
|
59
|
+
a.pageSize === b.pageSize &&
|
|
60
|
+
a.totalItems === b.totalItems));
|
|
61
|
+
this.state$ = this._pagination$.pipe(map(() => this.buildStateSnapshot()));
|
|
62
|
+
this.stateChange$ = this._stateChange$.asObservable();
|
|
63
|
+
// Clear focus/editing on pagination changes
|
|
64
|
+
this.paginationChange$.subscribe(() => {
|
|
65
|
+
this.clearFocus();
|
|
66
|
+
this.clearEditingCell();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// STATE ACCESS METHODS
|
|
71
|
+
// ============================================================================
|
|
72
|
+
/**
|
|
73
|
+
* Get current state snapshot
|
|
74
|
+
*/
|
|
75
|
+
getState() {
|
|
76
|
+
return this.buildStateSnapshot();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get current pagination state
|
|
80
|
+
*/
|
|
81
|
+
getPagination() {
|
|
82
|
+
return { ...this._pagination$.value };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get columns with sorting enabled
|
|
86
|
+
*/
|
|
87
|
+
getSortedColumns() {
|
|
88
|
+
return this._columns.filter(col => col.sortEnabled === true);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get columns with filtering enabled
|
|
92
|
+
*/
|
|
93
|
+
getFilteredColumns() {
|
|
94
|
+
return this._columns.filter(col => col.filterConfig?.enabled === true);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get current columns reference
|
|
98
|
+
*/
|
|
99
|
+
getColumns() {
|
|
100
|
+
return this._columns;
|
|
101
|
+
}
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// PAGINATION METHODS
|
|
104
|
+
// ============================================================================
|
|
105
|
+
/**
|
|
106
|
+
* Set current page
|
|
107
|
+
* @param page Page number (0-indexed)
|
|
108
|
+
*/
|
|
109
|
+
setPage(page) {
|
|
110
|
+
const currentState = this._pagination$.value;
|
|
111
|
+
if (page < 0 || page >= currentState.totalPages) {
|
|
112
|
+
console.warn(`Invalid page number: ${page}. Valid range: 0-${currentState.totalPages - 1}`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this._pagination$.next({
|
|
116
|
+
...currentState,
|
|
117
|
+
currentPage: page
|
|
118
|
+
});
|
|
119
|
+
this.emitStateChange('pagination');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Set page size
|
|
123
|
+
* @param size Number of items per page
|
|
124
|
+
*/
|
|
125
|
+
setPageSize(size) {
|
|
126
|
+
if (size <= 0) {
|
|
127
|
+
console.warn(`Invalid page size: ${size}. Must be greater than 0.`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const currentState = this._pagination$.value;
|
|
131
|
+
const newTotalPages = this.calculateTotalPages(currentState.totalItems, size);
|
|
132
|
+
this._pagination$.next({
|
|
133
|
+
currentPage: 0,
|
|
134
|
+
pageSize: size,
|
|
135
|
+
totalItems: currentState.totalItems,
|
|
136
|
+
totalPages: newTotalPages
|
|
137
|
+
});
|
|
138
|
+
this.emitStateChange('pagination');
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Set total items (called after API response)
|
|
142
|
+
* @param total Total number of items
|
|
143
|
+
*/
|
|
144
|
+
setTotalItems(total) {
|
|
145
|
+
const currentState = this._pagination$.value;
|
|
146
|
+
const newTotalPages = this.calculateTotalPages(total, currentState.pageSize);
|
|
147
|
+
this._pagination$.next({
|
|
148
|
+
...currentState,
|
|
149
|
+
totalItems: total,
|
|
150
|
+
totalPages: newTotalPages
|
|
151
|
+
});
|
|
152
|
+
// Don't emit state change here - this is called after data load
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Go to next page
|
|
156
|
+
*/
|
|
157
|
+
nextPage() {
|
|
158
|
+
const currentState = this._pagination$.value;
|
|
159
|
+
if (this.hasNextPage()) {
|
|
160
|
+
this.setPage(currentState.currentPage + 1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Go to previous page
|
|
165
|
+
*/
|
|
166
|
+
previousPage() {
|
|
167
|
+
const currentState = this._pagination$.value;
|
|
168
|
+
if (this.hasPreviousPage()) {
|
|
169
|
+
this.setPage(currentState.currentPage - 1);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Go to first page
|
|
174
|
+
*/
|
|
175
|
+
firstPage() {
|
|
176
|
+
this.setPage(0);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Go to last page
|
|
180
|
+
*/
|
|
181
|
+
lastPage() {
|
|
182
|
+
const currentState = this._pagination$.value;
|
|
183
|
+
if (currentState.totalPages > 0) {
|
|
184
|
+
this.setPage(currentState.totalPages - 1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if there is a next page
|
|
189
|
+
*/
|
|
190
|
+
hasNextPage() {
|
|
191
|
+
const currentState = this._pagination$.value;
|
|
192
|
+
return currentState.currentPage < currentState.totalPages - 1;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if there is a previous page
|
|
196
|
+
*/
|
|
197
|
+
hasPreviousPage() {
|
|
198
|
+
const currentState = this._pagination$.value;
|
|
199
|
+
return currentState.currentPage > 0;
|
|
200
|
+
}
|
|
201
|
+
// ============================================================================
|
|
202
|
+
// SORTING METHODS (operate on column configs)
|
|
203
|
+
// ============================================================================
|
|
204
|
+
/**
|
|
205
|
+
* Set sort on a column (clears other sorts)
|
|
206
|
+
* @param columnKey Column key
|
|
207
|
+
* @param direction Sort direction
|
|
208
|
+
*/
|
|
209
|
+
setSortOnColumn(columnKey, direction) {
|
|
210
|
+
const column = this.findColumn(columnKey);
|
|
211
|
+
if (!column) {
|
|
212
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (column.sortable === false) {
|
|
216
|
+
console.warn(`Column ${columnKey} is not sortable`);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
// Clear all other sorts
|
|
220
|
+
this._columns.forEach(col => {
|
|
221
|
+
if (col.key !== columnKey) {
|
|
222
|
+
col.sortDirection = SortDirection.NONE;
|
|
223
|
+
col.sortEnabled = false;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
// Set sort on target column
|
|
227
|
+
column.sortDirection = direction;
|
|
228
|
+
column.sortEnabled = direction !== SortDirection.NONE;
|
|
229
|
+
this.emitStateChange('sorting');
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Add sort to a column (for multi-column sorting)
|
|
233
|
+
* @param columnKey Column key
|
|
234
|
+
* @param direction Sort direction
|
|
235
|
+
*/
|
|
236
|
+
addSortToColumn(columnKey, direction) {
|
|
237
|
+
const column = this.findColumn(columnKey);
|
|
238
|
+
if (!column) {
|
|
239
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (column.sortable === false) {
|
|
243
|
+
console.warn(`Column ${columnKey} is not sortable`);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
column.sortDirection = direction;
|
|
247
|
+
column.sortEnabled = direction !== SortDirection.NONE;
|
|
248
|
+
this.emitStateChange('sorting');
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Toggle sort on a column (cycles through none -> asc -> desc -> none)
|
|
252
|
+
* @param columnKey Column key
|
|
253
|
+
*/
|
|
254
|
+
toggleSortOnColumn(columnKey) {
|
|
255
|
+
const column = this.findColumn(columnKey);
|
|
256
|
+
if (!column) {
|
|
257
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (column.sortable === false) {
|
|
261
|
+
console.warn(`Column ${columnKey} is not sortable`);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const currentDirection = column.sortDirection || SortDirection.NONE;
|
|
265
|
+
let newDirection;
|
|
266
|
+
switch (currentDirection) {
|
|
267
|
+
case SortDirection.NONE:
|
|
268
|
+
newDirection = SortDirection.ASC;
|
|
269
|
+
break;
|
|
270
|
+
case SortDirection.ASC:
|
|
271
|
+
newDirection = SortDirection.DESC;
|
|
272
|
+
break;
|
|
273
|
+
case SortDirection.DESC:
|
|
274
|
+
newDirection = SortDirection.NONE;
|
|
275
|
+
break;
|
|
276
|
+
default:
|
|
277
|
+
newDirection = SortDirection.ASC;
|
|
278
|
+
}
|
|
279
|
+
column.sortDirection = newDirection;
|
|
280
|
+
column.sortEnabled = newDirection !== SortDirection.NONE;
|
|
281
|
+
this.clearFocus();
|
|
282
|
+
this.clearEditingCell();
|
|
283
|
+
this.emitStateChange('sorting');
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Clear all sorting
|
|
287
|
+
*/
|
|
288
|
+
clearAllSorting() {
|
|
289
|
+
this._columns.forEach(col => {
|
|
290
|
+
col.sortDirection = SortDirection.NONE;
|
|
291
|
+
col.sortEnabled = false;
|
|
292
|
+
});
|
|
293
|
+
this.clearFocus();
|
|
294
|
+
this.clearEditingCell();
|
|
295
|
+
this.emitStateChange('sorting');
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Get sort configuration for a column
|
|
299
|
+
* @param columnKey Column key
|
|
300
|
+
* @returns Sort configuration or null
|
|
301
|
+
*/
|
|
302
|
+
getSortForColumn(columnKey) {
|
|
303
|
+
const column = this.findColumn(columnKey);
|
|
304
|
+
if (!column) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
direction: column.sortDirection || SortDirection.NONE,
|
|
309
|
+
enabled: column.sortEnabled || false
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
// ============================================================================
|
|
313
|
+
// FILTERING METHODS (operate on column configs)
|
|
314
|
+
// ============================================================================
|
|
315
|
+
/**
|
|
316
|
+
* Set filter on a column
|
|
317
|
+
* @param columnKey Column key
|
|
318
|
+
* @param operator Filter operator
|
|
319
|
+
* @param value Filter value
|
|
320
|
+
*/
|
|
321
|
+
setFilterOnColumn(columnKey, operator, value) {
|
|
322
|
+
const column = this.findColumn(columnKey);
|
|
323
|
+
if (!column) {
|
|
324
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (column.filterable === false) {
|
|
328
|
+
console.warn(`Column ${columnKey} is not filterable`);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
// Initialize filterConfig if it doesn't exist
|
|
332
|
+
if (!column.filterConfig) {
|
|
333
|
+
column.filterConfig = {};
|
|
334
|
+
}
|
|
335
|
+
column.filterConfig.operator = operator;
|
|
336
|
+
column.filterConfig.value = value;
|
|
337
|
+
column.filterConfig.enabled = true;
|
|
338
|
+
this.clearFocus();
|
|
339
|
+
this.clearEditingCell();
|
|
340
|
+
this.emitStateChange('filtering');
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Clear filter on a column
|
|
344
|
+
* @param columnKey Column key
|
|
345
|
+
*/
|
|
346
|
+
clearFilterOnColumn(columnKey) {
|
|
347
|
+
const column = this.findColumn(columnKey);
|
|
348
|
+
if (!column) {
|
|
349
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
// Initialize filterConfig if it doesn't exist (for consistency with setFilterOnColumn)
|
|
353
|
+
if (!column.filterConfig) {
|
|
354
|
+
column.filterConfig = {};
|
|
355
|
+
}
|
|
356
|
+
column.filterConfig.value = undefined;
|
|
357
|
+
column.filterConfig.enabled = false;
|
|
358
|
+
this.clearFocus();
|
|
359
|
+
this.clearEditingCell();
|
|
360
|
+
this.emitStateChange('filtering');
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Clear all filters
|
|
364
|
+
*/
|
|
365
|
+
clearAllFilters() {
|
|
366
|
+
this._columns.forEach(col => {
|
|
367
|
+
// Initialize filterConfig if it doesn't exist (for consistency with setFilterOnColumn)
|
|
368
|
+
if (!col.filterConfig) {
|
|
369
|
+
col.filterConfig = {};
|
|
370
|
+
}
|
|
371
|
+
col.filterConfig.value = undefined;
|
|
372
|
+
col.filterConfig.enabled = false;
|
|
373
|
+
});
|
|
374
|
+
this.clearFocus();
|
|
375
|
+
this.clearEditingCell();
|
|
376
|
+
this.emitStateChange('filtering');
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Set filter enabled state
|
|
380
|
+
* @param columnKey Column key
|
|
381
|
+
* @param enabled Whether filter is enabled
|
|
382
|
+
*/
|
|
383
|
+
setFilterEnabled(columnKey, enabled) {
|
|
384
|
+
const column = this.findColumn(columnKey);
|
|
385
|
+
if (!column) {
|
|
386
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
// Initialize filterConfig if it doesn't exist
|
|
390
|
+
if (!column.filterConfig) {
|
|
391
|
+
column.filterConfig = {};
|
|
392
|
+
}
|
|
393
|
+
column.filterConfig.enabled = enabled;
|
|
394
|
+
this.emitStateChange('filtering');
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Get filter configuration for a column
|
|
398
|
+
* @param columnKey Column key
|
|
399
|
+
* @returns Filter configuration or null
|
|
400
|
+
*/
|
|
401
|
+
getFilterForColumn(columnKey) {
|
|
402
|
+
const column = this.findColumn(columnKey);
|
|
403
|
+
if (!column) {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
return {
|
|
407
|
+
operator: column.filterConfig?.operator || FilterOperator.CONTAINS,
|
|
408
|
+
value: column.filterConfig?.value,
|
|
409
|
+
enabled: column.filterConfig?.enabled || false
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
// ============================================================================
|
|
413
|
+
// STICKY COLUMN MANAGEMENT
|
|
414
|
+
// ============================================================================
|
|
415
|
+
/**
|
|
416
|
+
* Get sticky columns grouped by position
|
|
417
|
+
* @returns Object with left and right sticky column keys
|
|
418
|
+
*/
|
|
419
|
+
getStickyColumns() {
|
|
420
|
+
const left = this._columns
|
|
421
|
+
.filter(col => col.sticky === 'left')
|
|
422
|
+
.map(col => col.key);
|
|
423
|
+
const right = this._columns
|
|
424
|
+
.filter(col => col.sticky === 'right')
|
|
425
|
+
.map(col => col.key);
|
|
426
|
+
return { left, right };
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Set sticky position for a column
|
|
430
|
+
* @param columnKey Column key
|
|
431
|
+
* @param position Sticky position ('left', 'right', or false)
|
|
432
|
+
*/
|
|
433
|
+
setStickyColumn(columnKey, position) {
|
|
434
|
+
const column = this.findColumn(columnKey);
|
|
435
|
+
if (!column) {
|
|
436
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
column.sticky = position;
|
|
440
|
+
this.calculateStickyOffsets();
|
|
441
|
+
this.emitStateChange('column-config');
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Calculate sticky offsets for all sticky columns
|
|
445
|
+
* This calculates cumulative widths for positioning
|
|
446
|
+
* @param rowNumberWidth Optional width of row number column to account for in left offset
|
|
447
|
+
* @param settingsColumnWidth Optional width of settings column to account for in right offset
|
|
448
|
+
*/
|
|
449
|
+
calculateStickyOffsets(rowNumberWidth, settingsColumnWidth) {
|
|
450
|
+
// Update stored row number width if provided
|
|
451
|
+
if (rowNumberWidth !== undefined) {
|
|
452
|
+
this._rowNumberWidth = rowNumberWidth;
|
|
453
|
+
}
|
|
454
|
+
// Update stored settings column width if provided
|
|
455
|
+
if (settingsColumnWidth !== undefined) {
|
|
456
|
+
this._settingsColumnWidth = settingsColumnWidth;
|
|
457
|
+
}
|
|
458
|
+
// Calculate left sticky offsets
|
|
459
|
+
// Account for row number column width
|
|
460
|
+
let leftOffset = this._rowNumberWidth;
|
|
461
|
+
this._columns.forEach(col => {
|
|
462
|
+
if (col.sticky === 'left') {
|
|
463
|
+
col.stickyOffset = leftOffset;
|
|
464
|
+
leftOffset += col.width || 100;
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
// Calculate right sticky offsets
|
|
468
|
+
// Account for settings column width (row actions column)
|
|
469
|
+
let rightOffset = this._settingsColumnWidth;
|
|
470
|
+
for (let i = this._columns.length - 1; i >= 0; i--) {
|
|
471
|
+
const col = this._columns[i];
|
|
472
|
+
if (col.sticky === 'right') {
|
|
473
|
+
col.stickyOffset = rightOffset;
|
|
474
|
+
rightOffset += col.width || 100;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
// ============================================================================
|
|
479
|
+
// COLUMN MANAGEMENT
|
|
480
|
+
// ============================================================================
|
|
481
|
+
/**
|
|
482
|
+
* Update columns reference
|
|
483
|
+
* @param columns New columns array
|
|
484
|
+
*/
|
|
485
|
+
updateColumns(columns) {
|
|
486
|
+
this._columns = columns;
|
|
487
|
+
this.calculateStickyOffsets();
|
|
488
|
+
this.emitStateChange('column-config');
|
|
489
|
+
}
|
|
490
|
+
// ============================================================================
|
|
491
|
+
// COLUMN VISIBILITY METHODS
|
|
492
|
+
// ============================================================================
|
|
493
|
+
/**
|
|
494
|
+
* Toggle visibility of a column
|
|
495
|
+
* @param columnKey Column key
|
|
496
|
+
*/
|
|
497
|
+
toggleColumnVisibility(columnKey) {
|
|
498
|
+
const column = this.findColumn(columnKey);
|
|
499
|
+
if (!column) {
|
|
500
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
// Check if column is hideable
|
|
504
|
+
if (column.hideable === false) {
|
|
505
|
+
console.warn(`Column ${columnKey} cannot be hidden (hideable is false)`);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const currentVisibility = column.visible !== false; // Default to true if not set
|
|
509
|
+
column.visible = !currentVisibility;
|
|
510
|
+
this.emitStateChange('column-visibility');
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Set visibility of a column
|
|
514
|
+
* @param columnKey Column key
|
|
515
|
+
* @param visible Whether column should be visible
|
|
516
|
+
*/
|
|
517
|
+
setColumnVisibility(columnKey, visible) {
|
|
518
|
+
const column = this.findColumn(columnKey);
|
|
519
|
+
if (!column) {
|
|
520
|
+
console.warn(`Column not found: ${columnKey}`);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
// Check if column is hideable (only when trying to hide)
|
|
524
|
+
if (!visible && column.hideable === false) {
|
|
525
|
+
console.warn(`Column ${columnKey} cannot be hidden (hideable is false)`);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
column.visible = visible;
|
|
529
|
+
this.emitStateChange('column-visibility');
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Get all visible columns
|
|
533
|
+
* @returns Array of visible column configs
|
|
534
|
+
*/
|
|
535
|
+
getVisibleColumns() {
|
|
536
|
+
return this._columns.filter(col => col.visible !== false); // Default to true if not set
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Get visibility state for all columns
|
|
540
|
+
* @returns Array of column visibility info
|
|
541
|
+
*/
|
|
542
|
+
getAllColumnsVisibility() {
|
|
543
|
+
return this._columns.map(col => ({
|
|
544
|
+
key: col.key,
|
|
545
|
+
header: col.header || col.key,
|
|
546
|
+
visible: col.visible !== false,
|
|
547
|
+
hideable: col.hideable !== false // Default to true if not set
|
|
548
|
+
}));
|
|
549
|
+
}
|
|
550
|
+
// ============================================================================
|
|
551
|
+
// KEYBOARD NAVIGATION & FOCUS MANAGEMENT
|
|
552
|
+
// ============================================================================
|
|
553
|
+
/**
|
|
554
|
+
* Set table dimensions for navigation boundaries
|
|
555
|
+
*/
|
|
556
|
+
setDimensions(rowCount, columnCount) {
|
|
557
|
+
this._rowCount = rowCount;
|
|
558
|
+
this._columnCount = columnCount;
|
|
559
|
+
// Update total rows in validation state
|
|
560
|
+
this.setValidationRowCount(rowCount);
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Focus a cell by position
|
|
564
|
+
*/
|
|
565
|
+
focusCell(rowIndex, columnIndex) {
|
|
566
|
+
if (rowIndex < 0 || rowIndex >= this._rowCount)
|
|
567
|
+
return;
|
|
568
|
+
if (columnIndex < 0 || columnIndex >= this._columnCount)
|
|
569
|
+
return;
|
|
570
|
+
this._focusedCellPosition$.next({ rowIndex, columnIndex });
|
|
571
|
+
this.emitStateChange('cell-focus');
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Get currently focused position
|
|
575
|
+
*/
|
|
576
|
+
getFocusedPosition() {
|
|
577
|
+
return this._focusedCellPosition$.value;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Notify that a cell entered edit mode
|
|
581
|
+
*/
|
|
582
|
+
setEditingCell(rowIndex, columnIndex) {
|
|
583
|
+
this._editingCellPosition$.next({ rowIndex, columnIndex });
|
|
584
|
+
this.emitStateChange('cell-edit-start');
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Notify that edit mode ended
|
|
588
|
+
*/
|
|
589
|
+
clearEditingCell() {
|
|
590
|
+
this._editingCellPosition$.next(null);
|
|
591
|
+
this.emitStateChange('cell-edit-end');
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Check if any cell is currently editing
|
|
595
|
+
*/
|
|
596
|
+
isAnyCellEditing() {
|
|
597
|
+
return this._editingCellPosition$.value !== null;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Get currently editing position
|
|
601
|
+
*/
|
|
602
|
+
getEditingPosition() {
|
|
603
|
+
return this._editingCellPosition$.value;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Move focus in a direction using NavigationDirection enum
|
|
607
|
+
*/
|
|
608
|
+
moveFocus(direction) {
|
|
609
|
+
// Block navigation if any cell is editing
|
|
610
|
+
if (this.isAnyCellEditing()) {
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
const current = this._focusedCellPosition$.value;
|
|
614
|
+
if (!current)
|
|
615
|
+
return false;
|
|
616
|
+
let newRow = current.rowIndex;
|
|
617
|
+
let newCol = current.columnIndex;
|
|
618
|
+
// Use NavigationDirection enum values
|
|
619
|
+
switch (direction) {
|
|
620
|
+
case NavigationDirection.UP:
|
|
621
|
+
newRow--;
|
|
622
|
+
break;
|
|
623
|
+
case NavigationDirection.DOWN:
|
|
624
|
+
newRow++;
|
|
625
|
+
break;
|
|
626
|
+
case NavigationDirection.LEFT:
|
|
627
|
+
newCol--;
|
|
628
|
+
break;
|
|
629
|
+
case NavigationDirection.RIGHT:
|
|
630
|
+
newCol++;
|
|
631
|
+
break;
|
|
632
|
+
}
|
|
633
|
+
if (newRow < 0 || newRow >= this._rowCount)
|
|
634
|
+
return false;
|
|
635
|
+
if (newCol < 0 || newCol >= this._columnCount)
|
|
636
|
+
return false;
|
|
637
|
+
this.focusCell(newRow, newCol);
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Clear focus
|
|
642
|
+
*/
|
|
643
|
+
clearFocus() {
|
|
644
|
+
this._focusedCellPosition$.next(null);
|
|
645
|
+
this.emitStateChange('cell-focus');
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Check if navigation is active
|
|
649
|
+
*/
|
|
650
|
+
isNavigationActive() {
|
|
651
|
+
return this._focusedCellPosition$.value !== null;
|
|
652
|
+
}
|
|
653
|
+
// ============================================================================
|
|
654
|
+
// VALIDATION STATE METHODS
|
|
655
|
+
// ============================================================================
|
|
656
|
+
/**
|
|
657
|
+
* Update cell validation and accumulate into row/table validation state
|
|
658
|
+
* Only stores invalid states - valid rows are automatically removed
|
|
659
|
+
*/
|
|
660
|
+
updateCellValidation(rowIndex, columnKey, isValid, error) {
|
|
661
|
+
const currentState = this._tableValidationState$.value;
|
|
662
|
+
const rowStates = new Map(currentState.rowStates);
|
|
663
|
+
// Get existing row state (only exists if row has errors)
|
|
664
|
+
let rowState = rowStates.get(rowIndex);
|
|
665
|
+
if (!isValid && error) {
|
|
666
|
+
// Cell is invalid - add or update error
|
|
667
|
+
if (!rowState) {
|
|
668
|
+
// Create new row state for this invalid row
|
|
669
|
+
rowState = {
|
|
670
|
+
rowIndex,
|
|
671
|
+
isValid: false,
|
|
672
|
+
invalidCellCount: 1,
|
|
673
|
+
cellErrors: new Map([[columnKey, error]]),
|
|
674
|
+
lastValidated: new Date()
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
// Update existing row state
|
|
679
|
+
const cellErrors = new Map(rowState.cellErrors);
|
|
680
|
+
cellErrors.set(columnKey, error);
|
|
681
|
+
rowState = {
|
|
682
|
+
rowIndex,
|
|
683
|
+
isValid: false,
|
|
684
|
+
invalidCellCount: cellErrors.size,
|
|
685
|
+
cellErrors,
|
|
686
|
+
lastValidated: new Date()
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
rowStates.set(rowIndex, rowState);
|
|
690
|
+
}
|
|
691
|
+
else {
|
|
692
|
+
// Cell is valid - remove error if it exists
|
|
693
|
+
if (rowState) {
|
|
694
|
+
const cellErrors = new Map(rowState.cellErrors);
|
|
695
|
+
cellErrors.delete(columnKey);
|
|
696
|
+
if (cellErrors.size === 0) {
|
|
697
|
+
// No more errors in this row - remove row state completely
|
|
698
|
+
rowStates.delete(rowIndex);
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
// Still has other errors - update row state
|
|
702
|
+
rowState = {
|
|
703
|
+
rowIndex,
|
|
704
|
+
isValid: false,
|
|
705
|
+
invalidCellCount: cellErrors.size,
|
|
706
|
+
cellErrors,
|
|
707
|
+
lastValidated: new Date()
|
|
708
|
+
};
|
|
709
|
+
rowStates.set(rowIndex, rowState);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
// If rowState doesn't exist, cell was already valid - do nothing
|
|
713
|
+
}
|
|
714
|
+
// Recalculate table state
|
|
715
|
+
// All rows in rowStates map are invalid by definition
|
|
716
|
+
const invalidRows = rowStates.size;
|
|
717
|
+
const newTableState = {
|
|
718
|
+
isValid: invalidRows === 0,
|
|
719
|
+
totalRows: currentState.totalRows,
|
|
720
|
+
validRows: currentState.totalRows - invalidRows,
|
|
721
|
+
invalidRows,
|
|
722
|
+
rowStates,
|
|
723
|
+
lastUpdated: new Date()
|
|
724
|
+
};
|
|
725
|
+
// Emit new state
|
|
726
|
+
this._tableValidationState$.next(newTableState);
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Get current table validation state
|
|
730
|
+
*/
|
|
731
|
+
getTableValidationState() {
|
|
732
|
+
return this._tableValidationState$.value;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Set total rows for validation state tracking
|
|
736
|
+
*/
|
|
737
|
+
setValidationRowCount(totalRows) {
|
|
738
|
+
const currentState = this._tableValidationState$.value;
|
|
739
|
+
this._tableValidationState$.next({
|
|
740
|
+
...currentState,
|
|
741
|
+
totalRows,
|
|
742
|
+
lastUpdated: new Date()
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
// ============================================================================
|
|
746
|
+
// STATE RESET
|
|
747
|
+
// ============================================================================
|
|
748
|
+
/**
|
|
749
|
+
* Reset to initial configuration
|
|
750
|
+
*/
|
|
751
|
+
reset() {
|
|
752
|
+
this.resetPagination();
|
|
753
|
+
this.resetAllSorting();
|
|
754
|
+
this.resetAllFilters();
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Reset pagination only
|
|
758
|
+
*/
|
|
759
|
+
resetPagination() {
|
|
760
|
+
this._pagination$.next({
|
|
761
|
+
currentPage: this._initialConfig.initialPage,
|
|
762
|
+
pageSize: this._initialConfig.pageSize,
|
|
763
|
+
totalItems: 0,
|
|
764
|
+
totalPages: 0
|
|
765
|
+
});
|
|
766
|
+
this.emitStateChange('pagination');
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Reset all column sorts
|
|
770
|
+
*/
|
|
771
|
+
resetAllSorting() {
|
|
772
|
+
this.clearAllSorting();
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Reset all column filters
|
|
776
|
+
*/
|
|
777
|
+
resetAllFilters() {
|
|
778
|
+
this.clearAllFilters();
|
|
779
|
+
}
|
|
780
|
+
// ============================================================================
|
|
781
|
+
// INTERNAL METHODS
|
|
782
|
+
// ============================================================================
|
|
783
|
+
/**
|
|
784
|
+
* Find a column by key
|
|
785
|
+
* @param columnKey Column key
|
|
786
|
+
* @returns Column config or undefined
|
|
787
|
+
*/
|
|
788
|
+
findColumn(columnKey) {
|
|
789
|
+
return this._columns.find(col => col.key === columnKey);
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Calculate total pages
|
|
793
|
+
* @param totalItems Total number of items
|
|
794
|
+
* @param pageSize Page size
|
|
795
|
+
* @returns Total number of pages
|
|
796
|
+
*/
|
|
797
|
+
calculateTotalPages(totalItems = 0, pageSize = 25) {
|
|
798
|
+
if (totalItems === 0 || pageSize === 0) {
|
|
799
|
+
return 0;
|
|
800
|
+
}
|
|
801
|
+
return Math.ceil(totalItems / pageSize);
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Emit state change event
|
|
805
|
+
* @param type Type of change
|
|
806
|
+
*/
|
|
807
|
+
emitStateChange(type) {
|
|
808
|
+
const state = this.buildStateSnapshot();
|
|
809
|
+
this._stateChange$.next({
|
|
810
|
+
type,
|
|
811
|
+
state
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Build state snapshot from current state
|
|
816
|
+
* @returns State snapshot
|
|
817
|
+
*/
|
|
818
|
+
buildStateSnapshot() {
|
|
819
|
+
return {
|
|
820
|
+
pagination: this.getPagination(),
|
|
821
|
+
// Build full sort state with direction and priority
|
|
822
|
+
sortedColumns: this._columns
|
|
823
|
+
.filter(col => col.sortEnabled === true)
|
|
824
|
+
.map((col, index) => ({
|
|
825
|
+
columnKey: col.key,
|
|
826
|
+
direction: col.sortDirection || SortDirection.NONE,
|
|
827
|
+
priority: index // Sort order based on enablement order
|
|
828
|
+
})),
|
|
829
|
+
// Build full filter state with operator and value
|
|
830
|
+
filteredColumns: this._columns
|
|
831
|
+
.filter(col => col.filterConfig?.enabled === true)
|
|
832
|
+
.map(col => ({
|
|
833
|
+
columnKey: col.key,
|
|
834
|
+
operator: col.filterConfig?.operator || FilterOperator.CONTAINS,
|
|
835
|
+
value: col.filterConfig?.value,
|
|
836
|
+
enabled: true
|
|
837
|
+
}))
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtc3RhdGUuY2xhc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zbWFydC10YWJsZS9zcmMvbGliL3JlbmRlcmVyL21vZGVscy90YWJsZS1zdGF0ZS5jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsZUFBZSxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1RCxPQUFPLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0QsT0FBTyxFQUVMLGFBQWEsRUFDYixjQUFjLEVBSWYsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFJOUQ7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFrRHJCOzs7O09BSUc7SUFDSCxZQUFZLE9BQTRCLEVBQUUsTUFBeUI7UUExQ25FLHdEQUF3RDtRQUNoRCxvQkFBZSxHQUFXLENBQUMsQ0FBQztRQUVwQyxzREFBc0Q7UUFDOUMseUJBQW9CLEdBQVcsQ0FBQyxDQUFDO1FBY3pDLG1DQUFtQztRQUMzQixjQUFTLEdBQVcsQ0FBQyxDQUFDO1FBQ3RCLGlCQUFZLEdBQVcsQ0FBQyxDQUFDO1FBdUIvQixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUN4QixJQUFJLENBQUMsY0FBYyxHQUFHO1lBQ3BCLFdBQVcsRUFBRSxNQUFNLEVBQUUsV0FBVyxJQUFJLENBQUM7WUFDckMsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLElBQUksRUFBRTtTQUNqQyxDQUFDO1FBRUYsOEJBQThCO1FBQzlCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxlQUFlLENBQWtCO1lBQ3ZELFdBQVcsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVk7WUFDN0MsUUFBUSxFQUFFLElBQUksQ0FBQyxjQUFjLENB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LENBQUMsSUFBSSxDQUFDO1lBQ3RCLElBQUk7WUFDSixLQUFLO1NBQ04sQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGtCQUFrQjtRQUN4QixPQUFPO1lBQ0wsVUFBVSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFFaEMsb0RBQW9EO1lBQ3BELGFBQWEsRUFBRSxJQUFJLENBQUMsUUFBUTtpQkFDekIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUM7aUJBQ3ZDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3BCLFNBQVMsRUFBRSxHQUFHLENBQUMsR0FBRztnQkFDbEIsU0FBUyxFQUFFLEdBQUcsQ0FBQyxhQUFhLElBQUksYUFBYSxDQUFDLElBQUk7Z0JBQ2xELFFBQVEsRUFBRSxLQUFLLENBQUUsdUNBQXVDO2FBQ3pELENBQUMsQ0FBQztZQUVMLGtEQUFrRDtZQUNsRCxlQUFlLEVBQUUsSUFBSSxDQUFDLFFBQVE7aUJBQzNCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsT0FBTyxLQUFLLElBQUksQ0FBQztpQkFDakQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDWCxTQUFTLEVBQUUsR0FBRyxDQUFDLEdBQUc7Z0JBQ2xCLFFBQVEsRUFBRSxHQUFHLENBQUMsWUFBWSxFQUFFLFFBQVEsSUFBSSxjQUFjLENBQUMsUUFBUTtnQkFDL0QsS0FBSyxFQUFFLEdBQUcsQ0FBQyxZQUFZLEVBQUUsS0FBSztnQkFDOUIsT0FBTyxFQUFFLElBQUk7YUFDZCxDQUFDLENBQUM7U0FDTixDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUYWJsZVN0YXRlIC0gUmVhY3RpdmUgc3RhdGUgbWFuYWdlbWVudCBmb3IgdGFibGUgb3BlcmF0aW9uc1xuICogRXZlbnQtZHJpdmVuIGFyY2hpdGVjdHVyZTogdHJhY2tzIHN0YXRlLCBlbWl0cyBldmVudHMsIGNvbnN1bWVyIGhhbmRsZXMgYXN5bmMgZGF0YSBvcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIGRpc3RpbmN0VW50aWxDaGFuZ2VkIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ29sdW1uQ29uZmlnIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2NvbHVtbi1jb25maWcuaW50ZXJmYWNlJztcbmltcG9ydCB7IFxuICBQYWdpbmF0aW9uU3RhdGUsIFxuICBTb3J0RGlyZWN0aW9uLCBcbiAgRmlsdGVyT3BlcmF0b3IsXG4gIFRhYmxlU3RhdGVDaGFuZ2VFdmVudCxcbiAgVGFibGVTdGF0ZVNuYXBzaG90LFxuICBDZWxsRm9jdXNQb3NpdGlvblxufSBmcm9tICcuL3RhYmxlLXR5cGVzJztcbmltcG9ydCB7IFRhYmxlU3RhdGVDb25maWcgfSBmcm9tICcuL3RhYmxlLXN0YXRlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uRGlyZWN0aW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2NlbGwtdHlwZXMnO1xuaW1wb3J0IHsgUm93VmFsaWRhdGlvblN0YXRlIH0gZnJvbSAnLi9yb3ctdmFsaWRhdGlvbi1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGFibGVWYWxpZGF0aW9uU3RhdGUgfSBmcm9tICcuL3RhYmxlLXZhbGlkYXRpb24tc3RhdGUuaW50ZXJmYWNlJztcblxuLyoqXG4gKiBUYWJsZVN0YXRlIGNsYXNzIC0gQ29sdW1uLWRyaXZlbiwgZXZlbnQtZW1pdHRpbmcgc3RhdGUgbWFuYWdlbWVudFxuICogTk8gZGF0YSBtYW5pcHVsYXRpb24gLSBvbmx5IHN0YXRlIHRyYWNraW5nIGFuZCBldmVudCBlbWlzc2lvblxuICovXG5leHBvcnQgY2xhc3MgVGFibGVTdGF0ZSB7XG4gIC8vIFJlZmVyZW5jZSB0byBjb2x1bW5zIGFycmF5IChjb2x1bW4tZHJpdmVuIGFyY2hpdGVjdHVyZSlcbiAgcHJpdmF0ZSBfY29sdW1uczogQ29sdW1uQ29uZmlnPGFueT5bXTtcbiAgXG4gIC8vIFBhZ2luYXRpb24gc3RhdGVcbiAgcHJpdmF0ZSBfcGFnaW5hdGlvbiQ6IEJlaGF2aW9yU3ViamVjdDxQYWdpbmF0aW9uU3RhdGU+O1xuICBcbiAgLy8gU3RhdGUgY2hhbmdlIGV2ZW50c1xuICBwcml2YXRlIF9zdGF0ZUNoYW5nZSQ6IFN1YmplY3Q8VGFibGVTdGF0ZUNoYW5nZUV2ZW50PjtcbiAgXG4gIC8vIEluaXRpYWwgY29uZmlndXJhdGlvblxuICBwcml2YXRlIF9pbml0aWFsQ29uZmlnOiBUYWJsZVN0YXRlQ29uZmlnO1xuICBcbiAgLy8gUm93IG51bWJlciBjb2x1bW4gd2lkdGggZm9yIHN0aWNreSBvZmZzZXQgY2FsY3VsYXRpb25cbiAgcHJpdmF0ZSBfcm93TnVtYmVyV2lkdGg6IG51bWJlciA9IDA7XG5cbiAgLy8gU2V0dGluZ3MgY29sdW1uIHdpZHRoIGZvciBzdGlja3kgb2Zmc2V0IGNhbGN1bGF0aW9uXG4gIHByaXZhdGUgX3NldHRpbmdzQ29sdW1uV2lkdGg6IG51bWJlciA9IDA7XG4gIFxuICAvLyBGb2N1cyBwb3NpdGlvbiB0cmFja2luZ1xuICBwcml2YXRlIF9mb2N1c2VkQ2VsbFBvc2l0aW9uJDogQmVoYXZpb3JTdWJqZWN0PENlbGxGb2N1c1Bvc2l0aW9uIHwgbnVsbD47XG4gIHB1YmxpYyByZWFkb25seSBmb2N1c2VkQ2VsbFBvc2l0aW9uJDogT2JzZXJ2YWJsZTxDZWxsRm9jdXNQb3NpdGlvbiB8IG51bGw+O1xuICBcbiAgLy8gRWRpdGluZyBwb3NpdGlvbiB0cmFja2luZ1xuICBwcml2YXRlIF9lZGl0aW5nQ2VsbFBvc2l0aW9uJDogQmVoYXZpb3JTdWJqZWN0PENlbGxGb2N1c1Bvc2l0aW9uIHwgbnVsbD47XG4gIHB1YmxpYyByZWFkb25seSBlZGl0aW5nQ2VsbFBvc2l0aW9uJDogT2JzZXJ2YWJsZTxDZWxsRm9jdXNQb3NpdGlvbiB8IG51bGw+O1xuICBcbiAgLy8gVmFsaWRhdGlvbiBzdGF0ZSB0cmFja2luZ1xuICBwcml2YXRlIF90YWJsZVZhbGlkYXRpb25TdGF0ZSQ6IEJlaGF2aW9yU3ViamVjdDxUYWJsZVZhbGlkYXRpb25TdGF0ZT47XG4gIHB1YmxpYyByZWFkb25seSB0YWJsZVZhbGlkYXRpb25TdGF0ZSQ6IE9ic2VydmFibGU8VGFibGVWYWxpZGF0aW9uU3RhdGU+O1xuICBcbiAgLy8gRGltZW5zaW9ucyBmb3IgYm91bmRhcnkgY2hlY2tpbmdcbiAgcHJpdmF0ZSBfcm93Q291bnQ6IG51bWJlciA9IDA7XG4gIHByaXZhdGUgX2NvbHVtbkNvdW50OiBudW1iZXIgPSAwO1xuXG4gIC8qKlxuICAgKiBPYnNlcnZhYmxlIG9mIGNvbXBsZXRlIHN0YXRlIHNuYXBzaG90XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3RhdGUkOiBPYnNlcnZhYmxlPFRhYmxlU3RhdGVTbmFwc2hvdD47XG5cbiAgLyoqXG4gICAqIE9ic2VydmFibGUgb2Ygc3RhdGUgY2hhbmdlIGV2ZW50c1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHN0YXRlQ2hhbmdlJDogT2JzZXJ2YWJsZTxUYWJsZVN0YXRlQ2hhbmdlRXZlbnQ+O1xuXG4gIC8qKlxuICAgKiBPYnNlcnZhYmxlIG9mIHBhZ2luYXRpb24gc3RhdGUgY2hhbmdlc1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBhZ2luYXRpb25DaGFuZ2UkOiBPYnNlcnZhYmxlPFBhZ2luYXRpb25TdGF0ZT47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSBjb2x1bW5zIFJlZmVyZW5jZSB0byBjb2x1bW5zIGFycmF5XG4gICAqIEBwYXJhbSBjb25maWcgSW5pdGlhbCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb2x1bW5zOiBDb2x1bW5Db25maWc8YW55PltdLCBjb25maWc/OiBUYWJsZVN0YXRlQ29uZmlnKSB7XG4gICAgdGhpcy5fY29sdW1ucyA9IGNvbHVtbnM7XG4gICAgdGhpcy5faW5pdGlhbENvbmZpZyA9IHtcbiAgICAgIGluaXRpYWxQYWdlOiBjb25maWc/LmluaXRpYWxQYWdlID8/IDAsXG4gICAgICBwYWdlU2l6ZTogY29uZmlnPy5wYWdlU2l6ZSA/PyAyNVxuICAgIH07XG5cbiAgICAvLyBJbml0aWFsaXplIHBhZ2luYXRpb24gc3RhdGVcbiAgICB0aGlzLl9wYWdpbmF0aW9uJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UGFnaW5hdGlvblN0YXRlPih7XG4gICAgICBjdXJyZW50UGFnZTogdGhpcy5faW5pdGlhbENvbmZpZy5pbml0aWFsUGFnZSEsXG4gICAgICBwYWdlU2l6ZTogdGhpcy5faW5pdGlhbENvbmZpZy5wYWdlU2l6ZSEsXG4gICAgICB0b3RhbEl0ZW1zOiAwLFxuICAgICAgdG90YWxQYWdlczogMFxuICAgIH0pO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBzdGF0ZSBjaGFuZ2Ugc3ViamVjdFxuICAgIHRoaXMuX3N0YXRlQ2hhbmdlJCA9IG5ldyBTdWJqZWN0PFRhYmxlU3RhdGVDaGFuZ2VFdmVudD4oKTtcbiAgICBcbiAgICAvLyBJbml0aWFsaXplIGZvY3VzIGFuZCBlZGl0aW5nIHBvc2l0aW9uIHRyYWNraW5nXG4gICAgdGhpcy5fZm9jdXNlZENlbGxQb3NpdGlvbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENlbGxGb2N1c1Bvc2l0aW9uIHwgbnVsbD4obnVsbCk7XG4gICAgdGhpcy5mb2N1c2VkQ2VsbFBvc2l0aW9uJCA9IHRoaXMuX2ZvY3VzZWRDZWxsUG9zaXRpb24kLmFzT2JzZXJ2YWJsZSgpO1xuICAgIFxuICAgIHRoaXMuX2VkaXRpbmdDZWxsUG9zaXRpb24kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDZWxsRm9jdXNQb3NpdGlvbiB8IG51bGw+KG51bGwpO1xuICAgIHRoaXMuZWRpdGluZ0NlbGxQb3NpdGlvbiQgPSB0aGlzLl9lZGl0aW5nQ2VsbFBvc2l0aW9uJC5hc09ic2VydmFibGUoKTtcbiAgICBcbiAgICAvLyBJbml0aWFsaXplIHZhbGlkYXRpb24gc3RhdGVcbiAgICB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRhYmxlVmFsaWRhdGlvblN0YXRlPih7XG4gICAgICBpc1ZhbGlkOiB0cnVlLFxuICAgICAgdG90YWxSb3dzOiAwLFxuICAgICAgdmFsaWRSb3dzOiAwLFxuICAgICAgaW52YWxpZFJvd3M6IDAsXG4gICAgICByb3dTdGF0ZXM6IG5ldyBNYXAoKSxcbiAgICAgIGxhc3RVcGRhdGVkOiBuZXcgRGF0ZSgpXG4gICAgfSk7XG4gICAgdGhpcy50YWJsZVZhbGlkYXRpb25TdGF0ZSQgPSB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQuYXNPYnNlcnZhYmxlKCk7XG4gICAgXG4gICAgdGhpcy5fY29sdW1uQ291bnQgPSBjb2x1bW5zLmZpbHRlcihjID0+IGMudmlzaWJsZSAhPT0gZmFsc2UpLmxlbmd0aDtcblxuICAgIC8vIFNldHVwIG9ic2VydmFibGVzXG4gICAgdGhpcy5wYWdpbmF0aW9uQ2hhbmdlJCA9IHRoaXMuX3BhZ2luYXRpb24kLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgoYSwgYikgPT4gXG4gICAgICAgIGEuY3VycmVudFBhZ2UgPT09IGIuY3VycmVudFBhZ2UgJiYgXG4gICAgICAgIGEucGFnZVNpemUgPT09IGIucGFnZVNpemUgJiZcbiAgICAgICAgYS50b3RhbEl0ZW1zID09PSBiLnRvdGFsSXRlbXNcbiAgICAgIClcbiAgICApO1xuXG4gICAgdGhpcy5zdGF0ZSQgPSB0aGlzLl9wYWdpbmF0aW9uJC5waXBlKFxuICAgICAgbWFwKCgpID0+IHRoaXMuYnVpbGRTdGF0ZVNuYXBzaG90KCkpXG4gICAgKTtcblxuICAgIHRoaXMuc3RhdGVDaGFuZ2UkID0gdGhpcy5fc3RhdGVDaGFuZ2UkLmFzT2JzZXJ2YWJsZSgpO1xuICAgIFxuICAgIC8vIENsZWFyIGZvY3VzL2VkaXRpbmcgb24gcGFnaW5hdGlvbiBjaGFuZ2VzXG4gICAgdGhpcy5wYWdpbmF0aW9uQ2hhbmdlJC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5jbGVhckZvY3VzKCk7XG4gICAgICB0aGlzLmNsZWFyRWRpdGluZ0NlbGwoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU1RBVEUgQUNDRVNTIE1FVEhPRFNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBzdGF0ZSBzbmFwc2hvdFxuICAgKi9cbiAgZ2V0U3RhdGUoKTogVGFibGVTdGF0ZVNuYXBzaG90IHtcbiAgICByZXR1cm4gdGhpcy5idWlsZFN0YXRlU25hcHNob3QoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBwYWdpbmF0aW9uIHN0YXRlXG4gICAqL1xuICBnZXRQYWdpbmF0aW9uKCk6IFBhZ2luYXRpb25TdGF0ZSB7XG4gICAgcmV0dXJuIHsgLi4udGhpcy5fcGFnaW5hdGlvbiQudmFsdWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY29sdW1ucyB3aXRoIHNvcnRpbmcgZW5hYmxlZFxuICAgKi9cbiAgZ2V0U29ydGVkQ29sdW1ucygpOiBDb2x1bW5Db25maWc8YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1ucy5maWx0ZXIoY29sID0+IGNvbC5zb3J0RW5hYmxlZCA9PT0gdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNvbHVtbnMgd2l0aCBmaWx0ZXJpbmcgZW5hYmxlZFxuICAgKi9cbiAgZ2V0RmlsdGVyZWRDb2x1bW5zKCk6IENvbHVtbkNvbmZpZzxhbnk+W10ge1xuICAgIHJldHVybiB0aGlzLl9jb2x1bW5zLmZpbHRlcihjb2wgPT4gY29sLmZpbHRlckNvbmZpZz8uZW5hYmxlZCA9PT0gdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgY29sdW1ucyByZWZlcmVuY2VcbiAgICovXG4gIGdldENvbHVtbnMoKTogQ29sdW1uQ29uZmlnPGFueT5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbHVtbnM7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFBBR0lOQVRJT04gTUVUSE9EU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIFNldCBjdXJyZW50IHBhZ2VcbiAgICogQHBhcmFtIHBhZ2UgUGFnZSBudW1iZXIgKDAtaW5kZXhlZClcbiAgICovXG4gIHNldFBhZ2UocGFnZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5fcGFnaW5hdGlvbiQudmFsdWU7XG4gICAgaWYgKHBhZ2UgPCAwIHx8IHBhZ2UgPj0gY3VycmVudFN0YXRlLnRvdGFsUGFnZXMpIHtcbiAgICAgIGNvbnNvbGUud2FybihgSW52YWxpZCBwYWdlIG51bWJlcjogJHtwYWdlfS4gVmFsaWQgcmFuZ2U6IDAtJHtjdXJyZW50U3RhdGUudG90YWxQYWdlcyAtIDF9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcGFnaW5hdGlvbiQubmV4dCh7XG4gICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICBjdXJyZW50UGFnZTogcGFnZVxuICAgIH0pO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdwYWdpbmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHBhZ2Ugc2l6ZVxuICAgKiBAcGFyYW0gc2l6ZSBOdW1iZXIgb2YgaXRlbXMgcGVyIHBhZ2VcbiAgICovXG4gIHNldFBhZ2VTaXplKHNpemU6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChzaXplIDw9IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihgSW52YWxpZCBwYWdlIHNpemU6ICR7c2l6ZX0uIE11c3QgYmUgZ3JlYXRlciB0aGFuIDAuYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5fcGFnaW5hdGlvbiQudmFsdWU7XG4gICAgY29uc3QgbmV3VG90YWxQYWdlcyA9IHRoaXMuY2FsY3VsYXRlVG90YWxQYWdlcyhjdXJyZW50U3RhdGUudG90YWxJdGVtcywgc2l6ZSk7XG4gICAgXG4gICAgdGhpcy5fcGFnaW5hdGlvbiQubmV4dCh7XG4gICAgICBjdXJyZW50UGFnZTogMCwgLy8gUmVzZXQgdG8gZmlyc3QgcGFnZVxuICAgICAgcGFnZVNpemU6IHNpemUsXG4gICAgICB0b3RhbEl0ZW1zOiBjdXJyZW50U3RhdGUudG90YWxJdGVtcyxcbiAgICAgIHRvdGFsUGFnZXM6IG5ld1RvdGFsUGFnZXNcbiAgICB9KTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgncGFnaW5hdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0b3RhbCBpdGVtcyAoY2FsbGVkIGFmdGVyIEFQSSByZXNwb25zZSlcbiAgICogQHBhcmFtIHRvdGFsIFRvdGFsIG51bWJlciBvZiBpdGVtc1xuICAgKi9cbiAgc2V0VG90YWxJdGVtcyh0b3RhbDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5fcGFnaW5hdGlvbiQudmFsdWU7XG4gICAgY29uc3QgbmV3VG90YWxQYWdlcyA9IHRoaXMuY2FsY3VsYXRlVG90YWxQYWdlcyh0b3RhbCwgY3VycmVudFN0YXRlLnBhZ2VTaXplKTtcbiAgICBcbiAgICB0aGlzLl9wYWdpbmF0aW9uJC5uZXh0KHtcbiAgICAgIC4uLmN1cnJlbnRTdGF0ZSxcbiAgICAgIHRvdGFsSXRlbXM6IHRvdGFsLFxuICAgICAgdG90YWxQYWdlczogbmV3VG90YWxQYWdlc1xuICAgIH0pO1xuICAgIC8vIERvbid0IGVtaXQgc3RhdGUgY2hhbmdlIGhlcmUgLSB0aGlzIGlzIGNhbGxlZCBhZnRlciBkYXRhIGxvYWRcbiAgfVxuXG4gIC8qKlxuICAgKiBHbyB0byBuZXh0IHBhZ2VcbiAgICovXG4gIG5leHRQYWdlKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuX3BhZ2luYXRpb24kLnZhbHVlO1xuICAgIGlmICh0aGlzLmhhc05leHRQYWdlKCkpIHtcbiAgICAgIHRoaXMuc2V0UGFnZShjdXJyZW50U3RhdGUuY3VycmVudFBhZ2UgKyAxKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR28gdG8gcHJldmlvdXMgcGFnZVxuICAgKi9cbiAgcHJldmlvdXNQYWdlKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuX3BhZ2luYXRpb24kLnZhbHVlO1xuICAgIGlmICh0aGlzLmhhc1ByZXZpb3VzUGFnZSgpKSB7XG4gICAgICB0aGlzLnNldFBhZ2UoY3VycmVudFN0YXRlLmN1cnJlbnRQYWdlIC0gMSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdvIHRvIGZpcnN0IHBhZ2VcbiAgICovXG4gIGZpcnN0UGFnZSgpOiB2b2lkIHtcbiAgICB0aGlzLnNldFBhZ2UoMCk7XG4gIH1cblxuICAvKipcbiAgICogR28gdG8gbGFzdCBwYWdlXG4gICAqL1xuICBsYXN0UGFnZSgpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB0aGlzLl9wYWdpbmF0aW9uJC52YWx1ZTtcbiAgICBpZiAoY3VycmVudFN0YXRlLnRvdGFsUGFnZXMgPiAwKSB7XG4gICAgICB0aGlzLnNldFBhZ2UoY3VycmVudFN0YXRlLnRvdGFsUGFnZXMgLSAxKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlcmUgaXMgYSBuZXh0IHBhZ2VcbiAgICovXG4gIGhhc05leHRQYWdlKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuX3BhZ2luYXRpb24kLnZhbHVlO1xuICAgIHJldHVybiBjdXJyZW50U3RhdGUuY3VycmVudFBhZ2UgPCBjdXJyZW50U3RhdGUudG90YWxQYWdlcyAtIDE7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlcmUgaXMgYSBwcmV2aW91cyBwYWdlXG4gICAqL1xuICBoYXNQcmV2aW91c1BhZ2UoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5fcGFnaW5hdGlvbiQudmFsdWU7XG4gICAgcmV0dXJuIGN1cnJlbnRTdGF0ZS5jdXJyZW50UGFnZSA+IDA7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFNPUlRJTkcgTUVUSE9EUyAob3BlcmF0ZSBvbiBjb2x1bW4gY29uZmlncylcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBTZXQgc29ydCBvbiBhIGNvbHVtbiAoY2xlYXJzIG90aGVyIHNvcnRzKVxuICAgKiBAcGFyYW0gY29sdW1uS2V5IENvbHVtbiBrZXlcbiAgICogQHBhcmFtIGRpcmVjdGlvbiBTb3J0IGRpcmVjdGlvblxuICAgKi9cbiAgc2V0U29ydE9uQ29sdW1uKGNvbHVtbktleTogc3RyaW5nLCBkaXJlY3Rpb246IFNvcnREaXJlY3Rpb24pOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29sdW1uLnNvcnRhYmxlID09PSBmYWxzZSkge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gJHtjb2x1bW5LZXl9IGlzIG5vdCBzb3J0YWJsZWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENsZWFyIGFsbCBvdGhlciBzb3J0c1xuICAgIHRoaXMuX2NvbHVtbnMuZm9yRWFjaChjb2wgPT4ge1xuICAgICAgaWYgKGNvbC5rZXkgIT09IGNvbHVtbktleSkge1xuICAgICAgICBjb2wuc29ydERpcmVjdGlvbiA9IFNvcnREaXJlY3Rpb24uTk9ORTtcbiAgICAgICAgY29sLnNvcnRFbmFibGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBTZXQgc29ydCBvbiB0YXJnZXQgY29sdW1uXG4gICAgY29sdW1uLnNvcnREaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgY29sdW1uLnNvcnRFbmFibGVkID0gZGlyZWN0aW9uICE9PSBTb3J0RGlyZWN0aW9uLk5PTkU7XG5cbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnc29ydGluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBzb3J0IHRvIGEgY29sdW1uIChmb3IgbXVsdGktY29sdW1uIHNvcnRpbmcpXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcGFyYW0gZGlyZWN0aW9uIFNvcnQgZGlyZWN0aW9uXG4gICAqL1xuICBhZGRTb3J0VG9Db2x1bW4oY29sdW1uS2V5OiBzdHJpbmcsIGRpcmVjdGlvbjogU29ydERpcmVjdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xuICAgIGlmICghY29sdW1uKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiBub3QgZm91bmQ6ICR7Y29sdW1uS2V5fWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjb2x1bW4uc29ydGFibGUgPT09IGZhbHNlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYENvbHVtbiAke2NvbHVtbktleX0gaXMgbm90IHNvcnRhYmxlYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29sdW1uLnNvcnREaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgY29sdW1uLnNvcnRFbmFibGVkID0gZGlyZWN0aW9uICE9PSBTb3J0RGlyZWN0aW9uLk5PTkU7XG5cbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnc29ydGluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSBzb3J0IG9uIGEgY29sdW1uIChjeWNsZXMgdGhyb3VnaCBub25lIC0+IGFzYyAtPiBkZXNjIC0+IG5vbmUpXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKi9cbiAgdG9nZ2xlU29ydE9uQ29sdW1uKGNvbHVtbktleTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uIG5vdCBmb3VuZDogJHtjb2x1bW5LZXl9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNvbHVtbi5zb3J0YWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uICR7Y29sdW1uS2V5fSBpcyBub3Qgc29ydGFibGVgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50RGlyZWN0aW9uID0gY29sdW1uLnNvcnREaXJlY3Rpb24gfHwgU29ydERpcmVjdGlvbi5OT05FO1xuICAgIGxldCBuZXdEaXJlY3Rpb246IFNvcnREaXJlY3Rpb247XG5cbiAgICBzd2l0Y2ggKGN1cnJlbnREaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgU29ydERpcmVjdGlvbi5OT05FOlxuICAgICAgICBuZXdEaXJlY3Rpb24gPSBTb3J0RGlyZWN0aW9uLkFTQztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFNvcnREaXJlY3Rpb24uQVNDOlxuICAgICAgICBuZXdEaXJlY3Rpb24gPSBTb3J0RGlyZWN0aW9uLkRFU0M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBTb3J0RGlyZWN0aW9uLkRFU0M6XG4gICAgICAgIG5ld0RpcmVjdGlvbiA9IFNvcnREaXJlY3Rpb24uTk9ORTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBuZXdEaXJlY3Rpb24gPSBTb3J0RGlyZWN0aW9uLkFTQztcbiAgICB9XG5cbiAgICBjb2x1bW4uc29ydERpcmVjdGlvbiA9IG5ld0RpcmVjdGlvbjtcbiAgICBjb2x1bW4uc29ydEVuYWJsZWQgPSBuZXdEaXJlY3Rpb24gIT09IFNvcnREaXJlY3Rpb24uTk9ORTtcblxuICAgIHRoaXMuY2xlYXJGb2N1cygpO1xuICAgIHRoaXMuY2xlYXJFZGl0aW5nQ2VsbCgpO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdzb3J0aW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIHNvcnRpbmdcbiAgICovXG4gIGNsZWFyQWxsU29ydGluZygpOiB2b2lkIHtcbiAgICB0aGlzLl9jb2x1bW5zLmZvckVhY2goY29sID0+IHtcbiAgICAgIGNvbC5zb3J0RGlyZWN0aW9uID0gU29ydERpcmVjdGlvbi5OT05FO1xuICAgICAgY29sLnNvcnRFbmFibGVkID0gZmFsc2U7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNsZWFyRm9jdXMoKTtcbiAgICB0aGlzLmNsZWFyRWRpdGluZ0NlbGwoKTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnc29ydGluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzb3J0IGNvbmZpZ3VyYXRpb24gZm9yIGEgY29sdW1uXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcmV0dXJucyBTb3J0IGNvbmZpZ3VyYXRpb24gb3IgbnVsbFxuICAgKi9cbiAgZ2V0U29ydEZvckNvbHVtbihjb2x1bW5LZXk6IHN0cmluZyk6IHsgZGlyZWN0aW9uOiBTb3J0RGlyZWN0aW9uOyBlbmFibGVkOiBib29sZWFuIH0gfCBudWxsIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpcmVjdGlvbjogY29sdW1uLnNvcnREaXJlY3Rpb24gfHwgU29ydERpcmVjdGlvbi5OT05FLFxuICAgICAgZW5hYmxlZDogY29sdW1uLnNvcnRFbmFibGVkIHx8IGZhbHNlXG4gICAgfTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gRklMVEVSSU5HIE1FVEhPRFMgKG9wZXJhdGUgb24gY29sdW1uIGNvbmZpZ3MpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogU2V0IGZpbHRlciBvbiBhIGNvbHVtblxuICAgKiBAcGFyYW0gY29sdW1uS2V5IENvbHVtbiBrZXlcbiAgICogQHBhcmFtIG9wZXJhdG9yIEZpbHRlciBvcGVyYXRvclxuICAgKiBAcGFyYW0gdmFsdWUgRmlsdGVyIHZhbHVlXG4gICAqL1xuICBzZXRGaWx0ZXJPbkNvbHVtbihjb2x1bW5LZXk6IHN0cmluZywgb3BlcmF0b3I6IEZpbHRlck9wZXJhdG9yLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uIG5vdCBmb3VuZDogJHtjb2x1bW5LZXl9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNvbHVtbi5maWx0ZXJhYmxlID09PSBmYWxzZSkge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gJHtjb2x1bW5LZXl9IGlzIG5vdCBmaWx0ZXJhYmxlYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6ZSBmaWx0ZXJDb25maWcgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgIGlmICghY29sdW1uLmZpbHRlckNvbmZpZykge1xuICAgICAgY29sdW1uLmZpbHRlckNvbmZpZyA9IHt9O1xuICAgIH1cblxuICAgIGNvbHVtbi5maWx0ZXJDb25maWcub3BlcmF0b3IgPSBvcGVyYXRvcjtcbiAgICBjb2x1bW4uZmlsdGVyQ29uZmlnLnZhbHVlID0gdmFsdWU7XG4gICAgY29sdW1uLmZpbHRlckNvbmZpZy5lbmFibGVkID0gdHJ1ZTtcblxuICAgIHRoaXMuY2xlYXJGb2N1cygpO1xuICAgIHRoaXMuY2xlYXJFZGl0aW5nQ2VsbCgpO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdmaWx0ZXJpbmcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBmaWx0ZXIgb24gYSBjb2x1bW5cbiAgICogQHBhcmFtIGNvbHVtbktleSBDb2x1bW4ga2V5XG4gICAqL1xuICBjbGVhckZpbHRlck9uQ29sdW1uKGNvbHVtbktleTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uIG5vdCBmb3VuZDogJHtjb2x1bW5LZXl9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6ZSBmaWx0ZXJDb25maWcgaWYgaXQgZG9lc24ndCBleGlzdCAoZm9yIGNvbnNpc3RlbmN5IHdpdGggc2V0RmlsdGVyT25Db2x1bW4pXG4gICAgaWYgKCFjb2x1bW4uZmlsdGVyQ29uZmlnKSB7XG4gICAgICBjb2x1bW4uZmlsdGVyQ29uZmlnID0ge307XG4gICAgfVxuXG4gICAgY29sdW1uLmZpbHRlckNvbmZpZy52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICBjb2x1bW4uZmlsdGVyQ29uZmlnLmVuYWJsZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuY2xlYXJGb2N1cygpO1xuICAgIHRoaXMuY2xlYXJFZGl0aW5nQ2VsbCgpO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdmaWx0ZXJpbmcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgZmlsdGVyc1xuICAgKi9cbiAgY2xlYXJBbGxGaWx0ZXJzKCk6IHZvaWQge1xuICAgIHRoaXMuX2NvbHVtbnMuZm9yRWFjaChjb2wgPT4ge1xuICAgICAgLy8gSW5pdGlhbGl6ZSBmaWx0ZXJDb25maWcgaWYgaXQgZG9lc24ndCBleGlzdCAoZm9yIGNvbnNpc3RlbmN5IHdpdGggc2V0RmlsdGVyT25Db2x1bW4pXG4gICAgICBpZiAoIWNvbC5maWx0ZXJDb25maWcpIHtcbiAgICAgICAgY29sLmZpbHRlckNvbmZpZyA9IHt9O1xuICAgICAgfVxuICAgICAgXG4gICAgICBjb2wuZmlsdGVyQ29uZmlnLnZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgY29sLmZpbHRlckNvbmZpZy5lbmFibGVkID0gZmFsc2U7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNsZWFyRm9jdXMoKTtcbiAgICB0aGlzLmNsZWFyRWRpdGluZ0NlbGwoKTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnZmlsdGVyaW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGZpbHRlciBlbmFibGVkIHN0YXRlXG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcGFyYW0gZW5hYmxlZCBXaGV0aGVyIGZpbHRlciBpcyBlbmFibGVkXG4gICAqL1xuICBzZXRGaWx0ZXJFbmFibGVkKGNvbHVtbktleTogc3RyaW5nLCBlbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uIG5vdCBmb3VuZDogJHtjb2x1bW5LZXl9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6ZSBmaWx0ZXJDb25maWcgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgIGlmICghY29sdW1uLmZpbHRlckNvbmZpZykge1xuICAgICAgY29sdW1uLmZpbHRlckNvbmZpZyA9IHt9O1xuICAgIH1cblxuICAgIGNvbHVtbi5maWx0ZXJDb25maWcuZW5hYmxlZCA9IGVuYWJsZWQ7XG5cbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnZmlsdGVyaW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGZpbHRlciBjb25maWd1cmF0aW9uIGZvciBhIGNvbHVtblxuICAgKiBAcGFyYW0gY29sdW1uS2V5IENvbHVtbiBrZXlcbiAgICogQHJldHVybnMgRmlsdGVyIGNvbmZpZ3VyYXRpb24gb3IgbnVsbFxuICAgKi9cbiAgZ2V0RmlsdGVyRm9yQ29sdW1uKGNvbHVtbktleTogc3RyaW5nKTogeyBvcGVyYXRvcjogRmlsdGVyT3BlcmF0b3I7IHZhbHVlOiBhbnk7IGVuYWJsZWQ6IGJvb2xlYW4gfSB8IG51bGwge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xuICAgIGlmICghY29sdW1uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgb3BlcmF0b3I6IGNvbHVtbi5maWx0ZXJDb25maWc/Lm9wZXJhdG9yIHx8IEZpbHRlck9wZXJhdG9yLkNPTlRBSU5TLFxuICAgICAgdmFsdWU6IGNvbHVtbi5maWx0ZXJDb25maWc/LnZhbHVlLFxuICAgICAgZW5hYmxlZDogY29sdW1uLmZpbHRlckNvbmZpZz8uZW5hYmxlZCB8fCBmYWxzZVxuICAgIH07XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFNUSUNLWSBDT0xVTU4gTUFOQUdFTUVOVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIEdldCBzdGlja3kgY29sdW1ucyBncm91cGVkIGJ5IHBvc2l0aW9uXG4gICAqIEByZXR1cm5zIE9iamVjdCB3aXRoIGxlZnQgYW5kIHJpZ2h0IHN0aWNreSBjb2x1bW4ga2V5c1xuICAgKi9cbiAgZ2V0U3RpY2t5Q29sdW1ucygpOiB7IGxlZnQ6IHN0cmluZ1tdOyByaWdodDogc3RyaW5nW10gfSB7XG4gICAgY29uc3QgbGVmdCA9IHRoaXMuX2NvbHVtbnNcbiAgICAgIC5maWx0ZXIoY29sID0+IGNvbC5zdGlja3kgPT09ICdsZWZ0JylcbiAgICAgIC5tYXAoY29sID0+IGNvbC5rZXkpO1xuICAgIFxuICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5fY29sdW1uc1xuICAgICAgLmZpbHRlcihjb2wgPT4gY29sLnN0aWNreSA9PT0gJ3JpZ2h0JylcbiAgICAgIC5tYXAoY29sID0+IGNvbC5rZXkpO1xuICAgIFxuICAgIHJldHVybiB7IGxlZnQsIHJpZ2h0IH07XG4gIH1cblxuICAvKipcbiAgICogU2V0IHN0aWNreSBwb3NpdGlvbiBmb3IgYSBjb2x1bW5cbiAgICogQHBhcmFtIGNvbHVtbktleSBDb2x1bW4ga2V5XG4gICAqIEBwYXJhbSBwb3NpdGlvbiBTdGlja3kgcG9zaXRpb24gKCdsZWZ0JywgJ3JpZ2h0Jywgb3IgZmFsc2UpXG4gICAqL1xuICBzZXRTdGlja3lDb2x1bW4oY29sdW1uS2V5OiBzdHJpbmcsIHBvc2l0aW9uOiAnbGVmdCcgfCAncmlnaHQnIHwgZmFsc2UpOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAoY29sdW1uIGFzIGFueSkuc3RpY2t5ID0gcG9zaXRpb247XG4gICAgdGhpcy5jYWxjdWxhdGVTdGlja3lPZmZzZXRzKCk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ2NvbHVtbi1jb25maWcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgc3RpY2t5IG9mZnNldHMgZm9yIGFsbCBzdGlja3kgY29sdW1uc1xuICAgKiBUaGlzIGNhbGN1bGF0ZXMgY3VtdWxhdGl2ZSB3aWR0aHMgZm9yIHBvc2l0aW9uaW5nXG4gICAqIEBwYXJhbSByb3dOdW1iZXJXaWR0aCBPcHRpb25hbCB3aWR0aCBvZiByb3cgbnVtYmVyIGNvbHVtbiB0byBhY2NvdW50IGZvciBpbiBsZWZ0IG9mZnNldFxuICAgKiBAcGFyYW0gc2V0dGluZ3NDb2x1bW5XaWR0aCBPcHRpb25hbCB3aWR0aCBvZiBzZXR0aW5ncyBjb2x1bW4gdG8gYWNjb3VudCBmb3IgaW4gcmlnaHQgb2Zmc2V0XG4gICAqL1xuICBjYWxjdWxhdGVTdGlja3lPZmZzZXRzKHJvd051bWJlcldpZHRoPzogbnVtYmVyLCBzZXR0aW5nc0NvbHVtbldpZHRoPzogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gVXBkYXRlIHN0b3JlZCByb3cgbnVtYmVyIHdpZHRoIGlmIHByb3ZpZGVkXG4gICAgaWYgKHJvd051bWJlcldpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuX3Jvd051bWJlcldpZHRoID0gcm93TnVtYmVyV2lkdGg7XG4gICAgfVxuICAgIFxuICAgIC8vIFVwZGF0ZSBzdG9yZWQgc2V0dGluZ3MgY29sdW1uIHdpZHRoIGlmIHByb3ZpZGVkXG4gICAgaWYgKHNldHRpbmdzQ29sdW1uV2lkdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fc2V0dGluZ3NDb2x1bW5XaWR0aCA9IHNldHRpbmdzQ29sdW1uV2lkdGg7XG4gICAgfVxuICAgIFxuICAgIC8vIENhbGN1bGF0ZSBsZWZ0IHN0aWNreSBvZmZzZXRzXG4gICAgLy8gQWNjb3VudCBmb3Igcm93IG51bWJlciBjb2x1bW4gd2lkdGhcbiAgICBsZXQgbGVmdE9mZnNldCA9IHRoaXMuX3Jvd051bWJlcldpZHRoO1xuICAgIHRoaXMuX2NvbHVtbnMuZm9yRWFjaChjb2wgPT4ge1xuICAgICAgaWYgKGNvbC5zdGlja3kgPT09ICdsZWZ0Jykge1xuICAgICAgICAoY29sIGFzIGFueSkuc3RpY2t5T2Zmc2V0ID0gbGVmdE9mZnNldDtcbiAgICAgICAgbGVmdE9mZnNldCArPSAoY29sLndpZHRoIGFzIG51bWJlcikgfHwgMTAwO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHJpZ2h0IHN0aWNreSBvZmZzZXRzXG4gICAgLy8gQWNjb3VudCBmb3Igc2V0dGluZ3MgY29sdW1uIHdpZHRoIChyb3cgYWN0aW9ucyBjb2x1bW4pXG4gICAgbGV0IHJpZ2h0T2Zmc2V0ID0gdGhpcy5fc2V0dGluZ3NDb2x1bW5XaWR0aDtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5fY29sdW1ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgY29uc3QgY29sID0gdGhpcy5fY29sdW1uc1tpXTtcbiAgICAgIGlmIChjb2wuc3RpY2t5ID09PSAncmlnaHQnKSB7XG4gICAgICAgIChjb2wgYXMgYW55KS5zdGlja3lPZmZzZXQgPSByaWdodE9mZnNldDtcbiAgICAgICAgcmlnaHRPZmZzZXQgKz0gKGNvbC53aWR0aCBhcyBudW1iZXIpIHx8IDEwMDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIENPTFVNTiBNQU5BR0VNRU5UXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogVXBkYXRlIGNvbHVtbnMgcmVmZXJlbmNlXG4gICAqIEBwYXJhbSBjb2x1bW5zIE5ldyBjb2x1bW5zIGFycmF5XG4gICAqL1xuICB1cGRhdGVDb2x1bW5zKGNvbHVtbnM6IENvbHVtbkNvbmZpZzxhbnk+W10pOiB2b2lkIHtcbiAgICB0aGlzLl9jb2x1bW5zID0gY29sdW1ucztcbiAgICB0aGlzLmNhbGN1bGF0ZVN0aWNreU9mZnNldHMoKTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY29sdW1uLWNvbmZpZycpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBDT0xVTU4gVklTSUJJTElUWSBNRVRIT0RTXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogVG9nZ2xlIHZpc2liaWxpdHkgb2YgYSBjb2x1bW5cbiAgICogQHBhcmFtIGNvbHVtbktleSBDb2x1bW4ga2V5XG4gICAqL1xuICB0b2dnbGVDb2x1bW5WaXNpYmlsaXR5KGNvbHVtbktleTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgaWYgKCFjb2x1bW4pIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uIG5vdCBmb3VuZDogJHtjb2x1bW5LZXl9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgY29sdW1uIGlzIGhpZGVhYmxlXG4gICAgaWYgKGNvbHVtbi5oaWRlYWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgIGNvbnNvbGUud2FybihgQ29sdW1uICR7Y29sdW1uS2V5fSBjYW5ub3QgYmUgaGlkZGVuIChoaWRlYWJsZSBpcyBmYWxzZSlgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50VmlzaWJpbGl0eSA9IGNvbHVtbi52aXNpYmxlICE9PSBmYWxzZTsgLy8gRGVmYXVsdCB0byB0cnVlIGlmIG5vdCBzZXRcbiAgICAoY29sdW1uIGFzIGFueSkudmlzaWJsZSA9ICFjdXJyZW50VmlzaWJpbGl0eTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY29sdW1uLXZpc2liaWxpdHknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdmlzaWJpbGl0eSBvZiBhIGNvbHVtblxuICAgKiBAcGFyYW0gY29sdW1uS2V5IENvbHVtbiBrZXlcbiAgICogQHBhcmFtIHZpc2libGUgV2hldGhlciBjb2x1bW4gc2hvdWxkIGJlIHZpc2libGVcbiAgICovXG4gIHNldENvbHVtblZpc2liaWxpdHkoY29sdW1uS2V5OiBzdHJpbmcsIHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcbiAgICBpZiAoIWNvbHVtbikge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gbm90IGZvdW5kOiAke2NvbHVtbktleX1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBjb2x1bW4gaXMgaGlkZWFibGUgKG9ubHkgd2hlbiB0cnlpbmcgdG8gaGlkZSlcbiAgICBpZiAoIXZpc2libGUgJiYgY29sdW1uLmhpZGVhYmxlID09PSBmYWxzZSkge1xuICAgICAgY29uc29sZS53YXJuKGBDb2x1bW4gJHtjb2x1bW5LZXl9IGNhbm5vdCBiZSBoaWRkZW4gKGhpZGVhYmxlIGlzIGZhbHNlKWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIChjb2x1bW4gYXMgYW55KS52aXNpYmxlID0gdmlzaWJsZTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY29sdW1uLXZpc2liaWxpdHknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIHZpc2libGUgY29sdW1uc1xuICAgKiBAcmV0dXJucyBBcnJheSBvZiB2aXNpYmxlIGNvbHVtbiBjb25maWdzXG4gICAqL1xuICBnZXRWaXNpYmxlQ29sdW1ucygpOiBDb2x1bW5Db25maWc8YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fY29sdW1ucy5maWx0ZXIoY29sID0+IGNvbC52aXNpYmxlICE9PSBmYWxzZSk7IC8vIERlZmF1bHQgdG8gdHJ1ZSBpZiBub3Qgc2V0XG4gIH1cblxuICAvKipcbiAgICogR2V0IHZpc2liaWxpdHkgc3RhdGUgZm9yIGFsbCBjb2x1bW5zXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIGNvbHVtbiB2aXNpYmlsaXR5IGluZm9cbiAgICovXG4gIGdldEFsbENvbHVtbnNWaXNpYmlsaXR5KCk6IHsga2V5OiBzdHJpbmc7IGhlYWRlcjogc3RyaW5nOyB2aXNpYmxlOiBib29sZWFuOyBoaWRlYWJsZTogYm9vbGVhbiB9W10ge1xuICAgIHJldHVybiB0aGlzLl9jb2x1bW5zLm1hcChjb2wgPT4gKHtcbiAgICAgIGtleTogY29sLmtleSxcbiAgICAgIGhlYWRlcjogY29sLmhlYWRlciB8fCBjb2wua2V5LFxuICAgICAgdmlzaWJsZTogY29sLnZpc2libGUgIT09IGZhbHNlLCAvLyBEZWZhdWx0IHRvIHRydWUgaWYgbm90IHNldFxuICAgICAgaGlkZWFibGU6IGNvbC5oaWRlYWJsZSAhPT0gZmFsc2UgLy8gRGVmYXVsdCB0byB0cnVlIGlmIG5vdCBzZXRcbiAgICB9KSk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEtFWUJPQVJEIE5BVklHQVRJT04gJiBGT0NVUyBNQU5BR0VNRU5UXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogU2V0IHRhYmxlIGRpbWVuc2lvbnMgZm9yIG5hdmlnYXRpb24gYm91bmRhcmllc1xuICAgKi9cbiAgc2V0RGltZW5zaW9ucyhyb3dDb3VudDogbnVtYmVyLCBjb2x1bW5Db3VudDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5fcm93Q291bnQgPSByb3dDb3VudDtcbiAgICB0aGlzLl9jb2x1bW5Db3VudCA9IGNvbHVtbkNvdW50O1xuICAgIFxuICAgIC8vIFVwZGF0ZSB0b3RhbCByb3dzIGluIHZhbGlkYXRpb24gc3RhdGVcbiAgICB0aGlzLnNldFZhbGlkYXRpb25Sb3dDb3VudChyb3dDb3VudCk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBGb2N1cyBhIGNlbGwgYnkgcG9zaXRpb25cbiAgICovXG4gIGZvY3VzQ2VsbChyb3dJbmRleDogbnVtYmVyLCBjb2x1bW5JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHJvd0luZGV4IDwgMCB8fCByb3dJbmRleCA+PSB0aGlzLl9yb3dDb3VudCkgcmV0dXJuO1xuICAgIGlmIChjb2x1bW5JbmRleCA8IDAgfHwgY29sdW1uSW5kZXggPj0gdGhpcy5fY29sdW1uQ291bnQpIHJldHVybjtcbiAgICBcbiAgICB0aGlzLl9mb2N1c2VkQ2VsbFBvc2l0aW9uJC5uZXh0KHsgcm93SW5kZXgsIGNvbHVtbkluZGV4IH0pO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdjZWxsLWZvY3VzJyk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudGx5IGZvY3VzZWQgcG9zaXRpb25cbiAgICovXG4gIGdldEZvY3VzZWRQb3NpdGlvbigpOiBDZWxsRm9jdXNQb3NpdGlvbiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9mb2N1c2VkQ2VsbFBvc2l0aW9uJC52YWx1ZTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIE5vdGlmeSB0aGF0IGEgY2VsbCBlbnRlcmVkIGVkaXQgbW9kZVxuICAgKi9cbiAgc2V0RWRpdGluZ0NlbGwocm93SW5kZXg6IG51bWJlciwgY29sdW1uSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuX2VkaXRpbmdDZWxsUG9zaXRpb24kLm5leHQoeyByb3dJbmRleCwgY29sdW1uSW5kZXggfSk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ2NlbGwtZWRpdC1zdGFydCcpO1xuICB9XG4gIFxuICAvKipcbiAgICogTm90aWZ5IHRoYXQgZWRpdCBtb2RlIGVuZGVkXG4gICAqL1xuICBjbGVhckVkaXRpbmdDZWxsKCk6IHZvaWQge1xuICAgIHRoaXMuX2VkaXRpbmdDZWxsUG9zaXRpb24kLm5leHQobnVsbCk7XG4gICAgdGhpcy5lbWl0U3RhdGVDaGFuZ2UoJ2NlbGwtZWRpdC1lbmQnKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIENoZWNrIGlmIGFueSBjZWxsIGlzIGN1cnJlbnRseSBlZGl0aW5nXG4gICAqL1xuICBpc0FueUNlbGxFZGl0aW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9lZGl0aW5nQ2VsbFBvc2l0aW9uJC52YWx1ZSAhPT0gbnVsbDtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjdXJyZW50bHkgZWRpdGluZyBwb3NpdGlvblxuICAgKi9cbiAgZ2V0RWRpdGluZ1Bvc2l0aW9uKCk6IENlbGxGb2N1c1Bvc2l0aW9uIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2VkaXRpbmdDZWxsUG9zaXRpb24kLnZhbHVlO1xuICB9XG4gIFxuICAvKipcbiAgICogTW92ZSBmb2N1cyBpbiBhIGRpcmVjdGlvbiB1c2luZyBOYXZpZ2F0aW9uRGlyZWN0aW9uIGVudW1cbiAgICovXG4gIG1vdmVGb2N1cyhkaXJlY3Rpb246IE5hdmlnYXRpb25EaXJlY3Rpb24pOiBib29sZWFuIHtcbiAgICAvLyBCbG9jayBuYXZpZ2F0aW9uIGlmIGFueSBjZWxsIGlzIGVkaXRpbmdcbiAgICBpZiAodGhpcy5pc0FueUNlbGxFZGl0aW5nKCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuX2ZvY3VzZWRDZWxsUG9zaXRpb24kLnZhbHVlO1xuICAgIGlmICghY3VycmVudCkgcmV0dXJuIGZhbHNlO1xuICAgIFxuICAgIGxldCBuZXdSb3cgPSBjdXJyZW50LnJvd0luZGV4O1xuICAgIGxldCBuZXdDb2wgPSBjdXJyZW50LmNvbHVtbkluZGV4O1xuICAgIFxuICAgIC8vIFVzZSBOYXZpZ2F0aW9uRGlyZWN0aW9uIGVudW0gdmFsdWVzXG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgTmF2aWdhdGlvbkRpcmVjdGlvbi5VUDogbmV3Um93LS07IGJyZWFrO1xuICAgICAgY2FzZSBOYXZpZ2F0aW9uRGlyZWN0aW9uLkRPV046IG5ld1JvdysrOyBicmVhaztcbiAgICAgIGNhc2UgTmF2aWdhdGlvbkRpcmVjdGlvbi5MRUZUOiBuZXdDb2wtLTsgYnJlYWs7XG4gICAgICBjYXNlIE5hdmlnYXRpb25EaXJlY3Rpb24uUklHSFQ6IG5ld0NvbCsrOyBicmVhaztcbiAgICB9XG4gICAgXG4gICAgaWYgKG5ld1JvdyA8IDAgfHwgbmV3Um93ID49IHRoaXMuX3Jvd0NvdW50KSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKG5ld0NvbCA8IDAgfHwgbmV3Q29sID49IHRoaXMuX2NvbHVtbkNvdW50KSByZXR1cm4gZmFsc2U7XG4gICAgXG4gICAgdGhpcy5mb2N1c0NlbGwobmV3Um93LCBuZXdDb2wpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2xlYXIgZm9jdXNcbiAgICovXG4gIGNsZWFyRm9jdXMoKTogdm9pZCB7XG4gICAgdGhpcy5fZm9jdXNlZENlbGxQb3NpdGlvbiQubmV4dChudWxsKTtcbiAgICB0aGlzLmVtaXRTdGF0ZUNoYW5nZSgnY2VsbC1mb2N1cycpO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgbmF2aWdhdGlvbiBpcyBhY3RpdmVcbiAgICovXG4gIGlzTmF2aWdhdGlvbkFjdGl2ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fZm9jdXNlZENlbGxQb3NpdGlvbiQudmFsdWUgIT09IG51bGw7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFZBTElEQVRJT04gU1RBVEUgTUVUSE9EU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIFxuICAvKipcbiAgICogVXBkYXRlIGNlbGwgdmFsaWRhdGlvbiBhbmQgYWNjdW11bGF0ZSBpbnRvIHJvdy90YWJsZSB2YWxpZGF0aW9uIHN0YXRlXG4gICAqIE9ubHkgc3RvcmVzIGludmFsaWQgc3RhdGVzIC0gdmFsaWQgcm93cyBhcmUgYXV0b21hdGljYWxseSByZW1vdmVkXG4gICAqL1xuICB1cGRhdGVDZWxsVmFsaWRhdGlvbihyb3dJbmRleDogbnVtYmVyLCBjb2x1bW5LZXk6IHN0cmluZywgaXNWYWxpZDogYm9vbGVhbiwgZXJyb3I/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQudmFsdWU7XG4gICAgY29uc3Qgcm93U3RhdGVzID0gbmV3IE1hcChjdXJyZW50U3RhdGUucm93U3RhdGVzKTtcbiAgICBcbiAgICAvLyBHZXQgZXhpc3Rpbmcgcm93IHN0YXRlIChvbmx5IGV4aXN0cyBpZiByb3cgaGFzIGVycm9ycylcbiAgICBsZXQgcm93U3RhdGUgPSByb3dTdGF0ZXMuZ2V0KHJvd0luZGV4KTtcbiAgICBcbiAgICBpZiAoIWlzVmFsaWQgJiYgZXJyb3IpIHtcbiAgICAgIC8vIENlbGwgaXMgaW52YWxpZCAtIGFkZCBvciB1cGRhdGUgZXJyb3JcbiAgICAgIGlmICghcm93U3RhdGUpIHtcbiAgICAgICAgLy8gQ3JlYXRlIG5ldyByb3cgc3RhdGUgZm9yIHRoaXMgaW52YWxpZCByb3dcbiAgICAgICAgcm93U3RhdGUgPSB7XG4gICAgICAgICAgcm93SW5kZXgsXG4gICAgICAgICAgaXNWYWxpZDogZmFsc2UsXG4gICAgICAgICAgaW52YWxpZENlbGxDb3VudDogMSxcbiAgICAgICAgICBjZWxsRXJyb3JzOiBuZXcgTWFwKFtbY29sdW1uS2V5LCBlcnJvcl1dKSxcbiAgICAgICAgICBsYXN0VmFsaWRhdGVkOiBuZXcgRGF0ZSgpXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBVcGRhdGUgZXhpc3Rpbmcgcm93IHN0YXRlXG4gICAgICAgIGNvbnN0IGNlbGxFcnJvcnMgPSBuZXcgTWFwKHJvd1N0YXRlLmNlbGxFcnJvcnMpO1xuICAgICAgICBjZWxsRXJyb3JzLnNldChjb2x1bW5LZXksIGVycm9yKTtcbiAgICAgICAgXG4gICAgICAgIHJvd1N0YXRlID0ge1xuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIGlzVmFsaWQ6IGZhbHNlLFxuICAgICAgICAgIGludmFsaWRDZWxsQ291bnQ6IGNlbGxFcnJvcnMuc2l6ZSxcbiAgICAgICAgICBjZWxsRXJyb3JzLFxuICAgICAgICAgIGxhc3RWYWxpZGF0ZWQ6IG5ldyBEYXRlKClcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJvd1N0YXRlcy5zZXQocm93SW5kZXgsIHJvd1N0YXRlKTtcbiAgICAgIFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDZWxsIGlzIHZhbGlkIC0gcmVtb3ZlIGVycm9yIGlmIGl0IGV4aXN0c1xuICAgICAgaWYgKHJvd1N0YXRlKSB7XG4gICAgICAgIGNvbnN0IGNlbGxFcnJvcnMgPSBuZXcgTWFwKHJvd1N0YXRlLmNlbGxFcnJvcnMpO1xuICAgICAgICBjZWxsRXJyb3JzLmRlbGV0ZShjb2x1bW5LZXkpO1xuICAgICAgICBcbiAgICAgICAgaWYgKGNlbGxFcnJvcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgIC8vIE5vIG1vcmUgZXJyb3JzIGluIHRoaXMgcm93IC0gcmVtb3ZlIHJvdyBzdGF0ZSBjb21wbGV0ZWx5XG4gICAgICAgICAgcm93U3RhdGVzLmRlbGV0ZShyb3dJbmRleCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gU3RpbGwgaGFzIG90aGVyIGVycm9ycyAtIHVwZGF0ZSByb3cgc3RhdGVcbiAgICAgICAgICByb3dTdGF0ZSA9IHtcbiAgICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkQ2VsbENvdW50OiBjZWxsRXJyb3JzLnNpemUsXG4gICAgICAgICAgICBjZWxsRXJyb3JzLFxuICAgICAgICAgICAgbGFzdFZhbGlkYXRlZDogbmV3IERhdGUoKVxuICAgICAgICAgIH07XG4gICAgICAgICAgcm93U3RhdGVzLnNldChyb3dJbmRleCwgcm93U3RhdGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBJZiByb3dTdGF0ZSBkb2Vzbid0IGV4aXN0LCBjZWxsIHdhcyBhbHJlYWR5IHZhbGlkIC0gZG8gbm90aGluZ1xuICAgIH1cbiAgICBcbiAgICAvLyBSZWNhbGN1bGF0ZSB0YWJsZSBzdGF0ZVxuICAgIC8vIEFsbCByb3dzIGluIHJvd1N0YXRlcyBtYXAgYXJlIGludmFsaWQgYnkgZGVmaW5pdGlvblxuICAgIGNvbnN0IGludmFsaWRSb3dzID0gcm93U3RhdGVzLnNpemU7XG4gICAgXG4gICAgY29uc3QgbmV3VGFibGVTdGF0ZTogVGFibGVWYWxpZGF0aW9uU3RhdGUgPSB7XG4gICAgICBpc1ZhbGlkOiBpbnZhbGlkUm93cyA9PT0gMCxcbiAgICAgIHRvdGFsUm93czogY3VycmVudFN0YXRlLnRvdGFsUm93cywgLy8gS2VlcCB0cmFjayBvZiB0b3RhbCByb3dzIHNlcGFyYXRlbHlcbiAgICAgIHZhbGlkUm93czogY3VycmVudFN0YXRlLnRvdGFsUm93cyAtIGludmFsaWRSb3dzLFxuICAgICAgaW52YWxpZFJvd3MsXG4gICAgICByb3dTdGF0ZXMsXG4gICAgICBsYXN0VXBkYXRlZDogbmV3IERhdGUoKVxuICAgIH07XG4gICAgXG4gICAgLy8gRW1pdCBuZXcgc3RhdGVcbiAgICB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQubmV4dChuZXdUYWJsZVN0YXRlKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHRhYmxlIHZhbGlkYXRpb24gc3RhdGVcbiAgICovXG4gIGdldFRhYmxlVmFsaWRhdGlvblN0YXRlKCk6IFRhYmxlVmFsaWRhdGlvblN0YXRlIHtcbiAgICByZXR1cm4gdGhpcy5fdGFibGVWYWxpZGF0aW9uU3RhdGUkLnZhbHVlO1xuICB9XG4gIFxuICAvKipcbiAgICogU2V0IHRvdGFsIHJvd3MgZm9yIHZhbGlkYXRpb24gc3RhdGUgdHJhY2tpbmdcbiAgICovXG4gIHNldFZhbGlkYXRpb25Sb3dDb3VudCh0b3RhbFJvd3M6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IHRoaXMuX3RhYmxlVmFsaWRhdGlvblN0YXRlJC52YWx1ZTtcbiAgICB0aGlzLl90YWJsZVZhbGlkYXRpb25TdGF0ZSQubmV4dCh7XG4gICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICB0b3RhbFJvd3MsXG4gICAgICBsYXN0VXBkYXRlZDogbmV3IERhdGUoKVxuICAgIH0pO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBTVEFURSBSRVNFVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRvIGluaXRpYWwgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZXNldFBhZ2luYXRpb24oKTtcbiAgICB0aGlzLnJlc2V0QWxsU29ydGluZygpO1xuICAgIHRoaXMucmVzZXRBbGxGaWx0ZXJzKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgcGFnaW5hdGlvbiBvbmx5XG4gICAqL1xuICByZXNldFBhZ2luYXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5fcGFnaW5hdGlvbiQubmV4dCh7XG4gICAgICBjdXJyZW50UGFnZTogdGhpcy5faW5pdGlhbENvbmZpZy5pbml0aWFsUGFnZSEsXG4gICAgICBwYWdlU2l6ZTogdGhpcy5faW5pdGlhbENvbmZpZy5wYWdlU2l6ZSEsXG4gICAgICB0b3RhbEl0ZW1zOiAwLFxuICAgICAgdG90YWxQYWdlczogMFxuICAgIH0pO1xuICAgIHRoaXMuZW1pdFN0YXRlQ2hhbmdlKCdwYWdpbmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgYWxsIGNvbHVtbiBzb3J0c1xuICAgKi9cbiAgcmVzZXRBbGxTb3J0aW5nKCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJBbGxTb3J0aW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgYWxsIGNvbHVtbiBmaWx0ZXJzXG4gICAqL1xuICByZXNldEFsbEZpbHRlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhckFsbEZpbHRlcnMoKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gSU5URVJOQUwgTUVUSE9EU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIEZpbmQgYSBjb2x1bW4gYnkga2V5XG4gICAqIEBwYXJhbSBjb2x1bW5LZXkgQ29sdW1uIGtleVxuICAgKiBAcmV0dXJucyBDb2x1bW4gY29uZmlnIG9yIHVuZGVmaW5lZFxuICAgKi9cbiAgcHJpdmF0ZSBmaW5kQ29sdW1uKGNvbHVtbktleTogc3RyaW5nKTogQ29sdW1uQ29uZmlnPGFueT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9jb2x1bW5zLmZpbmQoY29sID0+IGNvbC5rZXkgPT09IGNvbHVtbktleSk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRvdGFsIHBhZ2VzXG4gICAqIEBwYXJhbSB0b3RhbEl0ZW1zIFRvdGFsIG51bWJlciBvZiBpdGVtc1xuICAgKiBAcGFyYW0gcGFnZVNpemUgUGFnZSBzaXplXG4gICAqIEByZXR1cm5zIFRvdGFsIG51bWJlciBvZiBwYWdlc1xuICAgKi9cbiAgcHJpdmF0ZSBjYWxjdWxhdGVUb3RhbFBhZ2VzKHRvdGFsSXRlbXM6IG51bWJlciA9IDAsIHBhZ2VTaXplOiBudW1iZXIgPSAyNSk6IG51bWJlciB7XG4gICAgaWYgKHRvdGFsSXRlbXMgPT09IDAgfHwgcGFnZVNpemUgPT09IDApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gTWF0aC5jZWlsKHRvdGFsSXRlbXMgLyBwYWdlU2l6ZSk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdCBzdGF0ZSBjaGFuZ2UgZXZlbnRcbiAgICogQHBhcmFtIHR5cGUgVHlwZSBvZiBjaGFuZ2VcbiAgICovXG4gIHByaXZhdGUgZW1pdFN0YXRlQ2hhbmdlKHR5cGU6IFRhYmxlU3RhdGVDaGFuZ2VFdmVudFsndHlwZSddKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLmJ1aWxkU3RhdGVTbmFwc2hvdCgpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlJC5uZXh0KHtcbiAgICAgIHR5cGUsXG4gICAgICBzdGF0ZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHN0YXRlIHNuYXBzaG90IGZyb20gY3VycmVudCBzdGF0ZVxuICAgKiBAcmV0dXJucyBTdGF0ZSBzbmFwc2hvdFxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFN0YXRlU25hcHNob3QoKTogVGFibGVTdGF0ZVNuYXBzaG90IHtcbiAgICByZXR1cm4ge1xuICAgICAgcGFnaW5hdGlvbjogdGhpcy5nZXRQYWdpbmF0aW9uKCksXG4gICAgICBcbiAgICAgIC8vIEJ1aWxkIGZ1bGwgc29ydCBzdGF0ZSB3aXRoIGRpcmVjdGlvbiBhbmQgcHJpb3JpdHlcbiAgICAgIHNvcnRlZENvbHVtbnM6IHRoaXMuX2NvbHVtbnNcbiAgICAgICAgLmZpbHRlcihjb2wgPT4gY29sLnNvcnRFbmFibGVkID09PSB0cnVlKVxuICAgICAgICAubWFwKChjb2wsIGluZGV4KSA9PiAoe1xuICAgICAgICAgIGNvbHVtbktleTogY29sLmtleSxcbiAgICAgICAgICBkaXJlY3Rpb246IGNvbC5zb3J0RGlyZWN0aW9uIHx8IFNvcnREaXJlY3Rpb24uTk9ORSxcbiAgICAgICAgICBwcmlvcml0eTogaW5kZXggIC8vIFNvcnQgb3JkZXIgYmFzZWQgb24gZW5hYmxlbWVudCBvcmRlclxuICAgICAgICB9KSksXG4gICAgICBcbiAgICAgIC8vIEJ1aWxkIGZ1bGwgZmlsdGVyIHN0YXRlIHdpdGggb3BlcmF0b3IgYW5kIHZhbHVlXG4gICAgICBmaWx0ZXJlZENvbHVtbnM6IHRoaXMuX2NvbHVtbnNcbiAgICAgICAgLmZpbHRlcihjb2wgPT4gY29sLmZpbHRlckNvbmZpZz8uZW5hYmxlZCA9PT0gdHJ1ZSlcbiAgICAgICAgLm1hcChjb2wgPT4gKHtcbiAgICAgICAgICBjb2x1bW5LZXk6IGNvbC5rZXksXG4gICAgICAgICAgb3BlcmF0b3I6IGNvbC5maWx0ZXJDb25maWc/Lm9wZXJhdG9yIHx8IEZpbHRlck9wZXJhdG9yLkNPTlRBSU5TLFxuICAgICAgICAgIHZhbHVlOiBjb2wuZmlsdGVyQ29uZmlnPy52YWx1ZSxcbiAgICAgICAgICBlbmFibGVkOiB0cnVlXG4gICAgICAgIH0pKVxuICAgIH07XG4gIH1cbn1cblxuIl19
|