@aquera/ngx-smart-table 0.0.17-alpha → 0.0.18-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/{fesm2020 → fesm2022}/aquera-ngx-smart-table.mjs +1579 -2101
- package/fesm2022/aquera-ngx-smart-table.mjs.map +1 -0
- package/package.json +8 -16
- package/types/aquera-ngx-smart-table.d.ts +5909 -0
- package/aquera-ngx-smart-table.d.ts +0 -5
- package/esm2020/aquera-ngx-smart-table.mjs +0 -5
- package/esm2020/lib/builder/components/builder-preview/builder-preview.component.mjs +0 -63
- package/esm2020/lib/builder/components/builder-toolbar/builder-toolbar.component.mjs +0 -115
- package/esm2020/lib/builder/components/column-editor/column-editor.component.mjs +0 -206
- package/esm2020/lib/builder/components/column-list/column-list.component.mjs +0 -125
- package/esm2020/lib/builder/components/definition-builder/definition-builder.component.mjs +0 -105
- package/esm2020/lib/builder/components/table-config-editor/table-config-editor.component.mjs +0 -132
- package/esm2020/lib/builder/definition-builder.module.mjs +0 -70
- package/esm2020/lib/builder/models/builder-state.interface.mjs +0 -5
- package/esm2020/lib/builder/services/definition-builder.service.mjs +0 -251
- package/esm2020/lib/builder/services/definition-export.service.mjs +0 -167
- package/esm2020/lib/builder/services/definition-import.service.mjs +0 -193
- package/esm2020/lib/builder/services/sample-data-generator.service.mjs +0 -126
- package/esm2020/lib/builder/utils/config-validator.util.mjs +0 -165
- package/esm2020/lib/builder/utils/typescript-generator.util.mjs +0 -206
- package/esm2020/lib/editors/index.mjs +0 -9
- package/esm2020/lib/editors/nile-autocomplete-editor.mjs +0 -228
- package/esm2020/lib/editors/nile-calendar-editor.mjs +0 -211
- package/esm2020/lib/editors/nile-date-picker-editor.mjs +0 -188
- package/esm2020/lib/editors/nile-input-editor.mjs +0 -235
- package/esm2020/lib/editors/nile-select-editor.mjs +0 -498
- package/esm2020/lib/factories/column-config.factory.mjs +0 -231
- package/esm2020/lib/models/autosave-config.interface.mjs +0 -8
- package/esm2020/lib/models/base-column-config.class.mjs +0 -253
- package/esm2020/lib/models/cell-strategies.interface.mjs +0 -6
- package/esm2020/lib/models/cell-types.mjs +0 -147
- package/esm2020/lib/models/column-action.interface.mjs +0 -6
- package/esm2020/lib/models/column-config.interface.mjs +0 -43
- package/esm2020/lib/models/column-config.utils.mjs +0 -101
- package/esm2020/lib/models/row-action.interface.mjs +0 -5
- package/esm2020/lib/models/row-validator.interface.mjs +0 -2
- package/esm2020/lib/models/schema-validation.interface.mjs +0 -2
- package/esm2020/lib/models/sheet-action.interface.mjs +0 -5
- package/esm2020/lib/models/sheet-config.interface.mjs +0 -5
- package/esm2020/lib/models/table-config.interface.mjs +0 -107
- package/esm2020/lib/models/table-validator.interface.mjs +0 -2
- package/esm2020/lib/models/workbook-action.interface.mjs +0 -5
- package/esm2020/lib/models/workbook-config.interface.mjs +0 -5
- package/esm2020/lib/renderer/components/st-add-column-button/st-add-column-button.component.mjs +0 -24
- package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +0 -397
- package/esm2020/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.mjs +0 -103
- package/esm2020/lib/renderer/components/st-column-filter/st-column-filter.component.mjs +0 -383
- package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +0 -232
- package/esm2020/lib/renderer/components/st-column-visibility/st-column-visibility.component.mjs +0 -97
- package/esm2020/lib/renderer/components/st-header/st-header.component.mjs +0 -157
- package/esm2020/lib/renderer/components/st-pagination/st-pagination.component.mjs +0 -87
- package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +0 -167
- package/esm2020/lib/renderer/components/st-sheet/st-sheet.component.mjs +0 -165
- package/esm2020/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.mjs +0 -112
- package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +0 -1453
- package/esm2020/lib/renderer/components/st-table-actions/st-table-actions.component.mjs +0 -169
- package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +0 -581
- package/esm2020/lib/renderer/directives/click-outside.directive.mjs +0 -28
- package/esm2020/lib/renderer/directives/st-column-resize.directive.mjs +0 -108
- package/esm2020/lib/renderer/directives/st-keyboard-navigation.directive.mjs +0 -83
- package/esm2020/lib/renderer/models/cell-state.interface.mjs +0 -66
- package/esm2020/lib/renderer/models/cell.class.mjs +0 -389
- package/esm2020/lib/renderer/models/row-validation-state.interface.mjs +0 -7
- package/esm2020/lib/renderer/models/sheet-state.class.mjs +0 -90
- package/esm2020/lib/renderer/models/sheet-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/table-state.class.mjs +0 -871
- package/esm2020/lib/renderer/models/table-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/table-types.mjs +0 -29
- package/esm2020/lib/renderer/models/table-validation-state.interface.mjs +0 -7
- package/esm2020/lib/renderer/models/workbook-state.class.mjs +0 -174
- package/esm2020/lib/renderer/models/workbook-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/z-index.enum.mjs +0 -55
- package/esm2020/lib/schemas/table-config.schema.mjs +0 -472
- package/esm2020/lib/services/autosave.service.mjs +0 -92
- package/esm2020/lib/services/custom-validation-rules.util.mjs +0 -124
- package/esm2020/lib/services/json-schema-validator.service.mjs +0 -216
- package/esm2020/lib/services/row-validation.service.mjs +0 -42
- package/esm2020/lib/services/validation-logger.service.mjs +0 -177
- package/esm2020/lib/services/virtual-scroll.service.mjs +0 -52
- package/esm2020/lib/shared/shared-table-components.module.mjs +0 -35
- package/esm2020/lib/smart-table.module.mjs +0 -124
- package/esm2020/lib/strategies/default-editors.mjs +0 -433
- package/esm2020/lib/strategies/default-formatters.mjs +0 -238
- package/esm2020/lib/strategies/default-validators.mjs +0 -327
- package/esm2020/public-api.mjs +0 -146
- package/fesm2015/aquera-ngx-smart-table.mjs +0 -12347
- package/fesm2015/aquera-ngx-smart-table.mjs.map +0 -1
- package/fesm2020/aquera-ngx-smart-table.mjs.map +0 -1
- package/lib/builder/components/builder-preview/builder-preview.component.d.ts +0 -31
- package/lib/builder/components/builder-toolbar/builder-toolbar.component.d.ts +0 -53
- package/lib/builder/components/column-editor/column-editor.component.d.ts +0 -69
- package/lib/builder/components/column-list/column-list.component.d.ts +0 -65
- package/lib/builder/components/definition-builder/definition-builder.component.d.ts +0 -58
- package/lib/builder/components/table-config-editor/table-config-editor.component.d.ts +0 -32
- package/lib/builder/definition-builder.module.d.ts +0 -15
- package/lib/builder/models/builder-state.interface.d.ts +0 -93
- package/lib/builder/services/definition-builder.service.d.ts +0 -80
- package/lib/builder/services/definition-export.service.d.ts +0 -59
- package/lib/builder/services/definition-import.service.d.ts +0 -31
- package/lib/builder/services/sample-data-generator.service.d.ts +0 -41
- package/lib/builder/utils/config-validator.util.d.ts +0 -32
- package/lib/builder/utils/typescript-generator.util.d.ts +0 -29
- package/lib/editors/index.d.ts +0 -8
- package/lib/editors/nile-autocomplete-editor.d.ts +0 -102
- package/lib/editors/nile-calendar-editor.d.ts +0 -88
- package/lib/editors/nile-date-picker-editor.d.ts +0 -97
- package/lib/editors/nile-input-editor.d.ts +0 -67
- package/lib/editors/nile-select-editor.d.ts +0 -113
- package/lib/factories/column-config.factory.d.ts +0 -73
- package/lib/models/autosave-config.interface.d.ts +0 -23
- package/lib/models/base-column-config.class.d.ts +0 -115
- package/lib/models/cell-strategies.interface.d.ts +0 -188
- package/lib/models/cell-types.d.ts +0 -337
- package/lib/models/column-action.interface.d.ts +0 -86
- package/lib/models/column-config.interface.d.ts +0 -272
- package/lib/models/column-config.utils.d.ts +0 -37
- package/lib/models/row-action.interface.d.ts +0 -86
- package/lib/models/row-validator.interface.d.ts +0 -37
- package/lib/models/schema-validation.interface.d.ts +0 -42
- package/lib/models/sheet-action.interface.d.ts +0 -59
- package/lib/models/sheet-config.interface.d.ts +0 -41
- package/lib/models/table-config.interface.d.ts +0 -251
- package/lib/models/table-validator.interface.d.ts +0 -40
- package/lib/models/workbook-action.interface.d.ts +0 -95
- package/lib/models/workbook-config.interface.d.ts +0 -107
- package/lib/renderer/components/st-add-column-button/st-add-column-button.component.d.ts +0 -9
- package/lib/renderer/components/st-cell/st-cell.component.d.ts +0 -69
- package/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.d.ts +0 -39
- package/lib/renderer/components/st-column-filter/st-column-filter.component.d.ts +0 -139
- package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +0 -81
- package/lib/renderer/components/st-column-visibility/st-column-visibility.component.d.ts +0 -44
- package/lib/renderer/components/st-header/st-header.component.d.ts +0 -93
- package/lib/renderer/components/st-pagination/st-pagination.component.d.ts +0 -42
- package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +0 -67
- package/lib/renderer/components/st-sheet/st-sheet.component.d.ts +0 -98
- package/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.d.ts +0 -58
- package/lib/renderer/components/st-table/st-table.component.d.ts +0 -380
- package/lib/renderer/components/st-table-actions/st-table-actions.component.d.ts +0 -77
- package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +0 -275
- package/lib/renderer/directives/click-outside.directive.d.ts +0 -10
- package/lib/renderer/directives/st-column-resize.directive.d.ts +0 -44
- package/lib/renderer/directives/st-keyboard-navigation.directive.d.ts +0 -19
- package/lib/renderer/models/cell-state.interface.d.ts +0 -118
- package/lib/renderer/models/cell.class.d.ts +0 -174
- package/lib/renderer/models/row-validation-state.interface.d.ts +0 -27
- package/lib/renderer/models/sheet-state.class.d.ts +0 -67
- package/lib/renderer/models/sheet-state.interface.d.ts +0 -55
- package/lib/renderer/models/table-state.class.d.ts +0 -320
- package/lib/renderer/models/table-state.interface.d.ts +0 -18
- package/lib/renderer/models/table-types.d.ts +0 -228
- package/lib/renderer/models/table-validation-state.interface.d.ts +0 -34
- package/lib/renderer/models/workbook-state.class.d.ts +0 -117
- package/lib/renderer/models/workbook-state.interface.d.ts +0 -71
- package/lib/renderer/models/z-index.enum.d.ts +0 -44
- package/lib/schemas/table-config.schema.d.ts +0 -455
- package/lib/services/autosave.service.d.ts +0 -73
- package/lib/services/custom-validation-rules.util.d.ts +0 -12
- package/lib/services/json-schema-validator.service.d.ts +0 -49
- package/lib/services/row-validation.service.d.ts +0 -17
- package/lib/services/validation-logger.service.d.ts +0 -87
- package/lib/services/virtual-scroll.service.d.ts +0 -44
- package/lib/shared/shared-table-components.module.d.ts +0 -9
- package/lib/smart-table.module.d.ts +0 -26
- package/lib/strategies/default-editors.d.ts +0 -109
- package/lib/strategies/default-formatters.d.ts +0 -116
- package/lib/strategies/default-validators.d.ts +0 -113
- package/public-api.d.ts +0 -70
- package/src/lib/builder/README.md +0 -30
- package/src/lib/editors/README.md +0 -303
- package/src/lib/renderer/components/st-column-filter/README.md +0 -286
|
@@ -1,581 +0,0 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter, ViewChild, } from '@angular/core';
|
|
2
|
-
import { StTableComponent } from '../st-table/st-table.component';
|
|
3
|
-
import { BehaviorSubject, Subject, merge } from 'rxjs';
|
|
4
|
-
import { debounceTime, distinctUntilChanged, takeUntil, tap } from 'rxjs/operators';
|
|
5
|
-
import { WorkbookState } from '../../models/workbook-state.class';
|
|
6
|
-
import { TableState } from '../../models/table-state.class';
|
|
7
|
-
import { DEFAULT_AUTOSAVE_CONFIG } from '../../../models/autosave-config.interface';
|
|
8
|
-
import * as i0 from "@angular/core";
|
|
9
|
-
import * as i1 from "../../../services/autosave.service";
|
|
10
|
-
import * as i2 from "../st-table/st-table.component";
|
|
11
|
-
import * as i3 from "@angular/common";
|
|
12
|
-
export class StWorkbookComponent {
|
|
13
|
-
constructor(autosaveService, cdr) {
|
|
14
|
-
this.autosaveService = autosaveService;
|
|
15
|
-
this.cdr = cdr;
|
|
16
|
-
/**
|
|
17
|
-
* Map of sheet ID to data array
|
|
18
|
-
*/
|
|
19
|
-
this.sheetsData = new BehaviorSubject(new Map());
|
|
20
|
-
/**
|
|
21
|
-
* Emitted when active sheet changes
|
|
22
|
-
*/
|
|
23
|
-
this.sheetChanged = new EventEmitter();
|
|
24
|
-
/**
|
|
25
|
-
* Emitted when add sheet button is clicked
|
|
26
|
-
*/
|
|
27
|
-
this.addSheet = new EventEmitter();
|
|
28
|
-
/**
|
|
29
|
-
* Emitted when a sheet tab action is clicked
|
|
30
|
-
*/
|
|
31
|
-
this.sheetTabAction = new EventEmitter();
|
|
32
|
-
/**
|
|
33
|
-
* Emitted when a workbook action is clicked
|
|
34
|
-
*/
|
|
35
|
-
this.workbookAction = new EventEmitter();
|
|
36
|
-
/**
|
|
37
|
-
* Emitted when cell value changes
|
|
38
|
-
*/
|
|
39
|
-
this.cellChange = new EventEmitter();
|
|
40
|
-
/**
|
|
41
|
-
* Emitted when cell is saved
|
|
42
|
-
*/
|
|
43
|
-
this.cellSave = new EventEmitter();
|
|
44
|
-
/**
|
|
45
|
-
* Emitted when table state changes
|
|
46
|
-
*/
|
|
47
|
-
this.tableStateChange = new EventEmitter();
|
|
48
|
-
/**
|
|
49
|
-
* Emitted when fullscreen is toggled
|
|
50
|
-
*/
|
|
51
|
-
this.fullscreenToggle = new EventEmitter();
|
|
52
|
-
/**
|
|
53
|
-
* Emitted when user navigates past last row (arrow down at bottom)
|
|
54
|
-
* Only emitted if addRowOnNavigatePastEnd is enabled in tableConfig
|
|
55
|
-
*/
|
|
56
|
-
this.requestAddRow = new EventEmitter();
|
|
57
|
-
/**
|
|
58
|
-
* Array of sheets
|
|
59
|
-
*/
|
|
60
|
-
this.sheets = [];
|
|
61
|
-
/**
|
|
62
|
-
* Active sheet index
|
|
63
|
-
*/
|
|
64
|
-
this.activeSheetIndex = 0;
|
|
65
|
-
/**
|
|
66
|
-
* Current table config (for active sheet)
|
|
67
|
-
*/
|
|
68
|
-
this.currentTableConfig = null;
|
|
69
|
-
/**
|
|
70
|
-
* Current table data (for active sheet) - using BehaviorSubject for reactive updates
|
|
71
|
-
*/
|
|
72
|
-
this.currentTableData$ = new BehaviorSubject([]);
|
|
73
|
-
/**
|
|
74
|
-
* Current table state (for active sheet)
|
|
75
|
-
*/
|
|
76
|
-
this.currentTableState = null;
|
|
77
|
-
/**
|
|
78
|
-
* Unique key for table component (changes on sheet switch to force reinitialization)
|
|
79
|
-
*/
|
|
80
|
-
this.tableComponentKey = '';
|
|
81
|
-
/**
|
|
82
|
-
* Fullscreen state observable
|
|
83
|
-
*/
|
|
84
|
-
this.isFullscreen$ = new BehaviorSubject(false);
|
|
85
|
-
/**
|
|
86
|
-
* Tab actions dropdown state
|
|
87
|
-
*/
|
|
88
|
-
this.tabActionsOpen = false;
|
|
89
|
-
this.selectedSheet = null;
|
|
90
|
-
this.selectedSheetIndex = -1;
|
|
91
|
-
this.tabActionsPosition = {};
|
|
92
|
-
/**
|
|
93
|
-
* Workbook actions dropdown state
|
|
94
|
-
*/
|
|
95
|
-
this.workbookActionsOpen = false;
|
|
96
|
-
this.workbookActionsPosition = {};
|
|
97
|
-
/**
|
|
98
|
-
* Visible workbook actions for dropdown (filtered by hidden and showInToolbar)
|
|
99
|
-
*/
|
|
100
|
-
this.visibleWorkbookActions = [];
|
|
101
|
-
/**
|
|
102
|
-
* Workbook actions to show directly in toolbar
|
|
103
|
-
*/
|
|
104
|
-
this.toolbarWorkbookActions = [];
|
|
105
|
-
/**
|
|
106
|
-
* Destroy subject for cleanup
|
|
107
|
-
*/
|
|
108
|
-
this.destroy$ = new Subject();
|
|
109
|
-
/**
|
|
110
|
-
* Autosave enabled flag
|
|
111
|
-
*/
|
|
112
|
-
this.autosaveEnabled = false;
|
|
113
|
-
/**
|
|
114
|
-
* Autosave strategy
|
|
115
|
-
*/
|
|
116
|
-
this.autosaveStrategy = 'lazy';
|
|
117
|
-
/**
|
|
118
|
-
* Last save timestamp
|
|
119
|
-
*/
|
|
120
|
-
this.lastSaveTime = null;
|
|
121
|
-
/**
|
|
122
|
-
* Saving indicator
|
|
123
|
-
*/
|
|
124
|
-
this.isSaving = false;
|
|
125
|
-
/**
|
|
126
|
-
* Beforeunload handler reference
|
|
127
|
-
*/
|
|
128
|
-
this.beforeUnloadHandler = null;
|
|
129
|
-
}
|
|
130
|
-
ngOnInit() {
|
|
131
|
-
this.initializeComponent();
|
|
132
|
-
// Subscribe to sheetsData changes to update currentTableData$ reactively
|
|
133
|
-
this.sheetsData.pipe(takeUntil(this.destroy$)).subscribe((dataMap) => {
|
|
134
|
-
if (this.selectedSheet && dataMap) {
|
|
135
|
-
const newData = dataMap.get(this.selectedSheet.id);
|
|
136
|
-
if (newData) {
|
|
137
|
-
// Update the BehaviorSubject - st-table will react automatically
|
|
138
|
-
this.currentTableData$.next([...newData]);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
// Initialize autosave if enabled
|
|
143
|
-
const autosaveConfig = this.config.autosave || DEFAULT_AUTOSAVE_CONFIG;
|
|
144
|
-
this.autosaveEnabled = autosaveConfig.enabled;
|
|
145
|
-
this.autosaveStrategy = autosaveConfig.strategy;
|
|
146
|
-
if (this.autosaveEnabled) {
|
|
147
|
-
this.setupAutoRestore();
|
|
148
|
-
this.initializeAutosave();
|
|
149
|
-
this.setupBeforeUnloadWarning();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
ngOnChanges(changes) {
|
|
153
|
-
if (changes['config']) {
|
|
154
|
-
const isFirstChange = changes['config'].firstChange;
|
|
155
|
-
this.initializeComponent(isFirstChange);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Initialize component state
|
|
160
|
-
* @param isFirstInit Whether this is the first initialization (true) or a config update (false)
|
|
161
|
-
*/
|
|
162
|
-
initializeComponent(isFirstInit = true) {
|
|
163
|
-
if (!this.config)
|
|
164
|
-
return;
|
|
165
|
-
const previousSheetCount = this.sheets.length;
|
|
166
|
-
this.sheets = [...this.config.sheets];
|
|
167
|
-
const newSheetCount = this.sheets.length;
|
|
168
|
-
// Only reset activeSheetIndex on first init, preserve it on config updates
|
|
169
|
-
if (isFirstInit) {
|
|
170
|
-
this.activeSheetIndex = this.config.initialActiveSheetIndex || 0;
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
// Check if a new sheet was added - switch to the new sheet
|
|
174
|
-
if (newSheetCount > previousSheetCount) {
|
|
175
|
-
this.activeSheetIndex = newSheetCount - 1; // Switch to the newly added sheet
|
|
176
|
-
}
|
|
177
|
-
// Ensure activeSheetIndex is still valid after config change (e.g., sheet deleted)
|
|
178
|
-
else if (this.activeSheetIndex >= this.sheets.length) {
|
|
179
|
-
this.activeSheetIndex = Math.max(0, this.sheets.length - 1);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (!this.state) {
|
|
183
|
-
this.internalState = new WorkbookState({
|
|
184
|
-
id: this.config.id,
|
|
185
|
-
name: this.config.name,
|
|
186
|
-
initialActiveSheetIndex: this.activeSheetIndex
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
this.updateVisibleWorkbookActions();
|
|
190
|
-
this.updateActiveSheet();
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Get active state (external or internal)
|
|
194
|
-
*/
|
|
195
|
-
get activeState() {
|
|
196
|
-
return this.state || this.internalState;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Handle tab change event from nile-tab-group
|
|
200
|
-
*/
|
|
201
|
-
onTabChange(event) {
|
|
202
|
-
const newIndex = event.detail?.index ?? event;
|
|
203
|
-
// Ignore if clicked on toolbar tab
|
|
204
|
-
if (newIndex >= this.sheets.length) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
this.activeSheetIndex = newIndex;
|
|
208
|
-
this.activeState.setActiveSheetIndex(newIndex);
|
|
209
|
-
this.updateActiveSheet();
|
|
210
|
-
this.sheetChanged.emit(this.activeSheetIndex);
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Update active sheet data (triggers table re-initialization with new config/state)
|
|
214
|
-
*/
|
|
215
|
-
updateActiveSheet() {
|
|
216
|
-
const sheet = this.sheets[this.activeSheetIndex];
|
|
217
|
-
if (!sheet)
|
|
218
|
-
return;
|
|
219
|
-
// Update selected sheet reference for data subscriptions
|
|
220
|
-
this.selectedSheet = sheet;
|
|
221
|
-
this.selectedSheetIndex = this.activeSheetIndex;
|
|
222
|
-
// Get sheet data
|
|
223
|
-
const sheetData = this.sheetsData.getValue()?.get(sheet.id) || [];
|
|
224
|
-
// Create a fresh TableState for this sheet (lazy initialization)
|
|
225
|
-
// This ensures the table reinitializes with new config and state
|
|
226
|
-
const tableState = new TableState(sheet.tableConfig.columns, {
|
|
227
|
-
initialPage: sheet.tableConfig.initialState?.page || 1,
|
|
228
|
-
pageSize: sheet.tableConfig.pagination?.pageSize || 25
|
|
229
|
-
});
|
|
230
|
-
// Update current table properties (triggers Angular change detection)
|
|
231
|
-
// The st-table component will detect these changes and reinitialize
|
|
232
|
-
this.currentTableConfig = { ...sheet.tableConfig };
|
|
233
|
-
this.currentTableData$.next(sheetData);
|
|
234
|
-
this.currentTableState = tableState;
|
|
235
|
-
// Update component key to force DOM re-creation (true lazy loading)
|
|
236
|
-
// This ensures complete reinitialization of st-table component
|
|
237
|
-
this.tableComponentKey = `${sheet.id}-${Date.now()}`;
|
|
238
|
-
// Store the table state in workbook state for persistence
|
|
239
|
-
this.activeState.setSheetTableState(sheet.id, tableState);
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Add new sheet
|
|
243
|
-
*/
|
|
244
|
-
onAddSheet() {
|
|
245
|
-
this.addSheet.emit();
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* TrackBy function to force component recreation when key changes
|
|
249
|
-
*/
|
|
250
|
-
trackByKey(index, key) {
|
|
251
|
-
return key;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Check if can add more sheets
|
|
255
|
-
*/
|
|
256
|
-
get canAddSheet() {
|
|
257
|
-
if (this.config.display?.allowAddSheet === false) {
|
|
258
|
-
return false;
|
|
259
|
-
}
|
|
260
|
-
if (this.config.display?.maxSheets) {
|
|
261
|
-
return this.sheets.length < this.config.display.maxSheets;
|
|
262
|
-
}
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Get minimum sheets required
|
|
267
|
-
*/
|
|
268
|
-
get minSheets() {
|
|
269
|
-
return this.config.display?.minSheets || 1;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Open tab actions dropdown
|
|
273
|
-
*/
|
|
274
|
-
openTabActions(event, sheet, index) {
|
|
275
|
-
event.stopPropagation();
|
|
276
|
-
this.selectedSheet = sheet;
|
|
277
|
-
this.selectedSheetIndex = index;
|
|
278
|
-
this.tabActionsOpen = true;
|
|
279
|
-
// Position dropdown
|
|
280
|
-
const target = event.currentTarget;
|
|
281
|
-
const rect = target.getBoundingClientRect();
|
|
282
|
-
this.tabActionsPosition = {
|
|
283
|
-
top: `${rect.bottom + 4}px`,
|
|
284
|
-
left: `${rect.left}px`
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Close tab actions dropdown
|
|
289
|
-
*/
|
|
290
|
-
closeTabActions() {
|
|
291
|
-
this.tabActionsOpen = false;
|
|
292
|
-
this.selectedSheet = null;
|
|
293
|
-
this.selectedSheetIndex = -1;
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Check if sheet has tab actions
|
|
297
|
-
*/
|
|
298
|
-
hasTabActions(sheet) {
|
|
299
|
-
return !!(sheet.tabActions && sheet.tabActions.length > 0);
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Handle tab action click
|
|
303
|
-
*/
|
|
304
|
-
onTabActionClick(action, event) {
|
|
305
|
-
event.stopPropagation();
|
|
306
|
-
if (!this.selectedSheet)
|
|
307
|
-
return;
|
|
308
|
-
this.sheetTabAction.emit({
|
|
309
|
-
action,
|
|
310
|
-
sheetId: this.selectedSheet.id
|
|
311
|
-
});
|
|
312
|
-
this.closeTabActions();
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Toggle workbook actions dropdown
|
|
316
|
-
*/
|
|
317
|
-
toggleWorkbookActions(event) {
|
|
318
|
-
event.stopPropagation();
|
|
319
|
-
this.workbookActionsOpen = !this.workbookActionsOpen;
|
|
320
|
-
if (this.workbookActionsOpen) {
|
|
321
|
-
const target = event.currentTarget;
|
|
322
|
-
const rect = target.getBoundingClientRect();
|
|
323
|
-
this.workbookActionsPosition = {
|
|
324
|
-
top: `${rect.bottom + 4}px`,
|
|
325
|
-
right: `${window.innerWidth - rect.right}px`
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Close workbook actions dropdown
|
|
331
|
-
*/
|
|
332
|
-
closeWorkbookActions() {
|
|
333
|
-
this.workbookActionsOpen = false;
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Update visible workbook actions
|
|
337
|
-
*/
|
|
338
|
-
updateVisibleWorkbookActions() {
|
|
339
|
-
if (!this.config.workbookActions) {
|
|
340
|
-
this.visibleWorkbookActions = [];
|
|
341
|
-
this.toolbarWorkbookActions = [];
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
const visibleActions = this.config.workbookActions.filter(action => {
|
|
345
|
-
if (typeof action.hidden === 'function') {
|
|
346
|
-
return !action.hidden();
|
|
347
|
-
}
|
|
348
|
-
return !action.hidden;
|
|
349
|
-
});
|
|
350
|
-
// Separate toolbar actions from dropdown actions
|
|
351
|
-
this.toolbarWorkbookActions = visibleActions.filter(action => action.showInToolbar === true);
|
|
352
|
-
this.visibleWorkbookActions = visibleActions.filter(action => action.showInToolbar !== true);
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Check if workbook action is disabled
|
|
356
|
-
*/
|
|
357
|
-
isActionDisabled(action) {
|
|
358
|
-
if (typeof action.disabled === 'function') {
|
|
359
|
-
return action.disabled();
|
|
360
|
-
}
|
|
361
|
-
return action.disabled || false;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Handle workbook action click
|
|
365
|
-
*/
|
|
366
|
-
onWorkbookActionClick(action, event) {
|
|
367
|
-
event.stopPropagation();
|
|
368
|
-
if (this.isActionDisabled(action)) {
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
this.workbookAction.emit({
|
|
372
|
-
action,
|
|
373
|
-
workbookId: this.config.id
|
|
374
|
-
});
|
|
375
|
-
this.closeWorkbookActions();
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Toggle fullscreen mode
|
|
379
|
-
*/
|
|
380
|
-
toggleFullscreen() {
|
|
381
|
-
const current = this.isFullscreen$.value;
|
|
382
|
-
const newValue = !current;
|
|
383
|
-
this.isFullscreen$.next(newValue);
|
|
384
|
-
this.fullscreenToggle.emit(newValue);
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Handle cell change from table - update internal data and pass through to parent
|
|
388
|
-
*/
|
|
389
|
-
onCellChange(event) {
|
|
390
|
-
this.selectedSheet = this.sheets[this.activeSheetIndex];
|
|
391
|
-
// Update the internal sheetsData with the new cell value
|
|
392
|
-
if (this.selectedSheet && event.rowData && event.columnKey !== undefined) {
|
|
393
|
-
const currentData = this.sheetsData.getValue();
|
|
394
|
-
const sheetData = currentData.get(this.selectedSheet.id);
|
|
395
|
-
if (sheetData && event.rowIndex !== undefined) {
|
|
396
|
-
// Update the specific row's column value
|
|
397
|
-
const updatedRow = { ...sheetData[event.rowIndex] };
|
|
398
|
-
updatedRow[event.columnKey] = event.newValue;
|
|
399
|
-
// Create a new array with the updated row
|
|
400
|
-
const updatedSheetData = [...sheetData];
|
|
401
|
-
updatedSheetData[event.rowIndex] = updatedRow;
|
|
402
|
-
// Create a new Map with the updated sheet data
|
|
403
|
-
const updatedData = new Map(currentData);
|
|
404
|
-
updatedData.set(this.selectedSheet.id, updatedSheetData);
|
|
405
|
-
// Update the BehaviorSubject with new reference
|
|
406
|
-
this.sheetsData.next(updatedData);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
// Emit to parent
|
|
410
|
-
this.cellChange.emit(event);
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Handle cell save from table - update internal data and pass through to parent
|
|
414
|
-
*/
|
|
415
|
-
onCellSave(event) {
|
|
416
|
-
// Update the internal sheetsData with the new cell value
|
|
417
|
-
if (this.selectedSheet && event.rowData && event.columnKey !== undefined) {
|
|
418
|
-
const currentData = this.sheetsData.getValue();
|
|
419
|
-
const sheetData = currentData.get(this.selectedSheet.id);
|
|
420
|
-
if (sheetData && event.rowIndex !== undefined) {
|
|
421
|
-
// Update the specific row's column value
|
|
422
|
-
const updatedRow = { ...sheetData[event.rowIndex] };
|
|
423
|
-
updatedRow[event.columnKey] = event.newValue;
|
|
424
|
-
// Create a new array with the updated row
|
|
425
|
-
const updatedSheetData = [...sheetData];
|
|
426
|
-
updatedSheetData[event.rowIndex] = updatedRow;
|
|
427
|
-
// Create a new Map with the updated sheet data
|
|
428
|
-
const updatedData = new Map(currentData);
|
|
429
|
-
updatedData.set(this.selectedSheet.id, updatedSheetData);
|
|
430
|
-
// Update the BehaviorSubject with new reference
|
|
431
|
-
this.sheetsData.next(updatedData);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
// Emit to parent
|
|
435
|
-
this.cellSave.emit(event);
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Handle table state change - pass through to parent
|
|
439
|
-
*/
|
|
440
|
-
onTableStateChange(event) {
|
|
441
|
-
this.tableStateChange.emit(event);
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Handle request to add a new row - emitted when navigating past last row
|
|
445
|
-
*/
|
|
446
|
-
onRequestAddRow(event) {
|
|
447
|
-
const activeSheet = this.sheets[this.activeSheetIndex];
|
|
448
|
-
if (activeSheet) {
|
|
449
|
-
this.requestAddRow.emit({
|
|
450
|
-
sheetId: activeSheet.id,
|
|
451
|
-
focusColumn: event.focusColumn
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Component cleanup
|
|
457
|
-
*/
|
|
458
|
-
ngOnDestroy() {
|
|
459
|
-
this.destroy$.next();
|
|
460
|
-
this.destroy$.complete();
|
|
461
|
-
// Clear autosave data on destroy
|
|
462
|
-
if (this.autosaveEnabled) {
|
|
463
|
-
this.autosaveService.clear(this.config.id);
|
|
464
|
-
}
|
|
465
|
-
// Remove beforeunload handler
|
|
466
|
-
if (this.beforeUnloadHandler) {
|
|
467
|
-
window.removeEventListener('beforeunload', this.beforeUnloadHandler);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Initialize autosave subscription
|
|
472
|
-
*/
|
|
473
|
-
initializeAutosave() {
|
|
474
|
-
const changeEvents$ = merge(this.cellChange, this.cellSave, this.tableStateChange, this.sheetTabAction);
|
|
475
|
-
const autosave$ = this.autosaveStrategy === 'lazy'
|
|
476
|
-
? changeEvents$.pipe(tap(() => this.autosaveService.setDirty(this.config.id, true)), debounceTime(2000), distinctUntilChanged())
|
|
477
|
-
: changeEvents$.pipe(tap(() => this.autosaveService.setDirty(this.config.id, true)), debounceTime(100));
|
|
478
|
-
autosave$.pipe(takeUntil(this.destroy$)).subscribe(() => this.performAutosave());
|
|
479
|
-
}
|
|
480
|
-
/**
|
|
481
|
-
* Perform autosave operation
|
|
482
|
-
*/
|
|
483
|
-
performAutosave() {
|
|
484
|
-
this.isSaving = true;
|
|
485
|
-
const autosaveData = {
|
|
486
|
-
workbookConfig: this.config,
|
|
487
|
-
workbookState: this.activeState.getSnapshot(),
|
|
488
|
-
sheetsData: new Map(this.sheetsData.getValue()),
|
|
489
|
-
timestamp: new Date()
|
|
490
|
-
};
|
|
491
|
-
this.autosaveService.save(this.config.id, autosaveData);
|
|
492
|
-
this.lastSaveTime = new Date();
|
|
493
|
-
this.isSaving = false;
|
|
494
|
-
this.autosaveService.setDirty(this.config.id, false);
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Setup auto-restore from autosave
|
|
498
|
-
*/
|
|
499
|
-
setupAutoRestore() {
|
|
500
|
-
const autosaved = this.autosaveService.get(this.config.id);
|
|
501
|
-
if (autosaved) {
|
|
502
|
-
// Restore config
|
|
503
|
-
this.config = autosaved.workbookConfig;
|
|
504
|
-
// Restore sheets data
|
|
505
|
-
this.sheetsData.next(autosaved.sheetsData);
|
|
506
|
-
// Note: Workbook state restoration is handled internally
|
|
507
|
-
// If external state management is used, parent component should handle it
|
|
508
|
-
this.lastSaveTime = autosaved.timestamp;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Setup beforeunload warning for unsaved changes
|
|
513
|
-
*/
|
|
514
|
-
setupBeforeUnloadWarning() {
|
|
515
|
-
this.beforeUnloadHandler = (event) => {
|
|
516
|
-
if (this.autosaveService.isDirty(this.config.id)) {
|
|
517
|
-
event.preventDefault();
|
|
518
|
-
event.returnValue = 'You have unsaved changes. Are you sure you want to leave?';
|
|
519
|
-
return event.returnValue;
|
|
520
|
-
}
|
|
521
|
-
return undefined;
|
|
522
|
-
};
|
|
523
|
-
window.addEventListener('beforeunload', this.beforeUnloadHandler);
|
|
524
|
-
}
|
|
525
|
-
// ===================================================
|
|
526
|
-
// Public API Methods
|
|
527
|
-
// ===================================================
|
|
528
|
-
/**
|
|
529
|
-
* Scroll to a specific row in the current table
|
|
530
|
-
* @param rowIndex - The index of the row to scroll to
|
|
531
|
-
* @param focusFirstCell - Whether to focus the first editable cell (default: false)
|
|
532
|
-
*/
|
|
533
|
-
scrollToRow(rowIndex, focusFirstCell = false) {
|
|
534
|
-
if (this.tableComponent) {
|
|
535
|
-
this.tableComponent.scrollToRowAndFocus(rowIndex, focusFirstCell);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Scroll to the last row in the current table
|
|
540
|
-
* @param focusFirstCell - Whether to focus the first editable cell (default: true)
|
|
541
|
-
*/
|
|
542
|
-
scrollToLastRow(focusFirstCell = true) {
|
|
543
|
-
if (this.tableComponent) {
|
|
544
|
-
this.tableComponent.scrollToLastRow(focusFirstCell);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
StWorkbookComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StWorkbookComponent, deps: [{ token: i1.AutosaveService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
549
|
-
StWorkbookComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StWorkbookComponent, selector: "st-workbook", inputs: { config: "config", sheetsData: "sheetsData", state: "state" }, outputs: { sheetChanged: "sheetChanged", addSheet: "addSheet", sheetTabAction: "sheetTabAction", workbookAction: "workbookAction", cellChange: "cellChange", cellSave: "cellSave", tableStateChange: "tableStateChange", fullscreenToggle: "fullscreenToggle", requestAddRow: "requestAddRow" }, viewQueries: [{ propertyName: "tableComponent", first: true, predicate: StTableComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen$ | async\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex\">\n \n <!-- Sheet Tabs (one per sheet) -->\n <nile-tab *ngFor=\"let sheet of sheets; let i = index\"\n slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\"\n *ngIf=\"hasTabActions(sheet)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n <div class=\"autosave-indicator\" *ngIf=\"autosaveEnabled\">\n <nile-icon \n *ngIf=\"!isSaving && lastSaveTime\" \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime | date:'HH:mm:ss')\">\n </nile-icon>\n <nile-icon \n *ngIf=\"isSaving\" \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n </div>\n\n <!-- Toolbar Workbook Actions (shown as individual buttons) -->\n <button *ngFor=\"let action of toolbarWorkbookActions\"\n class=\"toolbar-action-button\"\n [class.disabled]=\"isActionDisabled(action)\"\n [title]=\"action.label\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" [name]=\"action.icon\"></nile-icon>\n <span *ngIf=\"!action.icon\">{{ action.label }}</span>\n </button>\n\n <!-- Workbook Actions Dropdown -->\n <button class=\"workbook-actions-button\"\n *ngIf=\"visibleWorkbookActions.length > 0\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n \n <!-- Add Sheet Button -->\n <button class=\"add-sheet-button\"\n *ngIf=\"canAddSheet\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n \n <!-- Fullscreen Button -->\n <button class=\"fullscreen-button\"\n *ngIf=\"config.display?.allowFullscreen !== false\"\n (click)=\"toggleFullscreen()\"\n [title]=\"(isFullscreen$ | async) ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"(isFullscreen$ | async) ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using ngFor with trackBy to force complete reinitialization when tableComponentKey changes -->\n <ng-container *ngFor=\"let key of [tableComponentKey]; trackBy: trackByKey\">\n <st-table *ngIf=\"currentTableConfig && currentTableState\"\n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n </ng-container>\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n<div class=\"tab-actions-dropdown\" \n *ngIf=\"tabActionsOpen\"\n [ngStyle]=\"tabActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of selectedSheet?.tabActions\" \n (click)=\"onTabActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Workbook Actions Dropdown -->\n<div class=\"workbook-actions-dropdown\"\n *ngIf=\"workbookActionsOpen\"\n [ngStyle]=\"workbookActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of visibleWorkbookActions\"\n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Fullscreen Backdrop -->\n<div class=\"fullscreen-backdrop\" \n *ngIf=\"isFullscreen$ | async\"\n (click)=\"toggleFullscreen()\">\n</div>\n\n", styles: ["@import\"@aquera/nile/lib/styles/variables.css\";:host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:white;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.workbook-toolbar-tab button.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab.active .sheet-name{font-weight:600}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"], components: [{ type: i2.StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], pipes: { "async": i3.AsyncPipe, "date": i3.DatePipe } });
|
|
550
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StWorkbookComponent, decorators: [{
|
|
551
|
-
type: Component,
|
|
552
|
-
args: [{ selector: 'st-workbook', template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen$ | async\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex\">\n \n <!-- Sheet Tabs (one per sheet) -->\n <nile-tab *ngFor=\"let sheet of sheets; let i = index\"\n slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\"\n *ngIf=\"hasTabActions(sheet)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n <div class=\"autosave-indicator\" *ngIf=\"autosaveEnabled\">\n <nile-icon \n *ngIf=\"!isSaving && lastSaveTime\" \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime | date:'HH:mm:ss')\">\n </nile-icon>\n <nile-icon \n *ngIf=\"isSaving\" \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n </div>\n\n <!-- Toolbar Workbook Actions (shown as individual buttons) -->\n <button *ngFor=\"let action of toolbarWorkbookActions\"\n class=\"toolbar-action-button\"\n [class.disabled]=\"isActionDisabled(action)\"\n [title]=\"action.label\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" [name]=\"action.icon\"></nile-icon>\n <span *ngIf=\"!action.icon\">{{ action.label }}</span>\n </button>\n\n <!-- Workbook Actions Dropdown -->\n <button class=\"workbook-actions-button\"\n *ngIf=\"visibleWorkbookActions.length > 0\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n \n <!-- Add Sheet Button -->\n <button class=\"add-sheet-button\"\n *ngIf=\"canAddSheet\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n \n <!-- Fullscreen Button -->\n <button class=\"fullscreen-button\"\n *ngIf=\"config.display?.allowFullscreen !== false\"\n (click)=\"toggleFullscreen()\"\n [title]=\"(isFullscreen$ | async) ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"(isFullscreen$ | async) ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using ngFor with trackBy to force complete reinitialization when tableComponentKey changes -->\n <ng-container *ngFor=\"let key of [tableComponentKey]; trackBy: trackByKey\">\n <st-table *ngIf=\"currentTableConfig && currentTableState\"\n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n </ng-container>\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n<div class=\"tab-actions-dropdown\" \n *ngIf=\"tabActionsOpen\"\n [ngStyle]=\"tabActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of selectedSheet?.tabActions\" \n (click)=\"onTabActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Workbook Actions Dropdown -->\n<div class=\"workbook-actions-dropdown\"\n *ngIf=\"workbookActionsOpen\"\n [ngStyle]=\"workbookActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of visibleWorkbookActions\"\n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Fullscreen Backdrop -->\n<div class=\"fullscreen-backdrop\" \n *ngIf=\"isFullscreen$ | async\"\n (click)=\"toggleFullscreen()\">\n</div>\n\n", styles: ["@import\"@aquera/nile/lib/styles/variables.css\";:host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:white;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.workbook-toolbar-tab button.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab.active .sheet-name{font-weight:600}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"] }]
|
|
553
|
-
}], ctorParameters: function () { return [{ type: i1.AutosaveService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { config: [{
|
|
554
|
-
type: Input
|
|
555
|
-
}], sheetsData: [{
|
|
556
|
-
type: Input
|
|
557
|
-
}], state: [{
|
|
558
|
-
type: Input
|
|
559
|
-
}], sheetChanged: [{
|
|
560
|
-
type: Output
|
|
561
|
-
}], addSheet: [{
|
|
562
|
-
type: Output
|
|
563
|
-
}], sheetTabAction: [{
|
|
564
|
-
type: Output
|
|
565
|
-
}], workbookAction: [{
|
|
566
|
-
type: Output
|
|
567
|
-
}], cellChange: [{
|
|
568
|
-
type: Output
|
|
569
|
-
}], cellSave: [{
|
|
570
|
-
type: Output
|
|
571
|
-
}], tableStateChange: [{
|
|
572
|
-
type: Output
|
|
573
|
-
}], fullscreenToggle: [{
|
|
574
|
-
type: Output
|
|
575
|
-
}], requestAddRow: [{
|
|
576
|
-
type: Output
|
|
577
|
-
}], tableComponent: [{
|
|
578
|
-
type: ViewChild,
|
|
579
|
-
args: [StTableComponent]
|
|
580
|
-
}] } });
|
|
581
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Qtd29ya2Jvb2suY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtdGFibGUvc3JjL2xpYi9yZW5kZXJlci9jb21wb25lbnRzL3N0LXdvcmtib29rL3N0LXdvcmtib29rLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvcmVuZGVyZXIvY29tcG9uZW50cy9zdC13b3JrYm9vay9zdC13b3JrYm9vay5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQU1aLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkQsT0FBTyxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHcEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRWxFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUk1RCxPQUFPLEVBQW9CLHVCQUF1QixFQUFFLE1BQU0sMkNBQTJDLENBQUM7Ozs7O0FBUXRHLE1BQU0sT0FBTyxtQkFBbUI7SUFpSzlCLFlBQ1UsZUFBZ0MsRUFDaEMsR0FBc0I7UUFEdEIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBN0poQzs7V0FFRztRQUNNLGVBQVUsR0FBd0MsSUFBSSxlQUFlLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBTzFGOztX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bUJBQW1CLDRjQWlFbkIsZ0JBQWdCLHFFQ2hHN0IsMmhMQTJJQTsyRkQ1R2EsbUJBQW1CO2tCQUwvQixTQUFTOytCQUNFLGFBQWE7c0lBUWQsTUFBTTtzQkFBZCxLQUFLO2dCQUtHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBS0csS0FBSztzQkFBYixLQUFLO2dCQUtJLFlBQVk7c0JBQXJCLE1BQU07Z0JBS0csUUFBUTtzQkFBakIsTUFBTTtnQkFLRyxjQUFjO3NCQUF2QixNQUFNO2dCQUtHLGNBQWM7c0JBQXZCLE1BQU07Z0JBS0csVUFBVTtzQkFBbkIsTUFBTTtnQkFLRyxRQUFRO3NCQUFqQixNQUFNO2dCQUtHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFLRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBTUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFLc0IsY0FBYztzQkFBMUMsU0FBUzt1QkFBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgT25Jbml0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIFZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdFRhYmxlQ29tcG9uZW50IH0gZnJvbSAnLi4vc3QtdGFibGUvc3QtdGFibGUuY29tcG9uZW50JztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCwgbWVyZ2UgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgV29ya2Jvb2tDb25maWcsIFdvcmtib29rU2hlZXRDb25maWcgfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvd29ya2Jvb2stY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBXb3JrYm9va0FjdGlvbiwgV29ya2Jvb2tBY3Rpb25FdmVudCwgU2hlZXRUYWJBY3Rpb25FdmVudCB9IGZyb20gJy4uLy4uLy4uL21vZGVscy93b3JrYm9vay1hY3Rpb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IFdvcmtib29rU3RhdGUgfSBmcm9tICcuLi8uLi9tb2RlbHMvd29ya2Jvb2stc3RhdGUuY2xhc3MnO1xuaW1wb3J0IHsgV29ya2Jvb2tTdGF0ZVNuYXBzaG90IH0gZnJvbSAnLi4vLi4vbW9kZWxzL3dvcmtib29rLXN0YXRlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBUYWJsZVN0YXRlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3RhYmxlLXN0YXRlLmNsYXNzJztcbmltcG9ydCB7IFRhYmxlQ29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL3RhYmxlLWNvbmZpZy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQ2VsbENoYW5nZUV2ZW50IH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2NlbGwtdHlwZXMnO1xuaW1wb3J0IHsgVGFibGVTdGF0ZUNoYW5nZUV2ZW50IH0gZnJvbSAnLi4vLi4vbW9kZWxzL3RhYmxlLXR5cGVzJztcbmltcG9ydCB7IEF1dG9zYXZlU3RyYXRlZ3ksIERFRkFVTFRfQVVUT1NBVkVfQ09ORklHIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2F1dG9zYXZlLWNvbmZpZy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQXV0b3NhdmVTZXJ2aWNlLCBBdXRvc2F2ZURhdGEgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9hdXRvc2F2ZS5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3Qtd29ya2Jvb2snLFxuICB0ZW1wbGF0ZVVybDogJy4vc3Qtd29ya2Jvb2suY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zdC13b3JrYm9vay5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBTdFdvcmtib29rQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBXb3JrYm9vayBjb25maWd1cmF0aW9uXG4gICAqL1xuICBASW5wdXQoKSBjb25maWchOiBXb3JrYm9va0NvbmZpZztcblxuICAvKipcbiAgICogTWFwIG9mIHNoZWV0IElEIHRvIGRhdGEgYXJyYXlcbiAgICovXG4gIEBJbnB1dCgpIHNoZWV0c0RhdGE6IEJlaGF2aW9yU3ViamVjdDxNYXA8c3RyaW5nLCBhbnlbXT4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChuZXcgTWFwKCkpO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBleHRlcm5hbCBzdGF0ZSBtYW5hZ2VtZW50XG4gICAqL1xuICBASW5wdXQoKSBzdGF0ZT86IFdvcmtib29rU3RhdGU7XG5cbiAgLyoqXG4gICAqIEVtaXR0ZWQgd2hlbiBhY3RpdmUgc2hlZXQgY2hhbmdlc1xuICAgKi9cbiAgQE91dHB1dCgpIHNoZWV0Q2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gIC8qKlxuICAgKiBFbWl0dGVkIHdoZW4gYWRkIHNoZWV0IGJ1dHRvbiBpcyBjbGlja2VkXG4gICAqL1xuICBAT3V0cHV0KCkgYWRkU2hlZXQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqXG4gICAqIEVtaXR0ZWQgd2hlbiBhIHNoZWV0IHRhYiBhY3Rpb24gaXMgY2xpY2tlZFxuICAgKi9cbiAgQE91dHB1dCgpIHNoZWV0VGFiQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxTaGVldFRhYkFjdGlvbkV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBFbWl0dGVkIHdoZW4gYSB3b3JrYm9vayBhY3Rpb24gaXMgY2xpY2tlZFxuICAgKi9cbiAgQE91dHB1dCgpIHdvcmtib29rQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxXb3JrYm9va0FjdGlvbkV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBFbWl0dGVkIHdoZW4gY2VsbCB2YWx1ZSBjaGFuZ2VzXG4gICAqL1xuICBAT3V0cHV0KCkgY2VsbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2VsbENoYW5nZUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBFbWl0dGVkIHdoZW4gY2VsbCBpcyBzYXZlZFxuICAgKi9cbiAgQE91dHB1dCgpIGNlbGxTYXZlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgLyoqXG4gICAqIEVtaXR0ZWQgd2hlbiB0YWJsZSBzdGF0ZSBjaGFuZ2VzXG4gICAqL1xuICBAT3V0cHV0KCkgdGFibGVTdGF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8VGFibGVTdGF0ZUNoYW5nZUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBFbWl0dGVkIHdoZW4gZnVsbHNjcmVlbiBpcyB0b2dnbGVkXG4gICAqL1xuICBAT3V0cHV0KCkgZnVsbHNjcmVlblRvZ2dsZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKipcbiAgICogRW1pdHRlZCB3aGVuIHVzZXIgbmF2aWdhdGVzIHBhc3QgbGFzdCByb3cgKGFycm93IGRvd24gYXQgYm90dG9tKVxuICAgKiBPbmx5IGVtaXR0ZWQgaWYgYWRkUm93T25OYXZpZ2F0ZVBhc3RFbmQgaXMgZW5hYmxlZCBpbiB0YWJsZUNvbmZpZ1xuICAgKi9cbiAgQE91dHB1dCgpIHJlcXVlc3RBZGRSb3cgPSBuZXcgRXZlbnRFbWl0dGVyPHsgc2hlZXRJZDogc3RyaW5nOyBmb2N1c0NvbHVtbj86IG51bWJlciB9PigpO1xuXG4gIC8qKlxuICAgKiBSZWZlcmVuY2UgdG8gdGhlIHN0LXRhYmxlIGNvbXBvbmVudCBmb3IgcHJvZ3JhbW1hdGljIGNvbnRyb2xcbiAgICovXG4gIEBWaWV3Q2hpbGQoU3RUYWJsZUNvbXBvbmVudCkgdGFibGVDb21wb25lbnQ/OiBTdFRhYmxlQ29tcG9uZW50O1xuXG4gIC8qKlxuICAgKiBBcnJheSBvZiBzaGVldHNcbiAgICovXG4gIHNoZWV0czogV29ya2Jvb2tTaGVldENvbmZpZ1tdID0gW107XG5cbiAgLyoqXG4gICAqIEFjdGl2ZSBzaGVldCBpbmRleFxuICAgKi9cbiAgYWN0aXZlU2hlZXRJbmRleCA9IDA7XG5cbiAgLyoqXG4gICAqIEN1cnJlbnQgdGFibGUgY29uZmlnIChmb3IgYWN0aXZlIHNoZWV0KVxuICAgKi9cbiAgY3VycmVudFRhYmxlQ29uZmlnOiBUYWJsZUNvbmZpZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBDdXJyZW50IHRhYmxlIGRhdGEgKGZvciBhY3RpdmUgc2hlZXQpIC0gdXNpbmcgQmVoYXZpb3JTdWJqZWN0IGZvciByZWFjdGl2ZSB1cGRhdGVzXG4gICAqL1xuICBjdXJyZW50VGFibGVEYXRhJDogQmVoYXZpb3JTdWJqZWN0PGFueVtdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55W10+KFtdKTtcblxuICAvKipcbiAgICogQ3VycmVudCB0YWJsZSBzdGF0ZSAoZm9yIGFjdGl2ZSBzaGVldClcbiAgICovXG4gIGN1cnJlbnRUYWJsZVN0YXRlOiBUYWJsZVN0YXRlIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFVuaXF1ZSBrZXkgZm9yIHRhYmxlIGNvbXBvbmVudCAoY2hhbmdlcyBvbiBzaGVldCBzd2l0Y2ggdG8gZm9yY2UgcmVpbml0aWFsaXphdGlvbilcbiAgICovXG4gIHRhYmxlQ29tcG9uZW50S2V5OiBzdHJpbmcgPSAnJztcblxuICAvKipcbiAgICogSW50ZXJuYWwgc3RhdGUgaW5zdGFuY2VcbiAgICovXG4gIGludGVybmFsU3RhdGU/OiBXb3JrYm9va1N0YXRlO1xuXG4gIC8qKlxuICAgKiBGdWxsc2NyZWVuIHN0YXRlIG9ic2VydmFibGVcbiAgICovXG4gIGlzRnVsbHNjcmVlbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcblxuICAvKipcbiAgICogVGFiIGFjdGlvbnMgZHJvcGRvd24gc3RhdGVcbiAgICovXG4gIHRhYkFjdGlvbnNPcGVuID0gZmFsc2U7XG4gIHNlbGVjdGVkU2hlZXQ6IFdvcmtib29rU2hlZXRDb25maWcgfCBudWxsID0gbnVsbDtcbiAgc2VsZWN0ZWRTaGVldEluZGV4OiBudW1iZXIgPSAtMTtcbiAgdGFiQWN0aW9uc1Bvc2l0aW9uOiBhbnkgPSB7fTtcblxuICAvKipcbiAgICogV29ya2Jvb2sgYWN0aW9ucyBkcm9wZG93biBzdGF0ZVxuICAgKi9cbiAgd29ya2Jvb2tBY3Rpb25zT3BlbiA9IGZhbHNlO1xuICB3b3JrYm9va0FjdGlvbnNQb3NpdGlvbjogYW55ID0ge307XG5cbiAgLyoqXG4gICAqIFZpc2libGUgd29ya2Jvb2sgYWN0aW9ucyBmb3IgZHJvcGRvd24gKGZpbHRlcmVkIGJ5IGhpZGRlbiBhbmQgc2hvd0luVG9vbGJhcilcbiAgICovXG4gIHZpc2libGVXb3JrYm9va0FjdGlvbnM6IFdvcmtib29rQWN0aW9uW10gPSBbXTtcblxuICAvKipcbiAgICogV29ya2Jvb2sgYWN0aW9ucyB0byBzaG93IGRpcmVjdGx5IGluIHRvb2xiYXJcbiAgICovXG4gIHRvb2xiYXJXb3JrYm9va0FjdGlvbnM6IFdvcmtib29rQWN0aW9uW10gPSBbXTtcblxuICAvKipcbiAgICogRGVzdHJveSBzdWJqZWN0IGZvciBjbGVhbnVwXG4gICAqL1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvKipcbiAgICogQXV0b3NhdmUgZW5hYmxlZCBmbGFnXG4gICAqL1xuICBhdXRvc2F2ZUVuYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogQXV0b3NhdmUgc3RyYXRlZ3lcbiAgICovXG4gIHByaXZhdGUgYXV0b3NhdmVTdHJhdGVneTogQXV0b3NhdmVTdHJhdGVneSA9ICdsYXp5JztcblxuICAvKipcbiAgICogTGFzdCBzYXZlIHRpbWVzdGFtcFxuICAgKi9cbiAgbGFzdFNhdmVUaW1lOiBEYXRlIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFNhdmluZyBpbmRpY2F0b3JcbiAgICovXG4gIGlzU2F2aW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEJlZm9yZXVubG9hZCBoYW5kbGVyIHJlZmVyZW5jZVxuICAgKi9cbiAgcHJpdmF0ZSBiZWZvcmVVbmxvYWRIYW5kbGVyOiAoKGV2ZW50OiBCZWZvcmVVbmxvYWRFdmVudCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGF1dG9zYXZlU2VydmljZTogQXV0b3NhdmVTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbml0aWFsaXplQ29tcG9uZW50KCk7XG5cbiAgICAvLyBTdWJzY3JpYmUgdG8gc2hlZXRzRGF0YSBjaGFuZ2VzIHRvIHVwZGF0ZSBjdXJyZW50VGFibGVEYXRhJCByZWFjdGl2ZWx5XG4gICAgdGhpcy5zaGVldHNEYXRhLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICApLnN1YnNjcmliZSgoZGF0YU1hcCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRTaGVldCAmJiBkYXRhTWFwKSB7XG4gICAgICAgIGNvbnN0IG5ld0RhdGEgPSBkYXRhTWFwLmdldCh0aGlzLnNlbGVjdGVkU2hlZXQuaWQpO1xuICAgICAgICBpZiAobmV3RGF0YSkge1xuICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgQmVoYXZpb3JTdWJqZWN0IC0gc3QtdGFibGUgd2lsbCByZWFjdCBhdXRvbWF0aWNhbGx5XG4gICAgICAgICAgdGhpcy5jdXJyZW50VGFibGVEYXRhJC5uZXh0KFsuLi5uZXdEYXRhXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEluaXRpYWxpemUgYXV0b3NhdmUgaWYgZW5hYmxlZFxuICAgIGNvbnN0IGF1dG9zYXZlQ29uZmlnID0gdGhpcy5jb25maWcuYXV0b3NhdmUgfHwgREVGQVVMVF9BVVRPU0FWRV9DT05GSUc7XG4gICAgdGhpcy5hdXRvc2F2ZUVuYWJsZWQgPSBhdXRvc2F2ZUNvbmZpZy5lbmFibGVkO1xuICAgIHRoaXMuYXV0b3NhdmVTdHJhdGVneSA9IGF1dG9zYXZlQ29uZmlnLnN0cmF0ZWd5O1xuXG4gICAgaWYgKHRoaXMuYXV0b3NhdmVFbmFibGVkKSB7XG4gICAgICB0aGlzLnNldHVwQXV0b1Jlc3RvcmUoKTtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUF1dG9zYXZlKCk7XG4gICAgICB0aGlzLnNldHVwQmVmb3JlVW5sb2FkV2FybmluZygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snY29uZmlnJ10pIHtcbiAgICAgIGNvbnN0IGlzRmlyc3RDaGFuZ2UgPSBjaGFuZ2VzWydjb25maWcnXS5maXJzdENoYW5nZTtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUNvbXBvbmVudChpc0ZpcnN0Q2hhbmdlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBjb21wb25lbnQgc3RhdGVcbiAgICogQHBhcmFtIGlzRmlyc3RJbml0IFdoZXRoZXIgdGhpcyBpcyB0aGUgZmlyc3QgaW5pdGlhbGl6YXRpb24gKHRydWUpIG9yIGEgY29uZmlnIHVwZGF0ZSAoZmFsc2UpXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVDb21wb25lbnQoaXNGaXJzdEluaXQ6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZykgcmV0dXJuO1xuXG4gICAgY29uc3QgcHJldmlvdXNTaGVldENvdW50ID0gdGhpcy5zaGVldHMubGVuZ3RoO1xuICAgIHRoaXMuc2hlZXRzID0gWy4uLnRoaXMuY29uZmlnLnNoZWV0c107XG4gICAgY29uc3QgbmV3U2hlZXRDb3VudCA9IHRoaXMuc2hlZXRzLmxlbmd0aDtcbiAgICBcbiAgICAvLyBPbmx5IHJlc2V0IGFjdGl2ZVNoZWV0SW5kZXggb24gZmlyc3QgaW5pdCwgcHJlc2VydmUgaXQgb24gY29uZmlnIHVwZGF0ZXNcbiAgICBpZiAoaXNGaXJzdEluaXQpIHtcbiAgICAgIHRoaXMuYWN0aXZlU2hlZXRJbmRleCA9IHRoaXMuY29uZmlnLmluaXRpYWxBY3RpdmVTaGVldEluZGV4IHx8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENoZWNrIGlmIGEgbmV3IHNoZWV0IHdhcyBhZGRlZCAtIHN3aXRjaCB0byB0aGUgbmV3IHNoZWV0XG4gICAgICBpZiAobmV3U2hlZXRDb3VudCA+IHByZXZpb3VzU2hlZXRDb3VudCkge1xuICAgICAgICB0aGlzLmFjdGl2ZVNoZWV0SW5kZXggPSBuZXdTaGVldENvdW50IC0gMTsgLy8gU3dpdGNoIHRvIHRoZSBuZXdseSBhZGRlZCBzaGVldFxuICAgICAgfVxuICAgICAgLy8gRW5zdXJlIGFjdGl2ZVNoZWV0SW5kZXggaXMgc3RpbGwgdmFsaWQgYWZ0ZXIgY29uZmlnIGNoYW5nZSAoZS5nLiwgc2hlZXQgZGVsZXRlZClcbiAgICAgIGVsc2UgaWYgKHRoaXMuYWN0aXZlU2hlZXRJbmRleCA+PSB0aGlzLnNoZWV0cy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hY3RpdmVTaGVldEluZGV4ID0gTWF0aC5tYXgoMCwgdGhpcy5zaGVldHMubGVuZ3RoIC0gMSk7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIGlmICghdGhpcy5zdGF0ZSkge1xuICAgICAgdGhpcy5pbnRlcm5hbFN0YXRlID0gbmV3IFdvcmtib29rU3RhdGUoe1xuICAgICAgICBpZDogdGhpcy5jb25maWcuaWQsXG4gICAgICAgIG5hbWU6IHRoaXMuY29uZmlnLm5hbWUsXG4gICAgICAgIGluaXRpYWxBY3RpdmVTaGVldEluZGV4OiB0aGlzLmFjdGl2ZVNoZWV0SW5kZXhcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlVmlzaWJsZVdvcmtib29rQWN0aW9ucygpO1xuICAgIHRoaXMudXBkYXRlQWN0aXZlU2hlZXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWN0aXZlIHN0YXRlIChleHRlcm5hbCBvciBpbnRlcm5hbClcbiAgICovXG4gIGdldCBhY3RpdmVTdGF0ZSgpOiBXb3JrYm9va1N0YXRlIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZSB8fCB0aGlzLmludGVybmFsU3RhdGUhO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSB0YWIgY2hhbmdlIGV2ZW50IGZyb20gbmlsZS10YWItZ3JvdXBcbiAgICovXG4gIG9uVGFiQ2hhbmdlKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdJbmRleCA9IGV2ZW50LmRldGFpbD8uaW5kZXggPz8gZXZlbnQ7XG4gICAgXG4gICAgLy8gSWdub3JlIGlmIGNsaWNrZWQgb24gdG9vbGJhciB0YWJcbiAgICBpZiAobmV3SW5kZXggPj0gdGhpcy5zaGVldHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5hY3RpdmVTaGVldEluZGV4ID0gbmV3SW5kZXg7XG4gICAgdGhpcy5hY3RpdmVTdGF0ZS5zZXRBY3RpdmVTaGVldEluZGV4KG5ld0luZGV4KTtcbiAgICB0aGlzLnVwZGF0ZUFjdGl2ZVNoZWV0KCk7XG4gICAgdGhpcy5zaGVldENoYW5nZWQuZW1pdCh0aGlzLmFjdGl2ZVNoZWV0SW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhY3RpdmUgc2hlZXQgZGF0YSAodHJpZ2dlcnMgdGFibGUgcmUtaW5pdGlhbGl6YXRpb24gd2l0aCBuZXcgY29uZmlnL3N0YXRlKVxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVBY3RpdmVTaGVldCgpOiB2b2lkIHtcbiAgICBjb25zdCBzaGVldCA9IHRoaXMuc2hlZXRzW3RoaXMuYWN0aXZlU2hlZXRJbmRleF07XG4gICAgaWYgKCFzaGVldCkgcmV0dXJuO1xuXG4gICAgLy8gVXBkYXRlIHNlbGVjdGVkIHNoZWV0IHJlZmVyZW5jZSBmb3IgZGF0YSBzdWJzY3JpcHRpb25zXG4gICAgdGhpcy5zZWxlY3RlZFNoZWV0ID0gc2hlZXQ7XG4gICAgdGhpcy5zZWxlY3RlZFNoZWV0SW5kZXggPSB0aGlzLmFjdGl2ZVNoZWV0SW5kZXg7XG5cbiAgICAvLyBHZXQgc2hlZXQgZGF0YVxuICAgIGNvbnN0IHNoZWV0RGF0YSA9IHRoaXMuc2hlZXRzRGF0YS5nZXRWYWx1ZSgpPy5nZXQoc2hlZXQuaWQpIHx8IFtdO1xuXG4gICAgLy8gQ3JlYXRlIGEgZnJlc2ggVGFibGVTdGF0ZSBmb3IgdGhpcyBzaGVldCAobGF6eSBpbml0aWFsaXphdGlvbilcbiAgICAvLyBUaGlzIGVuc3VyZXMgdGhlIHRhYmxlIHJlaW5pdGlhbGl6ZXMgd2l0aCBuZXcgY29uZmlnIGFuZCBzdGF0ZVxuICAgIGNvbnN0IHRhYmxlU3RhdGUgPSBuZXcgVGFibGVTdGF0ZShcbiAgICAgIHNoZWV0LnRhYmxlQ29uZmlnLmNvbHVtbnMsXG4gICAgICB7XG4gICAgICAgIGluaXRpYWxQYWdlOiBzaGVldC50YWJsZUNvbmZpZy5pbml0aWFsU3RhdGU/LnBhZ2UgfHwgMSxcbiAgICAgICAgcGFnZVNpemU6IHNoZWV0LnRhYmxlQ29uZmlnLnBhZ2luYXRpb24/LnBhZ2VTaXplIHx8IDI1XG4gICAgICB9XG4gICAgKTtcblxuICAgIC8vIFVwZGF0ZSBjdXJyZW50IHRhYmxlIHByb3BlcnRpZXMgKHRyaWdnZXJzIEFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvbilcbiAgICAvLyBUaGUgc3QtdGFibGUgY29tcG9uZW50IHdpbGwgZGV0ZWN0IHRoZXNlIGNoYW5nZXMgYW5kIHJlaW5pdGlhbGl6ZVxuICAgIHRoaXMuY3VycmVudFRhYmxlQ29uZmlnID0geyAuLi5zaGVldC50YWJsZUNvbmZpZyB9O1xuICAgIHRoaXMuY3VycmVudFRhYmxlRGF0YSQubmV4dChzaGVldERhdGEpO1xuICAgIHRoaXMuY3VycmVudFRhYmxlU3RhdGUgPSB0YWJsZVN0YXRlO1xuICAgIFxuICAgIC8vIFVwZGF0ZSBjb21wb25lbnQga2V5IHRvIGZvcmNlIERPTSByZS1jcmVhdGlvbiAodHJ1ZSBsYXp5IGxvYWRpbmcpXG4gICAgLy8gVGhpcyBlbnN1cmVzIGNvbXBsZXRlIHJlaW5pdGlhbGl6YXRpb24gb2Ygc3QtdGFibGUgY29tcG9uZW50XG4gICAgdGhpcy50YWJsZUNvbXBvbmVudEtleSA9IGAke3NoZWV0LmlkfS0ke0RhdGUubm93KCl9YDtcblxuICAgIC8vIFN0b3JlIHRoZSB0YWJsZSBzdGF0ZSBpbiB3b3JrYm9vayBzdGF0ZSBmb3IgcGVyc2lzdGVuY2VcbiAgICB0aGlzLmFjdGl2ZVN0YXRlLnNldFNoZWV0VGFibGVTdGF0ZShzaGVldC5pZCwgdGFibGVTdGF0ZSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgbmV3IHNoZWV0XG4gICAqL1xuICBvbkFkZFNoZWV0KCk6IHZvaWQge1xuICAgIHRoaXMuYWRkU2hlZXQuZW1pdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrQnkgZnVuY3Rpb24gdG8gZm9yY2UgY29tcG9uZW50IHJlY3JlYXRpb24gd2hlbiBrZXkgY2hhbmdlc1xuICAgKi9cbiAgdHJhY2tCeUtleShpbmRleDogbnVtYmVyLCBrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGtleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjYW4gYWRkIG1vcmUgc2hlZXRzXG4gICAqL1xuICBnZXQgY2FuQWRkU2hlZXQoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuY29uZmlnLmRpc3BsYXk/LmFsbG93QWRkU2hlZXQgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZy5kaXNwbGF5Py5tYXhTaGVldHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnNoZWV0cy5sZW5ndGggPCB0aGlzLmNvbmZpZy5kaXNwbGF5Lm1heFNoZWV0cztcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogR2V0IG1pbmltdW0gc2hlZXRzIHJlcXVpcmVkXG4gICAqL1xuICBnZXQgbWluU2hlZXRzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRpc3BsYXk/Lm1pblNoZWV0cyB8fCAxO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW4gdGFiIGFjdGlvbnMgZHJvcGRvd25cbiAgICovXG4gIG9wZW5UYWJBY3Rpb25zKGV2ZW50OiBNb3VzZUV2ZW50LCBzaGVldDogV29ya2Jvb2tTaGVldENvbmZpZywgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIFxuICAgIHRoaXMuc2VsZWN0ZWRTaGVldCA9IHNoZWV0O1xuICAgIHRoaXMuc2VsZWN0ZWRTaGVldEluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy50YWJBY3Rpb25zT3BlbiA9IHRydWU7XG5cbiAgICAvLyBQb3NpdGlvbiBkcm9wZG93blxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgY29uc3QgcmVjdCA9IHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB0aGlzLnRhYkFjdGlvbnNQb3NpdGlvbiA9IHtcbiAgICAgIHRvcDogYCR7cmVjdC5ib3R0b20gKyA0fXB4YCxcbiAgICAgIGxlZnQ6IGAke3JlY3QubGVmdH1weGBcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIHRhYiBhY3Rpb25zIGRyb3Bkb3duXG4gICAqL1xuICBjbG9zZVRhYkFjdGlvbnMoKTogdm9pZCB7XG4gICAgdGhpcy50YWJBY3Rpb25zT3BlbiA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0ZWRTaGVldCA9IG51bGw7XG4gICAgdGhpcy5zZWxlY3RlZFNoZWV0SW5kZXggPSAtMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBzaGVldCBoYXMgdGFiIGFjdGlvbnNcbiAgICovXG4gIGhhc1RhYkFjdGlvbnMoc2hlZXQ6IFdvcmtib29rU2hlZXRDb25maWcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEoc2hlZXQudGFiQWN0aW9ucyAmJiBzaGVldC50YWJBY3Rpb25zLmxlbmd0aCA+IDApO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSB0YWIgYWN0aW9uIGNsaWNrXG4gICAqL1xuICBvblRhYkFjdGlvbkNsaWNrKGFjdGlvbjogYW55LCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGlmICghdGhpcy5zZWxlY3RlZFNoZWV0KSByZXR1cm47XG5cbiAgICB0aGlzLnNoZWV0VGFiQWN0aW9uLmVtaXQoe1xuICAgICAgYWN0aW9uLFxuICAgICAgc2hlZXRJZDogdGhpcy5zZWxlY3RlZFNoZWV0LmlkXG4gICAgfSk7XG5cbiAgICB0aGlzLmNsb3NlVGFiQWN0aW9ucygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSB3b3JrYm9vayBhY3Rpb25zIGRyb3Bkb3duXG4gICAqL1xuICB0b2dnbGVXb3JrYm9va0FjdGlvbnMoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBcbiAgICB0aGlzLndvcmtib29rQWN0aW9uc09wZW4gPSAhdGhpcy53b3JrYm9va0FjdGlvbnNPcGVuO1xuXG4gICAgaWYgKHRoaXMud29ya2Jvb2tBY3Rpb25zT3Blbikge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQuY3VycmVudFRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGNvbnN0IHJlY3QgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICB0aGlzLndvcmtib29rQWN0aW9uc1Bvc2l0aW9uID0ge1xuICAgICAgICB0b3A6IGAke3JlY3QuYm90dG9tICsgNH1weGAsXG4gICAgICAgIHJpZ2h0OiBgJHt3aW5kb3cuaW5uZXJXaWR0aCAtIHJlY3QucmlnaHR9cHhgXG4gICAgICB9O1xuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIHdvcmtib29rIGFjdGlvbnMgZHJvcGRvd25cbiAgICovXG4gIGNsb3NlV29ya2Jvb2tBY3Rpb25zKCk6IHZvaWQge1xuICAgIHRoaXMud29ya2Jvb2tBY3Rpb25zT3BlbiA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB2aXNpYmxlIHdvcmtib29rIGFjdGlvbnNcbiAgICovXG4gIHByaXZhdGUgdXBkYXRlVmlzaWJsZVdvcmtib29rQWN0aW9ucygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLndvcmtib29rQWN0aW9ucykge1xuICAgICAgdGhpcy52aXNpYmxlV29ya2Jvb2tBY3Rpb25zID0gW107XG4gICAgICB0aGlzLnRvb2xiYXJXb3JrYm9va0FjdGlvbnMgPSBbXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2aXNpYmxlQWN0aW9ucyA9IHRoaXMuY29uZmlnLndvcmtib29rQWN0aW9ucy5maWx0ZXIoYWN0aW9uID0+IHtcbiAgICAgIGlmICh0eXBlb2YgYWN0aW9uLmhpZGRlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gIWFjdGlvbi5oaWRkZW4oKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAhYWN0aW9uLmhpZGRlbjtcbiAgICB9KTtcblxuICAgIC8vIFNlcGFyYXRlIHRvb2xiYXIgYWN0aW9ucyBmcm9tIGRyb3Bkb3duIGFjdGlvbnNcbiAgICB0aGlzLnRvb2xiYXJXb3JrYm9va0FjdGlvbnMgPSB2aXNpYmxlQWN0aW9ucy5maWx0ZXIoYWN0aW9uID0+IGFjdGlvbi5zaG93SW5Ub29sYmFyID09PSB0cnVlKTtcbiAgICB0aGlzLnZpc2libGVXb3JrYm9va0FjdGlvbnMgPSB2aXNpYmxlQWN0aW9ucy5maWx0ZXIoYWN0aW9uID0+IGFjdGlvbi5zaG93SW5Ub29sYmFyICE9PSB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB3b3JrYm9vayBhY3Rpb24gaXMgZGlzYWJsZWRcbiAgICovXG4gIGlzQWN0aW9uRGlzYWJsZWQoYWN0aW9uOiBXb3JrYm9va0FjdGlvbik6IGJvb2xlYW4ge1xuICAgIGlmICh0eXBlb2YgYWN0aW9uLmRpc2FibGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gYWN0aW9uLmRpc2FibGVkKCk7XG4gICAgfVxuICAgIHJldHVybiBhY3Rpb24uZGlzYWJsZWQgfHwgZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHdvcmtib29rIGFjdGlvbiBjbGlja1xuICAgKi9cbiAgb25Xb3JrYm9va0FjdGlvbkNsaWNrKGFjdGlvbjogV29ya2Jvb2tBY3Rpb24sIGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgaWYgKHRoaXMuaXNBY3Rpb25EaXNhYmxlZChhY3Rpb24pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy53b3JrYm9va0FjdGlvbi5lbWl0KHtcbiAgICAgIGFjdGlvbixcbiAgICAgIHdvcmtib29rSWQ6IHRoaXMuY29uZmlnLmlkXG4gICAgfSk7XG5cbiAgICB0aGlzLmNsb3NlV29ya2Jvb2tBY3Rpb25zKCk7XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlIGZ1bGxzY3JlZW4gbW9kZVxuICAgKi9cbiAgdG9nZ2xlRnVsbHNjcmVlbigpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5pc0Z1bGxzY3JlZW4kLnZhbHVlO1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gIWN1cnJlbnQ7XG4gICAgXG4gICAgdGhpcy5pc0Z1bGxzY3JlZW4kLm5leHQobmV3VmFsdWUpO1xuICAgIHRoaXMuZnVsbHNjcmVlblRvZ2dsZS5lbWl0KG5ld1ZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgY2VsbCBjaGFuZ2UgZnJvbSB0YWJsZSAtIHVwZGF0ZSBpbnRlcm5hbCBkYXRhIGFuZCBwYXNzIHRocm91Z2ggdG8gcGFyZW50XG4gICAqL1xuICBvbkNlbGxDaGFuZ2UoZXZlbnQ6IENlbGxDaGFuZ2VFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRTaGVldCA9IHRoaXMuc2hlZXRzW3RoaXMuYWN0aXZlU2hlZXRJbmRleF07XG4gICAgXG4gICAgLy8gVXBkYXRlIHRoZSBpbnRlcm5hbCBzaGVldHNEYXRhIHdpdGggdGhlIG5ldyBjZWxsIHZhbHVlXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRTaGVldCAmJiBldmVudC5yb3dEYXRhICYmIGV2ZW50LmNvbHVtbktleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBjdXJyZW50RGF0YSA9IHRoaXMuc2hlZXRzRGF0YS5nZXRWYWx1ZSgpO1xuICAgICAgY29uc3Qgc2hlZXREYXRhID0gY3VycmVudERhdGEuZ2V0KHRoaXMuc2VsZWN0ZWRTaGVldC5pZCk7XG4gICAgICBcbiAgICAgIGlmIChzaGVldERhdGEgJiYgZXZlbnQucm93SW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIHNwZWNpZmljIHJvdydzIGNvbHVtbiB2YWx1ZVxuICAgICAgICBjb25zdCB1cGRhdGVkUm93ID0geyAuLi5zaGVldERhdGFbZXZlbnQucm93SW5kZXhdIH07XG4gICAgICAgIHVwZGF0ZWRSb3dbZXZlbnQuY29sdW1uS2V5XSA9IGV2ZW50Lm5ld1ZhbHVlO1xuICAgICAgICBcbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGFycmF5IHdpdGggdGhlIHVwZGF0ZWQgcm93XG4gICAgICAgIGNvbnN0IHVwZGF0ZWRTaGVldERhdGEgPSBbLi4uc2hlZXREYXRhXTtcbiAgICAgICAgdXBkYXRlZFNoZWV0RGF0YVtldmVudC5yb3dJbmRleF0gPSB1cGRhdGVkUm93O1xuICAgICAgICBcbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IE1hcCB3aXRoIHRoZSB1cGRhdGVkIHNoZWV0IGRhdGFcbiAgICAgICAgY29uc3QgdXBkYXRlZERhdGEgPSBuZXcgTWFwKGN1cnJlbnREYXRhKTtcbiAgICAgICAgdXBkYXRlZERhdGEuc2V0KHRoaXMuc2VsZWN0ZWRTaGVldC5pZCwgdXBkYXRlZFNoZWV0RGF0YSk7XG4gICAgICAgIFxuICAgICAgICAvLyBVcGRhdGUgdGhlIEJlaGF2aW9yU3ViamVjdCB3aXRoIG5ldyByZWZlcmVuY2VcbiAgICAgICAgdGhpcy5zaGVldHNEYXRhLm5leHQodXBkYXRlZERhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBFbWl0IHRvIHBhcmVudFxuICAgIHRoaXMuY2VsbENoYW5nZS5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgY2VsbCBzYXZlIGZyb20gdGFibGUgLSB1cGRhdGUgaW50ZXJuYWwgZGF0YSBhbmQgcGFzcyB0aHJvdWdoIHRvIHBhcmVudFxuICAgKi9cbiAgb25DZWxsU2F2ZShldmVudDogYW55KTogdm9pZCB7XG4gICAgLy8gVXBkYXRlIHRoZSBpbnRlcm5hbCBzaGVldHNEYXRhIHdpdGggdGhlIG5ldyBjZWxsIHZhbHVlXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRTaGVldCAmJiBldmVudC5yb3dEYXRhICYmIGV2ZW50LmNvbHVtbktleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBjdXJyZW50RGF0YSA9IHRoaXMuc2hlZXRzRGF0YS5nZXRWYWx1ZSgpO1xuICAgICAgY29uc3Qgc2hlZXREYXRhID0gY3VycmVudERhdGEuZ2V0KHRoaXMuc2VsZWN0ZWRTaGVldC5pZCk7XG4gICAgICBcbiAgICAgIGlmIChzaGVldERhdGEgJiYgZXZlbnQucm93SW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIHNwZWNpZmljIHJvdydzIGNvbHVtbiB2YWx1ZVxuICAgICAgICBjb25zdCB1cGRhdGVkUm93ID0geyAuLi5zaGVldERhdGFbZXZlbnQucm93SW5kZXhdIH07XG4gICAgICAgIHVwZGF0ZWRSb3dbZXZlbnQuY29sdW1uS2V5XSA9IGV2ZW50Lm5ld1ZhbHVlO1xuICAgICAgICBcbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGFycmF5IHdpdGggdGhlIHVwZGF0ZWQgcm93XG4gICAgICAgIGNvbnN0IHVwZGF0ZWRTaGVldERhdGEgPSBbLi4uc2hlZXREYXRhXTtcbiAgICAgICAgdXBkYXRlZFNoZWV0RGF0YVtldmVudC5yb3dJbmRleF0gPSB1cGRhdGVkUm93O1xuICAgICAgICBcbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IE1hcCB3aXRoIHRoZSB1cGRhdGVkIHNoZWV0IGRhdGFcbiAgICAgICAgY29uc3QgdXBkYXRlZERhdGEgPSBuZXcgTWFwKGN1cnJlbnREYXRhKTtcbiAgICAgICAgdXBkYXRlZERhdGEuc2V0KHRoaXMuc2VsZWN0ZWRTaGVldC5pZCwgdXBkYXRlZFNoZWV0RGF0YSk7XG4gICAgICAgIFxuICAgICAgICAvLyBVcGRhdGUgdGhlIEJlaGF2aW9yU3ViamVjdCB3aXRoIG5ldyByZWZlcmVuY2VcbiAgICAgICAgdGhpcy5zaGVldHNEYXRhLm5leHQodXBkYXRlZERhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBFbWl0IHRvIHBhcmVudFxuICAgIHRoaXMuY2VsbFNhdmUuZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRhYmxlIHN0YXRlIGNoYW5nZSAtIHBhc3MgdGhyb3VnaCB0byBwYXJlbnRcbiAgICovXG4gIG9uVGFibGVTdGF0ZUNoYW5nZShldmVudDogVGFibGVTdGF0ZUNoYW5nZUV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy50YWJsZVN0YXRlQ2hhbmdlLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSByZXF1ZXN0IHRvIGFkZCBhIG5ldyByb3cgLSBlbWl0dGVkIHdoZW4gbmF2aWdhdGluZyBwYXN0IGxhc3Qgcm93XG4gICAqL1xuICBvblJlcXVlc3RBZGRSb3coZXZlbnQ6IHsgZm9jdXNDb2x1bW4/OiBudW1iZXIgfSk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZVNoZWV0ID0gdGhpcy5zaGVldHNbdGhpcy5hY3RpdmVTaGVldEluZGV4XTtcbiAgICBpZiAoYWN0aXZlU2hlZXQpIHtcbiAgICAgIHRoaXMucmVxdWVzdEFkZFJvdy5lbWl0KHtcbiAgICAgICAgc2hlZXRJZDogYWN0aXZlU2hlZXQuaWQsXG4gICAgICAgIGZvY3VzQ29sdW1uOiBldmVudC5mb2N1c0NvbHVtblxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXBvbmVudCBjbGVhbnVwXG4gICAqL1xuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG5cbiAgICAvLyBDbGVhciBhdXRvc2F2ZSBkYXRhIG9uIGRlc3Ryb3lcbiAgICBpZiAodGhpcy5hdXRvc2F2ZUVuYWJsZWQpIHtcbiAgICAgIHRoaXMuYXV0b3NhdmVTZXJ2aWNlLmNsZWFyKHRoaXMuY29uZmlnLmlkKTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgYmVmb3JldW5sb2FkIGhhbmRsZXJcbiAgICBpZiAodGhpcy5iZWZvcmVVbmxvYWRIYW5kbGVyKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdGhpcy5iZWZvcmVVbmxvYWRIYW5kbGVyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhdXRvc2F2ZSBzdWJzY3JpcHRpb25cbiAgICovXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUF1dG9zYXZlKCk6IHZvaWQge1xuICAgIGNvbnN0IGNoYW5nZUV2ZW50cyQgPSBtZXJnZShcbiAgICAgIHRoaXMuY2VsbENoYW5nZSxcbiAgICAgIHRoaXMuY2VsbFNhdmUsXG4gICAgICB0aGlzLnRhYmxlU3RhdGVDaGFuZ2UsXG4gICAgICB0aGlzLnNoZWV0VGFiQWN0aW9uXG4gICAgKTtcblxuICAgIGNvbnN0IGF1dG9zYXZlJCA9IHRoaXMuYXV0b3NhdmVTdHJhdGVneSA9PT0gJ2xhenknXG4gICAgICA/IGNoYW5nZUV2ZW50cyQucGlwZShcbiAgICAgICAgICB0YXAoKCkgPT4gdGhpcy5hdXRvc2F2ZVNlcnZpY2Uuc2V0RGlydHkodGhpcy5jb25maWcuaWQsIHRydWUpKSxcbiAgICAgICAgICBkZWJvdW5jZVRpbWUoMjAwMCksXG4gICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKVxuICAgICAgICApXG4gICAgICA6IGNoYW5nZUV2ZW50cyQucGlwZShcbiAgICAgICAgICB0YXAoKCkgPT4gdGhpcy5hdXRvc2F2ZVNlcnZpY2Uuc2V0RGlydHkodGhpcy5jb25maWcuaWQsIHRydWUpKSxcbiAgICAgICAgICBkZWJvdW5jZVRpbWUoMTAwKVxuICAgICAgICApO1xuXG4gICAgYXV0b3NhdmUkLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICApLnN1YnNjcmliZSgoKSA9PiB0aGlzLnBlcmZvcm1BdXRvc2F2ZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGF1dG9zYXZlIG9wZXJhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBwZXJmb3JtQXV0b3NhdmUoKTogdm9pZCB7XG4gICAgdGhpcy5pc1NhdmluZyA9IHRydWU7XG5cbiAgICBjb25zdCBhdXRvc2F2ZURhdGE6IEF1dG9zYXZlRGF0YSA9IHtcbiAgICAgIHdvcmtib29rQ29uZmlnOiB0aGlzLmNvbmZpZyxcbiAgICAgIHdvcmtib29rU3RhdGU6IHRoaXMuYWN0aXZlU3RhdGUuZ2V0U25hcHNob3QoKSxcbiAgICAgIHNoZWV0c0RhdGE6IG5ldyBNYXAodGhpcy5zaGVldHNEYXRhLmdldFZhbHVlKCkpLFxuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpXG4gICAgfTtcblxuICAgIHRoaXMuYXV0b3NhdmVTZXJ2aWNlLnNhdmUodGhpcy5jb25maWcuaWQsIGF1dG9zYXZlRGF0YSk7XG4gICAgdGhpcy5sYXN0U2F2ZVRpbWUgPSBuZXcgRGF0ZSgpO1xuICAgIHRoaXMuaXNTYXZpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmF1dG9zYXZlU2VydmljZS5zZXREaXJ0eSh0aGlzLmNvbmZpZy5pZCwgZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHVwIGF1dG8tcmVzdG9yZSBmcm9tIGF1dG9zYXZlXG4gICAqL1xuICBwcml2YXRlIHNldHVwQXV0b1Jlc3RvcmUoKTogdm9pZCB7XG4gICAgY29uc3QgYXV0b3NhdmVkID0gdGhpcy5hdXRvc2F2ZVNlcnZpY2UuZ2V0KHRoaXMuY29uZmlnLmlkKTtcblxuICAgIGlmIChhdXRvc2F2ZWQpIHtcbiAgICAgIC8vIFJlc3RvcmUgY29uZmlnXG4gICAgICB0aGlzLmNvbmZpZyA9IGF1dG9zYXZlZC53b3JrYm9va0NvbmZpZztcblxuICAgICAgLy8gUmVzdG9yZSBzaGVldHMgZGF0YVxuICAgICAgdGhpcy5zaGVldHNEYXRhLm5leHQoYXV0b3NhdmVkLnNoZWV0c0RhdGEpO1xuXG4gICAgICAvLyBOb3RlOiBXb3JrYm9vayBzdGF0ZSByZXN0b3JhdGlvbiBpcyBoYW5kbGVkIGludGVybmFsbHlcbiAgICAgIC8vIElmIGV4dGVybmFsIHN0YXRlIG1hbmFnZW1lbnQgaXMgdXNlZCwgcGFyZW50IGNvbXBvbmVudCBzaG91bGQgaGFuZGxlIGl0XG5cbiAgICAgIHRoaXMubGFzdFNhdmVUaW1lID0gYXV0b3NhdmVkLnRpbWVzdGFtcDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0dXAgYmVmb3JldW5sb2FkIHdhcm5pbmcgZm9yIHVuc2F2ZWQgY2hhbmdlc1xuICAgKi9cbiAgcHJpdmF0ZSBzZXR1cEJlZm9yZVVubG9hZFdhcm5pbmcoKTogdm9pZCB7XG4gICAgdGhpcy5iZWZvcmVVbmxvYWRIYW5kbGVyID0gKGV2ZW50OiBCZWZvcmVVbmxvYWRFdmVudCkgPT4ge1xuICAgICAgaWYgKHRoaXMuYXV0b3NhdmVTZXJ2aWNlLmlzRGlydHkodGhpcy5jb25maWcuaWQpKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2ZW50LnJldHVyblZhbHVlID0gJ1lvdSBoYXZlIHVuc2F2ZWQgY2hhbmdlcy4gQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGxlYXZlPyc7XG4gICAgICAgIHJldHVybiBldmVudC5yZXR1cm5WYWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCB0aGlzLmJlZm9yZVVubG9hZEhhbmRsZXIpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFB1YmxpYyBBUEkgTWV0aG9kc1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogU2Nyb2xsIHRvIGEgc3BlY2lmaWMgcm93IGluIHRoZSBjdXJyZW50IHRhYmxlXG4gICAqIEBwYXJhbSByb3dJbmRleCAtIFRoZSBpbmRleCBvZiB0aGUgcm93IHRvIHNjcm9sbCB0b1xuICAgKiBAcGFyYW0gZm9jdXNGaXJzdENlbGwgLSBXaGV0aGVyIHRvIGZvY3VzIHRoZSBmaXJzdCBlZGl0YWJsZSBjZWxsIChkZWZhdWx0OiBmYWxzZSlcbiAgICovXG4gIHB1YmxpYyBzY3JvbGxUb1Jvdyhyb3dJbmRleDogbnVtYmVyLCBmb2N1c0ZpcnN0Q2VsbDogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudGFibGVDb21wb25lbnQpIHtcbiAgICAgIHRoaXMudGFibGVDb21wb25lbnQuc2Nyb2xsVG9Sb3dBbmRGb2N1cyhyb3dJbmRleCwgZm9jdXNGaXJzdENlbGwpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTY3JvbGwgdG8gdGhlIGxhc3Qgcm93IGluIHRoZSBjdXJyZW50IHRhYmxlXG4gICAqIEBwYXJhbSBmb2N1c0ZpcnN0Q2VsbCAtIFdoZXRoZXIgdG8gZm9jdXMgdGhlIGZpcnN0IGVkaXRhYmxlIGNlbGwgKGRlZmF1bHQ6IHRydWUpXG4gICAqL1xuICBwdWJsaWMgc2Nyb2xsVG9MYXN0Um93KGZvY3VzRmlyc3RDZWxsOiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRhYmxlQ29tcG9uZW50KSB7XG4gICAgICB0aGlzLnRhYmxlQ29tcG9uZW50LnNjcm9sbFRvTGFzdFJvdyhmb2N1c0ZpcnN0Q2VsbCk7XG4gICAgfVxuICB9XG59XG5cbiIsIjxkaXYgY2xhc3M9XCJ3b3JrYm9vay1jb250YWluZXJcIiBbY2xhc3MuZnVsbHNjcmVlbl09XCJpc0Z1bGxzY3JlZW4kIHwgYXN5bmNcIj5cbiAgPG5pbGUtdGFiLWdyb3VwIFthY3RpdmVJbmRleF09XCJhY3RpdmVTaGVldEluZGV4XCI+XG4gICAgXG4gICAgPCEtLSBTaGVldCBUYWJzIChvbmUgcGVyIHNoZWV0KSAtLT5cbiAgICA8bmlsZS10YWIgKm5nRm9yPVwibGV0IHNoZWV0IG9mIHNoZWV0czsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgICAgIHNsb3Q9XCJuYXZcIiBcbiAgICAgICAgICAgICAgcGFuZWw9XCJzaGFyZWQtcGFuZWxcIlxuICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImkgPT09IGFjdGl2ZVNoZWV0SW5kZXhcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwib25UYWJDaGFuZ2UoaSlcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzaGVldC10YWItY29udGVudFwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNoZWV0LW5hbWVcIj57eyBzaGVldC5uYW1lIH19PC9zcGFuPlxuICAgICAgICBcbiAgICAgICAgPCEtLSBUYWIgYWN0aW9ucyBkcm9wZG93biBidXR0b24gLS0+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJ0YWItYWN0aW9ucy1idXR0b25cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvcGVuVGFiQWN0aW9ucygkZXZlbnQsIHNoZWV0LCBpKVwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJoYXNUYWJBY3Rpb25zKHNoZWV0KVwiPlxuICAgICAgICAgIDxuaWxlLWljb24gbmFtZT1cImFycm93ZG93blwiIHNpemU9XCIxNFwiPjwvbmlsZS1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmlsZS10YWI+XG4gICAgXG4gICAgPCEtLSBUb29sYmFyIFRhYiAoZm9yIHdvcmtib29rIGNvbnRyb2xzKSAtLT5cbiAgICA8bmlsZS10YWIgc2xvdD1cIm5hdlwiIFxuICAgICAgICAgICAgICBwYW5lbD1cInNoYXJlZC1wYW5lbFwiXG4gICAgICAgICAgICAgIGNsYXNzPVwid29ya2Jvb2stdG9vbGJhci10YWJcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwidHJ1ZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIndvcmtib29rLXRvb2xiYXItY29udGVudFwiPlxuICAgICAgICA8IS0tIEF1dG9zYXZlIEluZGljYXRvciAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImF1dG9zYXZlLWluZGljYXRvclwiICpuZ0lmPVwiYXV0b3NhdmVFbmFibGVkXCI+XG4gICAgICAgICAgPG5pbGUtaWNvbiBcbiAgICAgICAgICAgICpuZ0lmPVwiIWlzU2F2aW5nICYmIGxhc3RTYXZlVGltZVwiIFxuICAgICAgICAgICAgbmFtZT1cInNhdmVcIiBcbiAgICAgICAgICAgIHNpemU9XCIxNFwiXG4gICAgICAgICAgICBbdGl0bGVdPVwiJ1NhdmVkIGF0ICcgKyAobGFzdFNhdmVUaW1lIHwgZGF0ZTonSEg6bW06c3MnKVwiPlxuICAgICAgICAgIDwvbmlsZS1pY29uPlxuICAgICAgICAgIDxuaWxlLWljb24gXG4gICAgICAgICAgICAqbmdJZj1cImlzU2F2aW5nXCIgXG4gICAgICAgICAgICBuYW1lPVwibG9hZGVyXCIgXG4gICAgICAgICAgICBzaXplPVwiMTRcIlxuICAgICAgICAgICAgdGl0bGU9XCJTYXZpbmcuLi5cIj5cbiAgICAgICAgICA8L25pbGUtaWNvbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBUb29sYmFyIFdvcmtib29rIEFjdGlvbnMgKHNob3duIGFzIGluZGl2aWR1YWwgYnV0dG9ucykgLS0+XG4gICAgICAgIDxidXR0b24gKm5nRm9yPVwibGV0IGFjdGlvbiBvZiB0b29sYmFyV29ya2Jvb2tBY3Rpb25zXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRvb2xiYXItYWN0aW9uLWJ1dHRvblwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cImlzQWN0aW9uRGlzYWJsZWQoYWN0aW9uKVwiXG4gICAgICAgICAgICAgICAgW3RpdGxlXT1cImFjdGlvbi5sYWJlbFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uV29ya2Jvb2tBY3Rpb25DbGljayhhY3Rpb24sICRldmVudClcIj5cbiAgICAgICAgICA8bmlsZS1pY29uICpuZ0lmPVwiYWN0aW9uLmljb25cIiBbbmFtZV09XCJhY3Rpb24uaWNvblwiPjwvbmlsZS1pY29uPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIWFjdGlvbi5pY29uXCI+e3sgYWN0aW9uLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICA8IS0tIFdvcmtib29rIEFjdGlvbnMgRHJvcGRvd24gLS0+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJ3b3JrYm9vay1hY3Rpb25zLWJ1dHRvblwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJ2aXNpYmxlV29ya2Jvb2tBY3Rpb25zLmxlbmd0aCA+IDBcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVXb3JrYm9va0FjdGlvbnMoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJXb3JrYm9vayBBY3Rpb25zXCI+XG4gICAgICAgICAgPG5pbGUtaWNvbiBuYW1lPVwic2V0dGluZ3NcIj48L25pbGUtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIFxuICAgICAgICA8IS0tIEFkZCBTaGVldCBCdXR0b24gLS0+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJhZGQtc2hlZXQtYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cImNhbkFkZFNoZWV0XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib25BZGRTaGVldCgpXCJcbiAgICAgICAgICAgICAgICB0aXRsZT1cIkFkZCBTaGVldFwiPlxuICAgICAgICAgIDxuaWxlLWljb24gbmFtZT1cInBsdXNcIj48L25pbGUtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIFxuICAgICAgICA8IS0tIEZ1bGxzY3JlZW4gQnV0dG9uIC0tPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZnVsbHNjcmVlbi1idXR0b25cIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiY29uZmlnLmRpc3BsYXk/LmFsbG93RnVsbHNjcmVlbiAhPT0gZmFsc2VcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVGdWxsc2NyZWVuKClcIlxuICAgICAgICAgICAgICAgIFt0aXRsZV09XCIoaXNGdWxsc2NyZWVuJCB8IGFzeW5jKSA/ICdFeGl0IEZ1bGxzY3JlZW4nIDogJ0Z1bGxzY3JlZW4nXCI+XG4gICAgICAgICAgPG5pbGUtaWNvbiBbbmFtZV09XCIoaXNGdWxsc2NyZWVuJCB8IGFzeW5jKSA/ICdjb2xsYXBzZScgOiAnZXhwYW5kLTA2J1wiPjwvbmlsZS1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmlsZS10YWI+XG4gICAgXG4gICAgPCEtLSBTaW5nbGUgU2hhcmVkIFRhYiBQYW5lbCAtLT5cbiAgICA8bmlsZS10YWItcGFuZWwgbmFtZT1cInNoYXJlZC1wYW5lbFwiPlxuICAgICAgPCEtLSBMYXp5IGxvYWRpbmcgc3RyYXRlZ3k6IHRhYmxlIGlzIGRlc3Ryb3llZCBhbmQgcmVjcmVhdGVkIHdpdGggbmV3IGNvbmZpZy9zdGF0ZSB3aGVuIHNoZWV0IGNoYW5nZXMgLS0+XG4gICAgICA8IS0tIFVzaW5nIG5nRm9yIHdpdGggdHJhY2tCeSB0byBmb3JjZSBjb21wbGV0ZSByZWluaXRpYWxpemF0aW9uIHdoZW4gdGFibGVDb21wb25lbnRLZXkgY2hhbmdlcyAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGtleSBvZiBbdGFibGVDb21wb25lbnRLZXldOyB0cmFja0J5OiB0cmFja0J5S2V5XCI+XG4gICAgICAgIDxzdC10YWJsZSAqbmdJZj1cImN1cnJlbnRUYWJsZUNvbmZpZyAmJiBjdXJyZW50VGFibGVTdGF0ZVwiXG4gICAgICAgICAgICAgICAgICBbYXR0ci5kYXRhLXNoZWV0LWtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgW3RhYmxlQ29uZmlnXT1cImN1cnJlbnRUYWJsZUNvbmZpZ1wiXG4gICAgICAgICAgICAgICAgICBbZGF0YSRdPVwiY3VycmVudFRhYmxlRGF0YSRcIlxuICAgICAgICAgICAgICAgICAgW3RhYmxlU3RhdGVdPVwiY3VycmVudFRhYmxlU3RhdGVcIlxuICAgICAgICAgICAgICAgICAgKGNlbGxDaGFuZ2UpPVwib25DZWxsQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKGNlbGxTYXZlKT1cIm9uQ2VsbFNhdmUoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoc3RhdGVDaGFuZ2UpPVwib25UYWJsZVN0YXRlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKHJlcXVlc3RBZGRSb3cpPVwib25SZXF1ZXN0QWRkUm93KCRldmVudClcIj5cbiAgICAgICAgPC9zdC10YWJsZT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmlsZS10YWItcGFuZWw+XG4gICAgXG4gIDwvbmlsZS10YWItZ3JvdXA+XG48L2Rpdj5cblxuPCEtLSBUYWIgQWN0aW9ucyBEcm9wZG93biAtLT5cbjxkaXYgY2xhc3M9XCJ0YWItYWN0aW9ucy1kcm9wZG93blwiIFxuICAgICAqbmdJZj1cInRhYkFjdGlvbnNPcGVuXCJcbiAgICAgW25nU3R5bGVdPVwidGFiQWN0aW9uc1Bvc2l0aW9uXCI+XG4gIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1iYWNrZHJvcFwiIChjbGljayk9XCJjbG9zZVRhYkFjdGlvbnMoKVwiPjwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tbWVudVwiPlxuICAgIDxuaWxlLW1lbnU+XG4gICAgICA8bmlsZS1tZW51LWl0ZW0gKm5nRm9yPVwibGV0IGFjdGlvbiBvZiBzZWxlY3RlZFNoZWV0Py50YWJBY3Rpb25zXCIgXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uVGFiQWN0aW9uQ2xpY2soYWN0aW9uLCAkZXZlbnQpXCI+XG4gICAgICAgIDxuaWxlLWljb24gKm5nSWY9XCJhY3Rpb24uaWNvblwiIHNsb3Q9XCJwcmVmaXhcIiBzaXplPVwiMTRcIiBbbmFtZV09XCJhY3Rpb24uaWNvblwiPjwvbmlsZS1pY29uPlxuICAgICAgICB7eyBhY3Rpb24ubGFiZWwgfX1cbiAgICAgIDwvbmlsZS1tZW51LWl0ZW0+XG4gICAgPC9uaWxlLW1lbnU+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjwhLS0gV29ya2Jvb2sgQWN0aW9ucyBEcm9wZG93biAtLT5cbjxkaXYgY2xhc3M9XCJ3b3JrYm9vay1hY3Rpb25zLWRyb3Bkb3duXCJcbiAgICAgKm5nSWY9XCJ3b3JrYm9va0FjdGlvbnNPcGVuXCJcbiAgICAgW25nU3R5bGVdPVwid29ya2Jvb2tBY3Rpb25zUG9zaXRpb25cIj5cbiAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWJhY2tkcm9wXCIgKGNsaWNrKT1cImNsb3NlV29ya2Jvb2tBY3Rpb25zKClcIj48L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLW1lbnVcIj5cbiAgICA8bmlsZS1tZW51PlxuICAgICAgPG5pbGUtbWVudS1pdGVtICpuZ0Zvcj1cImxldCBhY3Rpb24gb2YgdmlzaWJsZVdvcmtib29rQWN0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cImlzQWN0aW9uRGlzYWJsZWQoYWN0aW9uKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uV29ya2Jvb2tBY3Rpb25DbGljayhhY3Rpb24sICRldmVudClcIj5cbiAgICAgICAgPG5pbGUtaWNvbiAqbmdJZj1cImFjdGlvbi5pY29uXCIgc2xvdD1cInByZWZpeFwiIHNpemU9XCIxNFwiIFtuYW1lXT1cImFjdGlvbi5pY29uXCI+PC9uaWxlLWljb24+XG4gICAgICAgIHt7IGFjdGlvbi5sYWJlbCB9fVxuICAgICAgPC9uaWxlLW1lbnUtaXRlbT5cbiAgICA8L25pbGUtbWVudT5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPCEtLSBGdWxsc2NyZWVuIEJhY2tkcm9wIC0tPlxuPGRpdiBjbGFzcz1cImZ1bGxzY3JlZW4tYmFja2Ryb3BcIiBcbiAgICAgKm5nSWY9XCJpc0Z1bGxzY3JlZW4kIHwgYXN5bmNcIlxuICAgICAoY2xpY2spPVwidG9nZ2xlRnVsbHNjcmVlbigpXCI+XG48L2Rpdj5cblxuIl19
|