@sumaris-net/ngx-components 2.7.6 → 2.8.0-rc2
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/doc/changelog.md +8 -0
- package/esm2022/public_api.mjs +7 -3
- package/esm2022/src/app/admin/users/users.mjs +5 -3
- package/esm2022/src/app/core/account/new-token.modal.mjs +4 -4
- package/esm2022/src/app/core/auth/auth.form.mjs +2 -2
- package/esm2022/src/app/core/core.testing.module.mjs +2 -2
- package/esm2022/src/app/core/form/entity/editor.class.mjs +33 -487
- package/esm2022/src/app/core/form/entity/entity-editor-modal.class.mjs +14 -26
- package/esm2022/src/app/core/form/entity/entity-editor.class.mjs +5 -4
- package/esm2022/src/app/core/form/entity/tab-editor.class.mjs +194 -0
- package/esm2022/src/app/core/form/form-container.class.mjs +312 -0
- package/esm2022/src/app/core/form/form.class.mjs +27 -36
- package/esm2022/src/app/core/form/form.utils.mjs +1 -1
- package/esm2022/src/app/core/menu/testing/menu.testing.mjs +2 -2
- package/esm2022/src/app/core/services/model/settings.model.mjs +2 -1
- package/esm2022/src/app/core/settings/settings.page.mjs +5 -9
- package/esm2022/src/app/core/table/table.class.mjs +9 -5
- package/esm2022/src/app/core/table/table.module.mjs +16 -3
- package/esm2022/src/app/core/table/table.pipes.mjs +74 -0
- package/esm2022/src/app/core/table/testing/table.testing.mjs +39 -17
- package/esm2022/src/app/core/table/testing/table2.testing.mjs +40 -22
- package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +3 -3
- package/esm2022/src/app/shared/pipes/form.pipes.mjs +10 -10
- package/esm2022/src/app/shared/pipes/pipes.module.mjs +28 -3
- package/esm2022/src/app/shared/pipes/selection.pipes.mjs +176 -0
- package/esm2022/src/app/shared/validator/validators.mjs +3 -2
- package/fesm2022/sumaris-net.ngx-components.mjs +655 -321
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +6 -2
- package/src/app/core/account/new-token.modal.d.ts +1 -1
- package/src/app/core/form/entity/editor.class.d.ts +18 -177
- package/src/app/core/form/entity/entity-editor-modal.class.d.ts +9 -12
- package/src/app/core/form/entity/entity-editor.class.d.ts +10 -6
- package/src/app/core/form/entity/tab-editor.class.d.ts +70 -0
- package/src/app/core/form/form-container.class.d.ts +123 -0
- package/src/app/core/form/form.class.d.ts +11 -21
- package/src/app/core/form/form.utils.d.ts +38 -23
- package/src/app/core/menu/testing/menu.testing.d.ts +1 -1
- package/src/app/core/services/model/settings.model.d.ts +1 -0
- package/src/app/core/settings/settings.page.d.ts +1 -2
- package/src/app/core/table/table.module.d.ts +4 -3
- package/src/app/core/table/table.pipes.d.ts +28 -0
- package/src/app/core/table/testing/table.testing.d.ts +9 -5
- package/src/app/core/table/testing/table2.testing.d.ts +10 -5
- package/src/app/shared/pipes/form.pipes.d.ts +1 -1
- package/src/app/shared/pipes/pipes.module.d.ts +5 -4
- package/src/app/shared/pipes/selection.pipes.d.ts +62 -0
- package/src/app/shared/validator/validators.d.ts +1 -0
- package/src/assets/manifest.json +1 -1
- package/src/theme/_ngx-components.scss +4 -0
- package/src/theme/_ngx-components.table.scss +4 -14
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Directive, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core';
|
|
2
|
+
import { isNotNil, toNumber } from '../../../shared/functions';
|
|
3
|
+
import { AppEditor } from './editor.class';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/router";
|
|
6
|
+
import * as i2 from "@ionic/angular";
|
|
7
|
+
import * as i3 from "@ngx-translate/core";
|
|
8
|
+
export class AppTabEditorOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Number of tab. 1 by default
|
|
11
|
+
*/
|
|
12
|
+
tabCount;
|
|
13
|
+
/**
|
|
14
|
+
* '200ms' by default
|
|
15
|
+
*/
|
|
16
|
+
tabGroupAnimationDuration;
|
|
17
|
+
/**
|
|
18
|
+
* Should enable swipe between tab, on touch screen
|
|
19
|
+
*/
|
|
20
|
+
enableSwipe; // true by default
|
|
21
|
+
}
|
|
22
|
+
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
|
23
|
+
export class AppTabEditor extends AppEditor {
|
|
24
|
+
route;
|
|
25
|
+
router;
|
|
26
|
+
navController;
|
|
27
|
+
alertCtrl;
|
|
28
|
+
translate;
|
|
29
|
+
_selectedTabIndex = 0;
|
|
30
|
+
// Editor options
|
|
31
|
+
tabCount;
|
|
32
|
+
enableSwipe;
|
|
33
|
+
tabGroupAnimationDuration;
|
|
34
|
+
queryTabIndexParamName;
|
|
35
|
+
set selectedTabIndex(value) {
|
|
36
|
+
this.setSelectedTabIndex(value);
|
|
37
|
+
}
|
|
38
|
+
get selectedTabIndex() {
|
|
39
|
+
return this._selectedTabIndex;
|
|
40
|
+
}
|
|
41
|
+
selectedTabIndexChange = new EventEmitter();
|
|
42
|
+
tabGroup;
|
|
43
|
+
constructor(route, // Modal editor give 'null'
|
|
44
|
+
router, navController, alertCtrl, translate, options) {
|
|
45
|
+
super(route, router, navController, alertCtrl, translate);
|
|
46
|
+
this.route = route;
|
|
47
|
+
this.router = router;
|
|
48
|
+
this.navController = navController;
|
|
49
|
+
this.alertCtrl = alertCtrl;
|
|
50
|
+
this.translate = translate;
|
|
51
|
+
options = {
|
|
52
|
+
tabCount: 1,
|
|
53
|
+
enableSwipe: true,
|
|
54
|
+
tabGroupAnimationDuration: '200ms',
|
|
55
|
+
...options,
|
|
56
|
+
};
|
|
57
|
+
this.tabCount = options.tabCount;
|
|
58
|
+
this.enableSwipe = options.enableSwipe;
|
|
59
|
+
this.tabGroupAnimationDuration = options.tabGroupAnimationDuration;
|
|
60
|
+
this.queryTabIndexParamName = 'tab';
|
|
61
|
+
this._logPrefix = '[tab-editor] ';
|
|
62
|
+
}
|
|
63
|
+
ngOnInit() {
|
|
64
|
+
super.ngOnInit();
|
|
65
|
+
// Read the selected tab index, from path query params
|
|
66
|
+
if (this.tabGroup && this.route && this.queryTabIndexParamName) {
|
|
67
|
+
this.registerSubscription(this.route.queryParams.subscribe((queryParams) => {
|
|
68
|
+
this.queryParams = { ...queryParams };
|
|
69
|
+
// Parse tab param
|
|
70
|
+
if (this.tabCount > 1 && this.queryTabIndexParamName) {
|
|
71
|
+
const tabIndex = toNumber(queryParams[this.queryTabIndexParamName], 0);
|
|
72
|
+
this.queryParams[this.queryTabIndexParamName] = tabIndex !== 0 ? tabIndex : undefined;
|
|
73
|
+
if (this.selectedTabIndex !== tabIndex) {
|
|
74
|
+
this.selectedTabIndex = tabIndex;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Realign tab, after a delay because the tab can be disabled when component is created
|
|
78
|
+
setTimeout(() => this.tabGroup.realignInkBar(), 500);
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
ngOnDestroy() {
|
|
83
|
+
super.ngOnDestroy();
|
|
84
|
+
this.selectedTabIndexChange.complete();
|
|
85
|
+
}
|
|
86
|
+
setSelectedTabIndex(value, opts) {
|
|
87
|
+
// Fix value
|
|
88
|
+
if (value < 0) {
|
|
89
|
+
value = 0;
|
|
90
|
+
}
|
|
91
|
+
else if (value > this.tabCount - 1) {
|
|
92
|
+
console.warn(`[tab-editor] Invalid tab index ${value}. Max value is ${this.tabCount - 1}`);
|
|
93
|
+
value = this._selectedTabIndex;
|
|
94
|
+
}
|
|
95
|
+
this._selectedTabIndex = value;
|
|
96
|
+
this.selectedTabIndexChange.next(value);
|
|
97
|
+
if (this.tabGroup && (!opts || opts.realignInkBar !== false)) {
|
|
98
|
+
this.tabGroup.selectedIndex = value;
|
|
99
|
+
this.markForCheck();
|
|
100
|
+
// Wait tab change in UI, before realign ink tab
|
|
101
|
+
setTimeout(() => this.tabGroup.realignInkBar(), 200);
|
|
102
|
+
}
|
|
103
|
+
else if (!opts || opts.emitEvent !== false) {
|
|
104
|
+
this.markForCheck();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
realignInkBar() {
|
|
108
|
+
this.tabGroup?.realignInkBar();
|
|
109
|
+
}
|
|
110
|
+
onTabChange(event, queryTabIndexParamName) {
|
|
111
|
+
queryTabIndexParamName = queryTabIndexParamName || this.queryTabIndexParamName;
|
|
112
|
+
if (!queryTabIndexParamName || !this.route)
|
|
113
|
+
return true; // Skip if tab query param not set, or no route
|
|
114
|
+
if (!this.queryParams || +this.queryParams[queryTabIndexParamName] !== event.index) {
|
|
115
|
+
this.queryParams = this.queryParams || {};
|
|
116
|
+
this.queryParams[queryTabIndexParamName] = event.index !== 0 ? event.index : undefined;
|
|
117
|
+
if (queryTabIndexParamName === 'tab' && isNotNil(this.queryParams['subtab'])) {
|
|
118
|
+
delete this.queryParams.subtab; // clean subtab
|
|
119
|
+
}
|
|
120
|
+
this.router.navigate(['.'], {
|
|
121
|
+
relativeTo: this.route,
|
|
122
|
+
queryParams: this.queryParams,
|
|
123
|
+
replaceUrl: true,
|
|
124
|
+
state: { animated: false },
|
|
125
|
+
});
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Action triggered when user swipes
|
|
132
|
+
*/
|
|
133
|
+
onSwipeTab(event) {
|
|
134
|
+
// DEBUG
|
|
135
|
+
// if (this.debug) console.debug("[tab-page] onSwipeTab()");
|
|
136
|
+
// Skip, if not a valid swipe event
|
|
137
|
+
if (!this.enableSwipe ||
|
|
138
|
+
!event ||
|
|
139
|
+
event.defaultPrevented ||
|
|
140
|
+
(event.srcEvent && event.srcEvent.defaultPrevented) ||
|
|
141
|
+
event.pointerType !== 'touch') {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
// DEBUG
|
|
145
|
+
//if (this.debug)
|
|
146
|
+
//console.debug("[tab-page] Detected swipe: " + event.type, event);
|
|
147
|
+
let selectTabIndex = this.selectedTabIndex;
|
|
148
|
+
switch (event.type) {
|
|
149
|
+
// Open next tab
|
|
150
|
+
case 'swipeleft':
|
|
151
|
+
selectTabIndex = selectTabIndex >= this.tabCount - 1 ? 0 : selectTabIndex + 1;
|
|
152
|
+
break;
|
|
153
|
+
// Open previous tab
|
|
154
|
+
case 'swiperight':
|
|
155
|
+
selectTabIndex = selectTabIndex <= 0 ? this.tabCount : selectTabIndex - 1;
|
|
156
|
+
break;
|
|
157
|
+
// Other case
|
|
158
|
+
default:
|
|
159
|
+
console.error('[tab-page] Unknown swipe action: ' + event.type);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
setTimeout(() => {
|
|
163
|
+
this.selectedTabIndex = selectTabIndex;
|
|
164
|
+
this.markForCheck();
|
|
165
|
+
});
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
onSubTabChange(event) {
|
|
169
|
+
this.onTabChange(event, 'subtab');
|
|
170
|
+
}
|
|
171
|
+
async unload(opts) {
|
|
172
|
+
this.selectedTabIndex = 0;
|
|
173
|
+
await super.unload(opts);
|
|
174
|
+
}
|
|
175
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: AppTabEditor, deps: [{ token: i1.ActivatedRoute, optional: true }, { token: i1.Router }, { token: i2.NavController }, { token: i2.AlertController }, { token: i3.TranslateService }, { token: AppTabEditorOptions, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
176
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.4", type: AppTabEditor, inputs: { queryTabIndexParamName: "queryTabIndexParamName", selectedTabIndex: "selectedTabIndex" }, outputs: { selectedTabIndexChange: "selectedTabIndexChange" }, viewQueries: [{ propertyName: "tabGroup", first: true, predicate: ["tabGroup"], descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
|
|
177
|
+
}
|
|
178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: AppTabEditor, decorators: [{
|
|
179
|
+
type: Directive
|
|
180
|
+
}], ctorParameters: () => [{ type: i1.ActivatedRoute, decorators: [{
|
|
181
|
+
type: Optional
|
|
182
|
+
}] }, { type: i1.Router }, { type: i2.NavController }, { type: i2.AlertController }, { type: i3.TranslateService }, { type: AppTabEditorOptions, decorators: [{
|
|
183
|
+
type: Optional
|
|
184
|
+
}] }], propDecorators: { queryTabIndexParamName: [{
|
|
185
|
+
type: Input
|
|
186
|
+
}], selectedTabIndex: [{
|
|
187
|
+
type: Input
|
|
188
|
+
}], selectedTabIndexChange: [{
|
|
189
|
+
type: Output
|
|
190
|
+
}], tabGroup: [{
|
|
191
|
+
type: ViewChild,
|
|
192
|
+
args: ['tabGroup', { static: true }]
|
|
193
|
+
}] } });
|
|
194
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWVkaXRvci5jbGFzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9mb3JtL2VudGl0eS90YWItZWRpdG9yLmNsYXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBcUIsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFNL0csT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsU0FBUyxFQUFjLE1BQU0sZ0JBQWdCLENBQUM7Ozs7O0FBU3ZELE1BQU0sT0FBTyxtQkFBbUI7SUFDOUI7O09BRUc7SUFDSCxRQUFRLENBQVU7SUFFbEI7O09BRUc7SUFDSCx5QkFBeUIsQ0FBVTtJQUVuQzs7T0FFRztJQUNILFdBQVcsQ0FBVyxDQUFDLGtCQUFrQjtDQUMxQztBQUdELGtFQUFrRTtBQUNsRSxNQUFNLE9BQWdCLFlBQTRDLFNBQVEsU0FBbUI7SUFzQm5FO0lBQ1o7SUFDQTtJQUNBO0lBQ0E7SUF6QkYsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0lBRWhDLGlCQUFpQjtJQUNQLFFBQVEsQ0FBUztJQUNqQixXQUFXLENBQVU7SUFDckIseUJBQXlCLENBQVM7SUFFbkMsc0JBQXNCLENBQVM7SUFFeEMsSUFBYSxnQkFBZ0IsQ0FBQyxLQUFhO1FBQ3pDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBQ0QsSUFBSSxnQkFBZ0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUM7SUFDaEMsQ0FBQztJQUVrQixzQkFBc0IsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO0lBRTlCLFFBQVEsQ0FBYztJQUUvRCxZQUN3QixLQUFxQixFQUFFLDJCQUEyQjtJQUM5RCxNQUFjLEVBQ2Qs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QUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3B0aW9uYWwsIE91dHB1dCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IE1hdFRhYkNoYW5nZUV2ZW50LCBNYXRUYWJHcm91cCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xuaW1wb3J0IHsgQWxlcnRDb250cm9sbGVyLCBOYXZDb250cm9sbGVyIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgSGFtbWVyU3dpcGVFdmVudCB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9nZXN0dXJlL2hhbW1lci51dGlscyc7XG5pbXBvcnQgeyBpc05vdE5pbCwgdG9OdW1iZXIgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcbmltcG9ydCB7IEFwcEVkaXRvciwgSUFwcEVkaXRvciB9IGZyb20gJy4vZWRpdG9yLmNsYXNzJztcblxuZXhwb3J0IGludGVyZmFjZSBJQXBwVGFiRWRpdG9yPFQgPSBhbnk+IGV4dGVuZHMgSUFwcEVkaXRvcjxUPiB7XG4gIHNlbGVjdGVkVGFiSW5kZXg6IG51bWJlcjtcbiAgc2V0U2VsZWN0ZWRUYWJJbmRleCh2YWx1ZTogbnVtYmVyLCBvcHRzPzogeyBlbWl0RXZlbnQ/OiBib29sZWFuOyByZWFsaWduSW5rQmFyPzogYm9vbGVhbiB9KTogdm9pZDtcbiAgdW5sb2FkKG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD47XG4gIHJlYWxpZ25JbmtCYXIoKTogdm9pZDtcbn1cblxuZXhwb3J0IGNsYXNzIEFwcFRhYkVkaXRvck9wdGlvbnMge1xuICAvKipcbiAgICogTnVtYmVyIG9mIHRhYi4gMSBieSBkZWZhdWx0XG4gICAqL1xuICB0YWJDb3VudD86IG51bWJlcjtcblxuICAvKipcbiAgICogJzIwMG1zJyBieSBkZWZhdWx0XG4gICAqL1xuICB0YWJHcm91cEFuaW1hdGlvbkR1cmF0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTaG91bGQgZW5hYmxlIHN3aXBlIGJldHdlZW4gdGFiLCBvbiB0b3VjaCBzY3JlZW5cbiAgICovXG4gIGVuYWJsZVN3aXBlPzogYm9vbGVhbjsgLy8gdHJ1ZSBieSBkZWZhdWx0XG59XG5cbkBEaXJlY3RpdmUoKVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtY2xhc3Mtc3VmZml4XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQXBwVGFiRWRpdG9yPFQgPSBhbnksIElEID0gbnVtYmVyLCBPID0gYW55PiBleHRlbmRzIEFwcEVkaXRvcjxULCBJRCwgTz4gaW1wbGVtZW50cyBJQXBwVGFiRWRpdG9yPFQ+LCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHByb3RlY3RlZCBfc2VsZWN0ZWRUYWJJbmRleCA9IDA7XG5cbiAgLy8gRWRpdG9yIG9wdGlvbnNcbiAgcHJvdGVjdGVkIHRhYkNvdW50OiBudW1iZXI7XG4gIHByb3RlY3RlZCBlbmFibGVTd2lwZTogYm9vbGVhbjtcbiAgcHJvdGVjdGVkIHRhYkdyb3VwQW5pbWF0aW9uRHVyYXRpb246IHN0cmluZztcblxuICBASW5wdXQoKSBxdWVyeVRhYkluZGV4UGFyYW1OYW1lOiBzdHJpbmc7XG5cbiAgQElucHV0KCkgc2V0IHNlbGVjdGVkVGFiSW5kZXgodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuc2V0U2VsZWN0ZWRUYWJJbmRleCh2YWx1ZSk7XG4gIH1cbiAgZ2V0IHNlbGVjdGVkVGFiSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRUYWJJbmRleDtcbiAgfVxuXG4gIEBPdXRwdXQoKSByZWFkb25seSBzZWxlY3RlZFRhYkluZGV4Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgQFZpZXdDaGlsZCgndGFiR3JvdXAnLCB7IHN0YXRpYzogdHJ1ZSB9KSB0YWJHcm91cDogTWF0VGFiR3JvdXA7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIEBPcHRpb25hbCgpIHByb3RlY3RlZCByb3V0ZTogQWN0aXZhdGVkUm91dGUsIC8vIE1vZGFsIGVkaXRvciBnaXZlICdudWxsJ1xuICAgIHByb3RlY3RlZCByb3V0ZXI6IFJvdXRlcixcbiAgICBwcm90ZWN0ZWQgbmF2Q29udHJvbGxlcjogTmF2Q29udHJvbGxlcixcbiAgICBwcm90ZWN0ZWQgYWxlcnRDdHJsOiBBbGVydENvbnRyb2xsZXIsXG4gICAgcHJvdGVjdGVkIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBvcHRpb25zPzogQXBwVGFiRWRpdG9yT3B0aW9uc1xuICApIHtcbiAgICBzdXBlcihyb3V0ZSwgcm91dGVyLCBuYXZDb250cm9sbGVyLCBhbGVydEN0cmwsIHRyYW5zbGF0ZSk7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIHRhYkNvdW50OiAxLFxuICAgICAgZW5hYmxlU3dpcGU6IHRydWUsXG4gICAgICB0YWJHcm91cEFuaW1hdGlvbkR1cmF0aW9uOiAnMjAwbXMnLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuICAgIHRoaXMudGFiQ291bnQgPSBvcHRpb25zLnRhYkNvdW50O1xuICAgIHRoaXMuZW5hYmxlU3dpcGUgPSBvcHRpb25zLmVuYWJsZVN3aXBlO1xuICAgIHRoaXMudGFiR3JvdXBBbmltYXRpb25EdXJhdGlvbiA9IG9wdGlvbnMudGFiR3JvdXBBbmltYXRpb25EdXJhdGlvbjtcbiAgICB0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUgPSAndGFiJztcbiAgICB0aGlzLl9sb2dQcmVmaXggPSAnW3RhYi1lZGl0b3JdICc7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgLy8gUmVhZCB0aGUgc2VsZWN0ZWQgdGFiIGluZGV4LCBmcm9tIHBhdGggcXVlcnkgcGFyYW1zXG4gICAgaWYgKHRoaXMudGFiR3JvdXAgJiYgdGhpcy5yb3V0ZSAmJiB0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24oXG4gICAgICAgIHRoaXMucm91dGUucXVlcnlQYXJhbXMuc3Vic2NyaWJlKChxdWVyeVBhcmFtcykgPT4ge1xuICAgICAgICAgIHRoaXMucXVlcnlQYXJhbXMgPSB7IC4uLnF1ZXJ5UGFyYW1zIH07XG5cbiAgICAgICAgICAvLyBQYXJzZSB0YWIgcGFyYW1cbiAgICAgICAgICBpZiAodGhpcy50YWJDb3VudCA+IDEgJiYgdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJJbmRleCA9IHRvTnVtYmVyKHF1ZXJ5UGFyYW1zW3RoaXMucXVlcnlUYWJJbmRleFBhcmFtTmFtZV0sIDApO1xuICAgICAgICAgICAgdGhpcy5xdWVyeVBhcmFtc1t0aGlzLnF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWVdID0gdGFiSW5kZXggIT09IDAgPyB0YWJJbmRleCA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkVGFiSW5kZXggIT09IHRhYkluZGV4KSB7XG4gICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUYWJJbmRleCA9IHRhYkluZGV4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFJlYWxpZ24gdGFiLCBhZnRlciBhIGRlbGF5IGJlY2F1c2UgdGhlIHRhYiBjYW4gYmUgZGlzYWJsZWQgd2hlbiBjb21wb25lbnQgaXMgY3JlYXRlZFxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50YWJHcm91cC5yZWFsaWduSW5rQmFyKCksIDUwMCk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgdGhpcy5zZWxlY3RlZFRhYkluZGV4Q2hhbmdlLmNvbXBsZXRlKCk7XG4gIH1cblxuICBzZXRTZWxlY3RlZFRhYkluZGV4KHZhbHVlOiBudW1iZXIsIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW47IHJlYWxpZ25JbmtCYXI/OiBib29sZWFuIH0pIHtcbiAgICAvLyBGaXggdmFsdWVcbiAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICB2YWx1ZSA9IDA7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA+IHRoaXMudGFiQ291bnQgLSAxKSB7XG4gICAgICBjb25zb2xlLndhcm4oYFt0YWItZWRpdG9yXSBJbnZhbGlkIHRhYiBpbmRleCAke3ZhbHVlfS4gTWF4IHZhbHVlIGlzICR7dGhpcy50YWJDb3VudCAtIDF9YCk7XG4gICAgICB2YWx1ZSA9IHRoaXMuX3NlbGVjdGVkVGFiSW5kZXg7XG4gICAgfVxuXG4gICAgdGhpcy5fc2VsZWN0ZWRUYWJJbmRleCA9IHZhbHVlO1xuICAgIHRoaXMuc2VsZWN0ZWRUYWJJbmRleENoYW5nZS5uZXh0KHZhbHVlKTtcblxuICAgIGlmICh0aGlzLnRhYkdyb3VwICYmICghb3B0cyB8fCBvcHRzLnJlYWxpZ25JbmtCYXIgIT09IGZhbHNlKSkge1xuICAgICAgdGhpcy50YWJHcm91cC5zZWxlY3RlZEluZGV4ID0gdmFsdWU7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgLy8gV2FpdCB0YWIgY2hhbmdlIGluIFVJLCBiZWZvcmUgcmVhbGlnbiBpbmsgdGFiXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMudGFiR3JvdXAucmVhbGlnbklua0JhcigpLCAyMDApO1xuICAgIH0gZWxzZSBpZiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHJlYWxpZ25JbmtCYXIoKSB7XG4gICAgdGhpcy50YWJHcm91cD8ucmVhbGlnbklua0JhcigpO1xuICB9XG5cbiAgb25UYWJDaGFuZ2UoZXZlbnQ6IE1hdFRhYkNoYW5nZUV2ZW50LCBxdWVyeVRhYkluZGV4UGFyYW1OYW1lPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcXVlcnlUYWJJbmRleFBhcmFtTmFtZSA9IHF1ZXJ5VGFiSW5kZXhQYXJhbU5hbWUgfHwgdGhpcy5xdWVyeVRhYkluZGV4UGFyYW1OYW1lO1xuXG4gICAgaWYgKCFxdWVyeVRhYkluZGV4UGFyYW1OYW1lIHx8ICF0aGlzLnJvdXRlKSByZXR1cm4gdHJ1ZTsgLy8gU2tpcCBpZiB0YWIgcXVlcnkgcGFyYW0gbm90IHNldCwgb3Igbm8gcm91dGVcblxuICAgIGlmICghdGhpcy5xdWVyeVBhcmFtcyB8fCArdGhpcy5xdWVyeVBhcmFtc1txdWVyeVRhYkluZGV4UGFyYW1OYW1lXSAhPT0gZXZlbnQuaW5kZXgpIHtcbiAgICAgIHRoaXMucXVlcnlQYXJhbXMgPSB0aGlzLnF1ZXJ5UGFyYW1zIHx8IHt9O1xuICAgICAgdGhpcy5xdWVyeVBhcmFtc1txdWVyeVRhYkluZGV4UGFyYW1OYW1lXSA9IGV2ZW50LmluZGV4ICE9PSAwID8gZXZlbnQuaW5kZXggOiB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChxdWVyeVRhYkluZGV4UGFyYW1OYW1lID09PSAndGFiJyAmJiBpc05vdE5pbCh0aGlzLnF1ZXJ5UGFyYW1zWydzdWJ0YWInXSkpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMucXVlcnlQYXJhbXMuc3VidGFiOyAvLyBjbGVhbiBzdWJ0YWJcbiAgICAgIH1cbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnLiddLCB7XG4gICAgICAgIHJlbGF0aXZlVG86IHRoaXMucm91dGUsXG4gICAgICAgIHF1ZXJ5UGFyYW1zOiB0aGlzLnF1ZXJ5UGFyYW1zLFxuICAgICAgICByZXBsYWNlVXJsOiB0cnVlLFxuICAgICAgICBzdGF0ZTogeyBhbmltYXRlZDogZmFsc2UgfSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3Rpb24gdHJpZ2dlcmVkIHdoZW4gdXNlciBzd2lwZXNcbiAgICovXG4gIG9uU3dpcGVUYWIoZXZlbnQ6IEhhbW1lclN3aXBlRXZlbnQpOiBib29sZWFuIHtcbiAgICAvLyBERUJVR1xuICAgIC8vIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmRlYnVnKFwiW3RhYi1wYWdlXSBvblN3aXBlVGFiKClcIik7XG5cbiAgICAvLyBTa2lwLCBpZiBub3QgYSB2YWxpZCBzd2lwZSBldmVudFxuICAgIGlmIChcbiAgICAgICF0aGlzLmVuYWJsZVN3aXBlIHx8XG4gICAgICAhZXZlbnQgfHxcbiAgICAgIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHxcbiAgICAgIChldmVudC5zcmNFdmVudCAmJiBldmVudC5zcmNFdmVudC5kZWZhdWx0UHJldmVudGVkKSB8fFxuICAgICAgZXZlbnQucG9pbnRlclR5cGUgIT09ICd0b3VjaCdcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBERUJVR1xuICAgIC8vaWYgKHRoaXMuZGVidWcpXG4gICAgLy9jb25zb2xlLmRlYnVnKFwiW3RhYi1wYWdlXSBEZXRlY3RlZCBzd2lwZTogXCIgKyBldmVudC50eXBlLCBldmVudCk7XG5cbiAgICBsZXQgc2VsZWN0VGFiSW5kZXggPSB0aGlzLnNlbGVjdGVkVGFiSW5kZXg7XG4gICAgc3dpdGNoIChldmVudC50eXBlKSB7XG4gICAgICAvLyBPcGVuIG5leHQgdGFiXG4gICAgICBjYXNlICdzd2lwZWxlZnQnOlxuICAgICAgICBzZWxlY3RUYWJJbmRleCA9IHNlbGVjdFRhYkluZGV4ID49IHRoaXMudGFiQ291bnQgLSAxID8gMCA6IHNlbGVjdFRhYkluZGV4ICsgMTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIC8vIE9wZW4gcHJldmlvdXMgdGFiXG4gICAgICBjYXNlICdzd2lwZXJpZ2h0JzpcbiAgICAgICAgc2VsZWN0VGFiSW5kZXggPSBzZWxlY3RUYWJJbmRleCA8PSAwID8gdGhpcy50YWJDb3VudCA6IHNlbGVjdFRhYkluZGV4IC0gMTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIC8vIE90aGVyIGNhc2VcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1t0YWItcGFnZV0gVW5rbm93biBzd2lwZSBhY3Rpb246ICcgKyBldmVudC50eXBlKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zZWxlY3RlZFRhYkluZGV4ID0gc2VsZWN0VGFiSW5kZXg7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBvblN1YlRhYkNoYW5nZShldmVudDogTWF0VGFiQ2hhbmdlRXZlbnQpIHtcbiAgICB0aGlzLm9uVGFiQ2hhbmdlKGV2ZW50LCAnc3VidGFiJyk7XG4gIH1cblxuICBhc3luYyB1bmxvYWQob3B0cz86IHsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZWxlY3RlZFRhYkluZGV4ID0gMDtcbiAgICBhd2FpdCBzdXBlci51bmxvYWQob3B0cyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0Rmlyc3RJbnZhbGlkVGFiSW5kZXgoKTogbnVtYmVyO1xufVxuIl19
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { Directive, Input } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject, Subject, Subscription } from 'rxjs';
|
|
3
|
+
import { AppFormProvider, AppFormUtils } from './form.utils';
|
|
4
|
+
import { waitForFalse, waitForTrue } from '../../shared/observables';
|
|
5
|
+
import { AppTable } from '../table/table.class';
|
|
6
|
+
import { AppForm } from './form.class';
|
|
7
|
+
import { AppEditor } from './entity/editor.class';
|
|
8
|
+
import { AbstractControl } from '@angular/forms';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
|
11
|
+
export class AppFormContainer {
|
|
12
|
+
_children;
|
|
13
|
+
_childrenPath;
|
|
14
|
+
_subscription = new Subscription();
|
|
15
|
+
_logPrefix = '[form-container] ';
|
|
16
|
+
_enabled = false;
|
|
17
|
+
destroySubject = new Subject();
|
|
18
|
+
// TODO use RxState instead ?
|
|
19
|
+
readySubject = new BehaviorSubject(false);
|
|
20
|
+
loadingSubject = new BehaviorSubject(true);
|
|
21
|
+
dirtySubject = new BehaviorSubject(false);
|
|
22
|
+
touchedSubject = new BehaviorSubject(false);
|
|
23
|
+
errorSubject = new BehaviorSubject(undefined);
|
|
24
|
+
get children() {
|
|
25
|
+
return this._children;
|
|
26
|
+
}
|
|
27
|
+
get tables() {
|
|
28
|
+
return this._children && this._children.filter((c) => c instanceof AppTable);
|
|
29
|
+
}
|
|
30
|
+
get forms() {
|
|
31
|
+
return this._children && this._children.filter((c) => c instanceof AppForm);
|
|
32
|
+
}
|
|
33
|
+
get editors() {
|
|
34
|
+
return this._children && this._children.filter((c) => c instanceof AppEditor);
|
|
35
|
+
}
|
|
36
|
+
get error() {
|
|
37
|
+
return this.errorSubject.value;
|
|
38
|
+
}
|
|
39
|
+
set error(error) {
|
|
40
|
+
this.setError(error);
|
|
41
|
+
}
|
|
42
|
+
get loading() {
|
|
43
|
+
return this.loadingSubject.value || (this._children && this._children.findIndex((c) => c.enabled && c.loading) !== -1) || false;
|
|
44
|
+
}
|
|
45
|
+
get loaded() {
|
|
46
|
+
return (!this.loadingSubject.value && (!this._children || this._children.findIndex((c) => c.enabled && c.loading) === -1)) || false;
|
|
47
|
+
}
|
|
48
|
+
get dirty() {
|
|
49
|
+
return this.dirtySubject.value || (this._children && this._children.findIndex((c) => c.enabled && c.dirty) !== -1) || false;
|
|
50
|
+
}
|
|
51
|
+
get valid() {
|
|
52
|
+
// Important: Should be not invalid AND not pending, so use '!valid' (DO NOT use 'invalid')
|
|
53
|
+
return !this._children || this._children.findIndex((c) => c.enabled && !c.valid) === -1;
|
|
54
|
+
}
|
|
55
|
+
get invalid() {
|
|
56
|
+
return (this._children && this._children.findIndex((c) => c.enabled && c.invalid) !== -1) || false;
|
|
57
|
+
}
|
|
58
|
+
get pending() {
|
|
59
|
+
return (this._children && this._children.findIndex((c) => c.enabled && c.pending) !== -1) || false;
|
|
60
|
+
}
|
|
61
|
+
get empty() {
|
|
62
|
+
return !this._enabled;
|
|
63
|
+
}
|
|
64
|
+
get touched() {
|
|
65
|
+
return this.touchedSubject.value || (this._children && this._children.findIndex((c) => c.enabled && c.touched) !== -1) || false;
|
|
66
|
+
}
|
|
67
|
+
get untouched() {
|
|
68
|
+
return (!this.touchedSubject.value && (!this._children || this._children.findIndex((c) => c.enabled && c.touched) === -1)) || false;
|
|
69
|
+
}
|
|
70
|
+
get enabled() {
|
|
71
|
+
return this._enabled;
|
|
72
|
+
}
|
|
73
|
+
get disabled() {
|
|
74
|
+
return !this._enabled;
|
|
75
|
+
}
|
|
76
|
+
get destroyed() {
|
|
77
|
+
return this.destroySubject?.closed !== false;
|
|
78
|
+
}
|
|
79
|
+
debug = false;
|
|
80
|
+
constructor() { }
|
|
81
|
+
ngOnInit() {
|
|
82
|
+
// Can be override by sub classes
|
|
83
|
+
}
|
|
84
|
+
ngOnDestroy() {
|
|
85
|
+
this._subscription.unsubscribe();
|
|
86
|
+
this.readySubject.unsubscribe();
|
|
87
|
+
this.loadingSubject.unsubscribe();
|
|
88
|
+
this.touchedSubject.unsubscribe();
|
|
89
|
+
this.errorSubject.unsubscribe();
|
|
90
|
+
this.destroySubject.next();
|
|
91
|
+
this.destroySubject.unsubscribe();
|
|
92
|
+
}
|
|
93
|
+
addForm(path, form) {
|
|
94
|
+
if (!form)
|
|
95
|
+
throw new Error('Trying to register an undefined child form');
|
|
96
|
+
this._children = this._children || [];
|
|
97
|
+
if (typeof form === 'function') {
|
|
98
|
+
this._children.push(new AppFormProvider(form));
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this._children.push(form);
|
|
102
|
+
}
|
|
103
|
+
this._childrenPath = this._childrenPath || [];
|
|
104
|
+
this._childrenPath.push(path || null);
|
|
105
|
+
}
|
|
106
|
+
addForms(forms) {
|
|
107
|
+
(forms || []).forEach((form) => this.addForm(null, form));
|
|
108
|
+
}
|
|
109
|
+
removeForm(form) {
|
|
110
|
+
if (!form)
|
|
111
|
+
throw new Error('Trying to remove an undefined child form');
|
|
112
|
+
const index = typeof form == 'string' ? (this._childrenPath || []).findIndex((c) => c === form) : (this._children || []).findIndex((c) => c === form);
|
|
113
|
+
if (index !== -1) {
|
|
114
|
+
this._childrenPath.splice(index, 1);
|
|
115
|
+
return this._children.splice(index, 1)?.[0];
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
disable(opts) {
|
|
120
|
+
this._enabled = false;
|
|
121
|
+
this._children?.forEach((c) => c.disable(opts));
|
|
122
|
+
if (!this.loading && (!opts || opts.emitEvent !== false))
|
|
123
|
+
this.markForCheck();
|
|
124
|
+
}
|
|
125
|
+
enable(opts) {
|
|
126
|
+
this._enabled = true;
|
|
127
|
+
this._children?.forEach((c) => c.enable(opts));
|
|
128
|
+
if (!this.loading && (!opts || opts.emitEvent !== false))
|
|
129
|
+
this.markForCheck();
|
|
130
|
+
}
|
|
131
|
+
markAsPristine(opts) {
|
|
132
|
+
this.error = null;
|
|
133
|
+
if (this.dirtySubject.value !== false) {
|
|
134
|
+
this.dirtySubject.next(false);
|
|
135
|
+
}
|
|
136
|
+
this._children?.forEach((c) => c.markAsPristine(opts));
|
|
137
|
+
if (!this.loading && (!opts || opts.emitEvent !== false))
|
|
138
|
+
this.markForCheck();
|
|
139
|
+
}
|
|
140
|
+
markAsUntouched(opts) {
|
|
141
|
+
if (this.touchedSubject.value !== false) {
|
|
142
|
+
this.touchedSubject.next(false);
|
|
143
|
+
}
|
|
144
|
+
this._children?.forEach((c) => c.markAsUntouched());
|
|
145
|
+
if (!this.loading && (!opts || opts.emitEvent !== false))
|
|
146
|
+
this.markForCheck();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @deprecated prefer to use markAllAsTouched()
|
|
150
|
+
* @param opts
|
|
151
|
+
*/
|
|
152
|
+
markAsTouched(opts) {
|
|
153
|
+
if (!this.touchedSubject.value !== true) {
|
|
154
|
+
this.touchedSubject.next(true);
|
|
155
|
+
}
|
|
156
|
+
this._children?.forEach((c) => c.markAsTouched(opts));
|
|
157
|
+
if (!this.loading && (!opts || opts.emitEvent !== false))
|
|
158
|
+
this.markForCheck();
|
|
159
|
+
}
|
|
160
|
+
markAllAsTouched(opts) {
|
|
161
|
+
if (this.touchedSubject.value !== true) {
|
|
162
|
+
this.touchedSubject.next(true);
|
|
163
|
+
}
|
|
164
|
+
this._children?.forEach((c) => c.markAllAsTouched(opts));
|
|
165
|
+
if (!this.loading && (!opts || opts.emitEvent !== false))
|
|
166
|
+
this.markForCheck();
|
|
167
|
+
}
|
|
168
|
+
markAsDirty(opts) {
|
|
169
|
+
if (this.dirtySubject.value !== true) {
|
|
170
|
+
this.dirtySubject.next(true);
|
|
171
|
+
if (!this.loading && (!opts || opts.emitEvent !== false))
|
|
172
|
+
this.markForCheck();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
markAsLoading(opts) {
|
|
176
|
+
if (!this.loadingSubject.closed && this.loadingSubject.value !== true) {
|
|
177
|
+
this.loadingSubject.next(true);
|
|
178
|
+
if (!opts || opts.emitEvent !== false) {
|
|
179
|
+
this.markForCheck();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
markAsLoaded(opts) {
|
|
184
|
+
if (!this.loadingSubject.closed && this.loadingSubject.value !== false) {
|
|
185
|
+
this.loadingSubject.next(false);
|
|
186
|
+
if (!opts || opts.onlySelf !== true) {
|
|
187
|
+
// Emit to children forms and editors
|
|
188
|
+
// note: tables should be changed by parent
|
|
189
|
+
this.forms?.forEach((f) => f.markAsLoaded(opts));
|
|
190
|
+
this.editors?.forEach((e) => e.markAsLoaded(opts));
|
|
191
|
+
}
|
|
192
|
+
if (!opts || opts.emitEvent !== false) {
|
|
193
|
+
this.markForCheck();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
markAsReady(opts) {
|
|
198
|
+
this._children?.forEach((c) => c.markAsReady(opts));
|
|
199
|
+
if (!this.readySubject.closed && this.readySubject.value !== true) {
|
|
200
|
+
this.readySubject.next(true);
|
|
201
|
+
// If subclasses implements OnReady
|
|
202
|
+
if (typeof this['ngOnReady'] === 'function') {
|
|
203
|
+
this.ngOnReady();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Wait form is ready
|
|
209
|
+
*
|
|
210
|
+
* @param opts
|
|
211
|
+
*/
|
|
212
|
+
ready(opts) {
|
|
213
|
+
if (this.readySubject.value)
|
|
214
|
+
return Promise.resolve();
|
|
215
|
+
return waitForTrue(this.readySubject, { stop: this.destroySubject, ...opts });
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Wait form is not busy (=loaded)
|
|
219
|
+
*
|
|
220
|
+
* @param opts
|
|
221
|
+
*/
|
|
222
|
+
waitIdle(opts) {
|
|
223
|
+
if (!this.loadingSubject.value)
|
|
224
|
+
return Promise.resolve();
|
|
225
|
+
return waitForFalse(this.loadingSubject, { stop: this.destroySubject, ...opts });
|
|
226
|
+
}
|
|
227
|
+
logFormErrors(prefix) {
|
|
228
|
+
if (this.debug)
|
|
229
|
+
console.debug('[editor] Editor not valid. Checking where (forms, tables)...');
|
|
230
|
+
this._children?.forEach((c) => this.logChildrenErrors(c, prefix));
|
|
231
|
+
}
|
|
232
|
+
/* -- protected methods -- */
|
|
233
|
+
registerSubscription(sub) {
|
|
234
|
+
this._subscription.add(sub);
|
|
235
|
+
}
|
|
236
|
+
unregisterSubscription(sub) {
|
|
237
|
+
this._subscription.remove(sub);
|
|
238
|
+
}
|
|
239
|
+
setError(value, opts) {
|
|
240
|
+
// Compare using '!=' to detect null and undefined as same value
|
|
241
|
+
if (this.errorSubject.value != value) {
|
|
242
|
+
this.errorSubject.next(value);
|
|
243
|
+
if (!opts || opts.emitEvent !== false)
|
|
244
|
+
this.markForCheck();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
resetError(opts) {
|
|
248
|
+
this.setError(undefined, opts);
|
|
249
|
+
}
|
|
250
|
+
markForCheck() {
|
|
251
|
+
// Should be overwritten by subclasses
|
|
252
|
+
if (this.debug)
|
|
253
|
+
console.warn('markForCheck() has been called, but is not overwritten by component ' + this.constructor.name);
|
|
254
|
+
}
|
|
255
|
+
logChildrenErrors(c, prefix, path) {
|
|
256
|
+
prefix = prefix || this._logPrefix;
|
|
257
|
+
// If editor
|
|
258
|
+
if (c instanceof AppEditor) {
|
|
259
|
+
if (!c.empty && !c.valid) {
|
|
260
|
+
if (c.pending) {
|
|
261
|
+
const path = c.constructor.name.toLowerCase();
|
|
262
|
+
console.warn(`${prefix} -> ${path}: waiting while pending...`);
|
|
263
|
+
AppFormUtils.waitWhilePending(c, { timeout: 1000 }).then(() => c.logFormErrors(prefix));
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
c.logFormErrors(prefix);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Angular form control
|
|
271
|
+
else if (c instanceof AbstractControl) {
|
|
272
|
+
AppFormUtils.logFormErrors(c, prefix, path);
|
|
273
|
+
}
|
|
274
|
+
// If form provider: get delegate
|
|
275
|
+
else if (c instanceof AppFormProvider) {
|
|
276
|
+
if (!c.empty && !c.valid) {
|
|
277
|
+
c.waitDelegate({ timeout: 1000 }).then((delegate) => this.logChildrenErrors(delegate, prefix, 'provider'));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// If table
|
|
281
|
+
else if (c instanceof AppTable) {
|
|
282
|
+
if (c.invalid && c.editedRow && c.editedRow.validator) {
|
|
283
|
+
const path = c.constructor.name.toLowerCase();
|
|
284
|
+
AppFormUtils.logFormErrors(c.editedRow.validator, prefix, path);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// If form
|
|
288
|
+
else if (c instanceof AppForm) {
|
|
289
|
+
if (!c.empty && !c.valid) {
|
|
290
|
+
if (c.pending) {
|
|
291
|
+
const path = c.constructor.name.toLowerCase();
|
|
292
|
+
console.warn(`${prefix} -> ${path}: waiting while pending...`);
|
|
293
|
+
AppFormUtils.waitWhilePending(c, { timeout: 1000 }).then(() => this.logChildrenErrors(c.form, prefix, path));
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
AppFormUtils.logFormErrors(c.form, prefix);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
console.warn(`${prefix} Unknown children sub-form: `, c);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: AppFormContainer, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
305
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.4", type: AppFormContainer, inputs: { debug: "debug" }, ngImport: i0 });
|
|
306
|
+
}
|
|
307
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: AppFormContainer, decorators: [{
|
|
308
|
+
type: Directive
|
|
309
|
+
}], ctorParameters: () => [], propDecorators: { debug: [{
|
|
310
|
+
type: Input
|
|
311
|
+
}] } });
|
|
312
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1jb250YWluZXIuY2xhc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvZm9ybS9mb3JtLWNvbnRhaW5lci5jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDcEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFxQyxNQUFNLGNBQWMsQ0FBQztBQUNoRyxPQUFPLEVBQUUsWUFBWSxFQUFrQixXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDaEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQWNqRCxrRUFBa0U7QUFDbEUsTUFBTSxPQUFnQixnQkFBZ0I7SUFDNUIsU0FBUyxDQUFhO0lBQ3RCLGFBQWEsQ0FBVztJQUN4QixhQUFhLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUNqQyxVQUFVLEdBQUcsbUJBQW1CLENBQUM7SUFDakMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUVSLGNBQWMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0lBRXhELDZCQUE2QjtJQUNwQixZQUFZLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDbkQsY0FBYyxHQUFHLElBQUksZUFBZSxDQUFVLElBQUksQ0FBQyxDQUFDO0lBQ3BELFlBQVksR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUNuRCxjQUFjLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDckQsWUFBWSxHQUFHLElBQUksZUFBZSxDQUFTLFNBQVMsQ0FBQyxDQUFDO0lBRS9ELElBQUksUUFBUTtRQUNWLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBRUQsSUFBSSxNQUFNO1FBQ1IsT0FBTyxJQUFJLENBQUMsU0FBUyxJQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFlBQVksUUFBUSxDQUFxQixDQUFDO0lBQ3BHLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxTQUFTLElBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsWUFBWSxPQUFPLENBQW9CLENBQUM7SUFDbEcsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxZQUFZLFNBQVMsQ0FBaUIsQ0FBQztJQUNqRyxDQUFDO0lBRUQsSUFBSSxLQUFLO1FBQ1AsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQztJQUNqQyxDQUFDO0lBRUQsSUFBSSxLQUFLLENBQUMsS0FBYTtRQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDbEksQ0FBQztJQUVELElBQUksTUFBTTtRQUNSLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDO0lBQ3RJLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDOUgsQ0FBQztJQUVELElBQUksS0FBSztRQUNQLDJGQUEyRjtRQUMzRixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1QsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDO0lBQ3JHLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVCxPQUFPLENBQUMsSUFBSSxD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Z0IsQ0FBQyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQy9HLENBQUM7cUJBQU0sQ0FBQztvQkFDTixZQUFZLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzdDLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSw4QkFBOEIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzRCxDQUFDO0lBQ0gsQ0FBQzt1R0FyVW1CLGdCQUFnQjsyRkFBaEIsZ0JBQWdCOzsyRkFBaEIsZ0JBQWdCO2tCQUZyQyxTQUFTO3dEQTJGQyxLQUFLO3NCQUFiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEFwcEZvcm1Qcm92aWRlciwgQXBwRm9ybVV0aWxzLCBJQXBwRm9ybSwgSUFwcEZvcm1HZXR0ZXIsIE9uUmVhZHkgfSBmcm9tICcuL2Zvcm0udXRpbHMnO1xuaW1wb3J0IHsgd2FpdEZvckZhbHNlLCBXYWl0Rm9yT3B0aW9ucywgd2FpdEZvclRydWUgfSBmcm9tICcuLi8uLi9zaGFyZWQvb2JzZXJ2YWJsZXMnO1xuaW1wb3J0IHsgQXBwVGFibGUgfSBmcm9tICcuLi90YWJsZS90YWJsZS5jbGFzcyc7XG5pbXBvcnQgeyBBcHBGb3JtIH0gZnJvbSAnLi9mb3JtLmNsYXNzJztcbmltcG9ydCB7IEFwcEVkaXRvciB9IGZyb20gJy4vZW50aXR5L2VkaXRvci5jbGFzcyc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUFwcEZvcm1Db250YWluZXI8VCA9IGFueT4gZXh0ZW5kcyBJQXBwRm9ybTxUPiB7XG4gIGNoaWxkcmVuOiBJQXBwRm9ybVtdO1xuICB0YWJsZXM6IEFwcFRhYmxlPGFueT5bXTtcbiAgZm9ybXM6IEFwcEZvcm08YW55PltdO1xuICBlZGl0b3JzOiBBcHBFZGl0b3I8YW55PltdO1xuXG4gIGFkZEZvcm0ocGF0aDogc3RyaW5nLCBmb3JtPzogSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcik6IHZvaWQ7XG4gIGFkZEZvcm1zKGZvcm1zOiAoSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcilbXSk6IHZvaWQ7XG4gIHJlbW92ZUZvcm0oZm9ybTogc3RyaW5nIHwgSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcik6IElBcHBGb3JtIHwgSUFwcEZvcm1HZXR0ZXI7XG59XG5cbkBEaXJlY3RpdmUoKVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtY2xhc3Mtc3VmZml4XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQXBwRm9ybUNvbnRhaW5lcjxUID0gYW55PiBpbXBsZW1lbnRzIElBcHBGb3JtQ29udGFpbmVyPFQ+LCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgX2NoaWxkcmVuOiBJQXBwRm9ybVtdO1xuICBwcml2YXRlIF9jaGlsZHJlblBhdGg6IHN0cmluZ1tdO1xuICBwcml2YXRlIF9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByb3RlY3RlZCBfbG9nUHJlZml4ID0gJ1tmb3JtLWNvbnRhaW5lcl0gJztcbiAgcHJvdGVjdGVkIF9lbmFibGVkID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlc3Ryb3lTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvLyBUT0RPIHVzZSBSeFN0YXRlIGluc3RlYWQgP1xuICByZWFkb25seSByZWFkeVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgbG9hZGluZ1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRydWUpO1xuICByZWFkb25seSBkaXJ0eVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgdG91Y2hlZFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgZXJyb3JTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KHVuZGVmaW5lZCk7XG5cbiAgZ2V0IGNoaWxkcmVuKCk6IElBcHBGb3JtW10ge1xuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbjtcbiAgfVxuXG4gIGdldCB0YWJsZXMoKTogQXBwVGFibGU8YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fY2hpbGRyZW4gJiYgKHRoaXMuX2NoaWxkcmVuLmZpbHRlcigoYykgPT4gYyBpbnN0YW5jZW9mIEFwcFRhYmxlKSBhcyBBcHBUYWJsZTxhbnk+W10pO1xuICB9XG5cbiAgZ2V0IGZvcm1zKCk6IEFwcEZvcm08YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fY2hpbGRyZW4gJiYgKHRoaXMuX2NoaWxkcmVuLmZpbHRlcigoYykgPT4gYyBpbnN0YW5jZW9mIEFwcEZvcm0pIGFzIEFwcEZvcm08YW55PltdKTtcbiAgfVxuXG4gIGdldCBlZGl0b3JzKCk6IEFwcEVkaXRvcjxhbnk+W10ge1xuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbiAmJiAodGhpcy5fY2hpbGRyZW4uZmlsdGVyKChjKSA9PiBjIGluc3RhbmNlb2YgQXBwRWRpdG9yKSBhcyBBcHBFZGl0b3JbXSk7XG4gIH1cblxuICBnZXQgZXJyb3IoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvclN1YmplY3QudmFsdWU7XG4gIH1cblxuICBzZXQgZXJyb3IoZXJyb3I6IHN0cmluZykge1xuICAgIHRoaXMuc2V0RXJyb3IoZXJyb3IpO1xuICB9XG5cbiAgZ2V0IGxvYWRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZGluZ1N1YmplY3QudmFsdWUgfHwgKHRoaXMuX2NoaWxkcmVuICYmIHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleCgoYykgPT4gYy5lbmFibGVkICYmIGMubG9hZGluZykgIT09IC0xKSB8fCBmYWxzZTtcbiAgfVxuXG4gIGdldCBsb2FkZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICghdGhpcy5sb2FkaW5nU3ViamVjdC52YWx1ZSAmJiAoIXRoaXMuX2NoaWxkcmVuIHx8IHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleCgoYykgPT4gYy5lbmFibGVkICYmIGMubG9hZGluZykgPT09IC0xKSkgfHwgZmFsc2U7XG4gIH1cblxuICBnZXQgZGlydHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGlydHlTdWJqZWN0LnZhbHVlIHx8ICh0aGlzLl9jaGlsZHJlbiAmJiB0aGlzLl9jaGlsZHJlbi5maW5kSW5kZXgoKGMpID0+IGMuZW5hYmxlZCAmJiBjLmRpcnR5KSAhPT0gLTEpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0IHZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIC8vIEltcG9ydGFudDogU2hvdWxkIGJlIG5vdCBpbnZhbGlkIEFORCBub3QgcGVuZGluZywgc28gdXNlICchdmFsaWQnIChETyBOT1QgdXNlICdpbnZhbGlkJylcbiAgICByZXR1cm4gIXRoaXMuX2NoaWxkcmVuIHx8IHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleCgoYykgPT4gYy5lbmFibGVkICYmICFjLnZhbGlkKSA9PT0gLTE7XG4gIH1cblxuICBnZXQgaW52YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHRoaXMuX2NoaWxkcmVuICYmIHRoaXMuX2NoaWxkcmVuLmZpbmRJbmRleCgoYykgPT4gYy5lbmFibGVkICYmIGMuaW52YWxpZCkgIT09IC0xKSB8fCBmYWxzZTtcbiAgfVxuXG4gIGdldCBwZW5kaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy5fY2hpbGRyZW4gJiYgdGhpcy5fY2hpbGRyZW4uZmluZEluZGV4KChjKSA9PiBjLmVuYWJsZWQgJiYgYy5wZW5kaW5nKSAhPT0gLTEpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0IGVtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5fZW5hYmxlZDtcbiAgfVxuXG4gIGdldCB0b3VjaGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRvdWNoZWRTdWJqZWN0LnZhbHVlIHx8ICh0aGlzLl9jaGlsZHJlbiAmJiB0aGlzLl9jaGlsZHJlbi5maW5kSW5kZXgoKGMpID0+IGMuZW5hYmxlZCAmJiBjLnRvdWNoZWQpICE9PSAtMSkgfHwgZmFsc2U7XG4gIH1cblxuICBnZXQgdW50b3VjaGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoIXRoaXMudG91Y2hlZFN1YmplY3QudmFsdWUgJiYgKCF0aGlzLl9jaGlsZHJlbiB8fCB0aGlzLl9jaGlsZHJlbi5maW5kSW5kZXgoKGMpID0+IGMuZW5hYmxlZCAmJiBjLnRvdWNoZWQpID09PSAtMSkpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0IGVuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VuYWJsZWQ7XG4gIH1cblxuICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLl9lbmFibGVkO1xuICB9XG5cbiAgZ2V0IGRlc3Ryb3llZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kZXN0cm95U3ViamVjdD8uY2xvc2VkICE9PSBmYWxzZTtcbiAgfVxuXG4gIEBJbnB1dCgpIGRlYnVnID0gZmFsc2U7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgLy8gQ2FuIGJlIG92ZXJyaWRlIGJ5IHN1YiBjbGFzc2VzXG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcblxuICAgIHRoaXMucmVhZHlTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5sb2FkaW5nU3ViamVjdC51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudG91Y2hlZFN1YmplY3QudW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmVycm9yU3ViamVjdC51bnN1YnNjcmliZSgpO1xuXG4gICAgdGhpcy5kZXN0cm95U3ViamVjdC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95U3ViamVjdC51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgYWRkRm9ybShwYXRoOiBzdHJpbmcsIGZvcm0/OiBJQXBwRm9ybSB8IElBcHBGb3JtR2V0dGVyKSB7XG4gICAgaWYgKCFmb3JtKSB0aHJvdyBuZXcgRXJyb3IoJ1RyeWluZyB0byByZWdpc3RlciBhbiB1bmRlZmluZWQgY2hpbGQgZm9ybScpO1xuICAgIHRoaXMuX2NoaWxkcmVuID0gdGhpcy5fY2hpbGRyZW4gfHwgW107XG4gICAgaWYgKHR5cGVvZiBmb3JtID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLl9jaGlsZHJlbi5wdXNoKG5ldyBBcHBGb3JtUHJvdmlkZXIoZm9ybSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9jaGlsZHJlbi5wdXNoKGZvcm0pO1xuICAgIH1cbiAgICB0aGlzLl9jaGlsZHJlblBhdGggPSB0aGlzLl9jaGlsZHJlblBhdGggfHwgW107XG4gICAgdGhpcy5fY2hpbGRyZW5QYXRoLnB1c2gocGF0aCB8fCBudWxsKTtcbiAgfVxuXG4gIGFkZEZvcm1zKGZvcm1zOiAoSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcilbXSkge1xuICAgIChmb3JtcyB8fCBbXSkuZm9yRWFjaCgoZm9ybSkgPT4gdGhpcy5hZGRGb3JtKG51bGwsIGZvcm0pKTtcbiAgfVxuXG4gIHJlbW92ZUZvcm0oZm9ybTogc3RyaW5nIHwgSUFwcEZvcm0gfCBJQXBwRm9ybUdldHRlcik6IElBcHBGb3JtIHwgSUFwcEZvcm1HZXR0ZXIge1xuICAgIGlmICghZm9ybSkgdGhyb3cgbmV3IEVycm9yKCdUcnlpbmcgdG8gcmVtb3ZlIGFuIHVuZGVmaW5lZCBjaGlsZCBmb3JtJyk7XG4gICAgY29uc3QgaW5kZXggPVxuICAgICAgdHlwZW9mIGZvcm0gPT0gJ3N0cmluZycgPyAodGhpcy5fY2hpbGRyZW5QYXRoIHx8IFtdKS5maW5kSW5kZXgoKGMpID0+IGMgPT09IGZvcm0pIDogKHRoaXMuX2NoaWxkcmVuIHx8IFtdKS5maW5kSW5kZXgoKGMpID0+IGMgPT09IGZvcm0pO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuX2NoaWxkcmVuUGF0aC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgcmV0dXJuIHRoaXMuX2NoaWxkcmVuLnNwbGljZShpbmRleCwgMSk/LlswXTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGRpc2FibGUob3B0cz86IHsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICB0aGlzLl9lbmFibGVkID0gZmFsc2U7XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goKGMpID0+IGMuZGlzYWJsZShvcHRzKSk7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBlbmFibGUob3B0cz86IHsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICB0aGlzLl9lbmFibGVkID0gdHJ1ZTtcbiAgICB0aGlzLl9jaGlsZHJlbj8uZm9yRWFjaCgoYykgPT4gYy5lbmFibGUob3B0cykpO1xuICAgIGlmICghdGhpcy5sb2FkaW5nICYmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgbWFya0FzUHJpc3RpbmUob3B0cz86IHsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICB0aGlzLmVycm9yID0gbnVsbDtcbiAgICBpZiAodGhpcy5kaXJ0eVN1YmplY3QudmFsdWUgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLmRpcnR5U3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICB9XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goKGMpID0+IGMubWFya0FzUHJpc3RpbmUob3B0cykpO1xuICAgIGlmICghdGhpcy5sb2FkaW5nICYmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgbWFya0FzVW50b3VjaGVkKG9wdHM/OiB7IG9ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgaWYgKHRoaXMudG91Y2hlZFN1YmplY3QudmFsdWUgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLnRvdWNoZWRTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLl9jaGlsZHJlbj8uZm9yRWFjaCgoYykgPT4gYy5tYXJrQXNVbnRvdWNoZWQoKSk7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgcHJlZmVyIHRvIHVzZSBtYXJrQWxsQXNUb3VjaGVkKClcbiAgICogQHBhcmFtIG9wdHNcbiAgICovXG4gIG1hcmtBc1RvdWNoZWQob3B0cz86IHsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICBpZiAoIXRoaXMudG91Y2hlZFN1YmplY3QudmFsdWUgIT09IHRydWUpIHtcbiAgICAgIHRoaXMudG91Y2hlZFN1YmplY3QubmV4dCh0cnVlKTtcbiAgICB9XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goKGMpID0+IGMubWFya0FzVG91Y2hlZChvcHRzKSk7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmcgJiYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkpIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBtYXJrQWxsQXNUb3VjaGVkKG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICh0aGlzLnRvdWNoZWRTdWJqZWN0LnZhbHVlICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLnRvdWNoZWRTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMuX2NoaWxkcmVuPy5mb3JFYWNoKChjKSA9PiBjLm1hcmtBbGxBc1RvdWNoZWQob3B0cykpO1xuICAgIGlmICghdGhpcy5sb2FkaW5nICYmICghb3B0cyB8fCBvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgbWFya0FzRGlydHkob3B0cz86IHsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICBpZiAodGhpcy5kaXJ0eVN1YmplY3QudmFsdWUgIT09IHRydWUpIHtcbiAgICAgIHRoaXMuZGlydHlTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICBpZiAoIXRoaXMubG9hZGluZyAmJiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSkgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBtYXJrQXNMb2FkaW5nKG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICghdGhpcy5sb2FkaW5nU3ViamVjdC5jbG9zZWQgJiYgdGhpcy5sb2FkaW5nU3ViamVjdC52YWx1ZSAhPT0gdHJ1ZSkge1xuICAgICAgdGhpcy5sb2FkaW5nU3ViamVjdC5uZXh0KHRydWUpO1xuXG4gICAgICBpZiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbWFya0FzTG9hZGVkKG9wdHM/OiB7IG9ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmdTdWJqZWN0LmNsb3NlZCAmJiB0aGlzLmxvYWRpbmdTdWJqZWN0LnZhbHVlICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5sb2FkaW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIGlmICghb3B0cyB8fCBvcHRzLm9ubHlTZWxmICE9PSB0cnVlKSB7XG4gICAgICAgIC8vIEVtaXQgdG8gY2hpbGRyZW4gZm9ybXMgYW5kIGVkaXRvcnNcbiAgICAgICAgLy8gbm90ZTogdGFibGVzIHNob3VsZCBiZSBjaGFuZ2VkIGJ5IHBhcmVudFxuICAgICAgICB0aGlzLmZvcm1zPy5mb3JFYWNoKChmKSA9PiBmLm1hcmtBc0xvYWRlZChvcHRzKSk7XG4gICAgICAgIHRoaXMuZWRpdG9ycz8uZm9yRWFjaCgoZSkgPT4gZS5tYXJrQXNMb2FkZWQob3B0cykpO1xuICAgICAgfVxuICAgICAgaWYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSkge1xuICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG1hcmtBc1JlYWR5KG9wdHM/OiB7IG9ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5fY2hpbGRyZW4/LmZvckVhY2goKGMpID0+IGMubWFya0FzUmVhZHkob3B0cykpO1xuICAgIGlmICghdGhpcy5yZWFkeVN1YmplY3QuY2xvc2VkICYmIHRoaXMucmVhZHlTdWJqZWN0LnZhbHVlICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLnJlYWR5U3ViamVjdC5uZXh0KHRydWUpO1xuXG4gICAgICAvLyBJZiBzdWJjbGFzc2VzIGltcGxlbWVudHMgT25SZWFkeVxuICAgICAgaWYgKHR5cGVvZiB0aGlzWyduZ09uUmVhZHknXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAodGhpcyBhcyBhbnkgYXMgT25SZWFkeSkubmdPblJlYWR5KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdhaXQgZm9ybSBpcyByZWFkeVxuICAgKlxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgcmVhZHkob3B0cz86IFdhaXRGb3JPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMucmVhZHlTdWJqZWN0LnZhbHVlKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgcmV0dXJuIHdhaXRGb3JUcnVlKHRoaXMucmVhZHlTdWJqZWN0LCB7IHN0b3A6IHRoaXMuZGVzdHJveVN1YmplY3QsIC4uLm9wdHMgfSk7XG4gIH1cblxuICAvKipcbiAgICogV2FpdCBmb3JtIGlzIG5vdCBidXN5ICg9bG9hZGVkKVxuICAgKlxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgd2FpdElkbGUob3B0cz86IFdhaXRGb3JPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmxvYWRpbmdTdWJqZWN0LnZhbHVlKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgcmV0dXJuIHdhaXRGb3JGYWxzZSh0aGlzLmxvYWRpbmdTdWJqZWN0LCB7IHN0b3A6IHRoaXMuZGVzdHJveVN1YmplY3QsIC4uLm9wdHMgfSk7XG4gIH1cblxuICBsb2dGb3JtRXJyb3JzKHByZWZpeD86IHN0cmluZykge1xuICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmRlYnVnKCdbZWRpdG9yXSBFZGl0b3Igbm90IHZhbGlkLiBDaGVja2luZyB3aGVyZSAoZm9ybXMsIHRhYmxlcykuLi4nKTtcbiAgICB0aGlzLl9jaGlsZHJlbj8uZm9yRWFjaCgoYykgPT4gdGhpcy5sb2dDaGlsZHJlbkVycm9ycyhjLCBwcmVmaXgpKTtcbiAgfVxuXG4gIC8qIC0tIHByb3RlY3RlZCBtZXRob2RzIC0tICovXG5cbiAgcHJvdGVjdGVkIHJlZ2lzdGVyU3Vic2NyaXB0aW9uKHN1YjogU3Vic2NyaXB0aW9uKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChzdWIpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHVucmVnaXN0ZXJTdWJzY3JpcHRpb24oc3ViOiBTdWJzY3JpcHRpb24pOiB2b2lkIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24ucmVtb3ZlKHN1Yik7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0RXJyb3IodmFsdWU6IHN0cmluZywgb3B0cz86IHsgZW1pdEV2ZW50PzogYm9vbGVhbiB9KSB7XG4gICAgLy8gQ29tcGFyZSB1c2luZyAnIT0nIHRvIGRldGVjdCBudWxsIGFuZCB1bmRlZmluZWQgYXMgc2FtZSB2YWx1ZVxuICAgIGlmICh0aGlzLmVycm9yU3ViamVjdC52YWx1ZSAhPSB2YWx1ZSkge1xuICAgICAgdGhpcy5lcnJvclN1YmplY3QubmV4dCh2YWx1ZSk7XG4gICAgICBpZiAoIW9wdHMgfHwgb3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCByZXNldEVycm9yKG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuc2V0RXJyb3IodW5kZWZpbmVkLCBvcHRzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBtYXJrRm9yQ2hlY2soKSB7XG4gICAgLy8gU2hvdWxkIGJlIG92ZXJ3cml0dGVuIGJ5IHN1YmNsYXNzZXNcbiAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS53YXJuKCdtYXJrRm9yQ2hlY2soKSBoYXMgYmVlbiBjYWxsZWQsIGJ1dCBpcyBub3Qgb3ZlcndyaXR0ZW4gYnkgY29tcG9uZW50ICcgKyB0aGlzLmNvbnN0cnVjdG9yLm5hbWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGxvZ0NoaWxkcmVuRXJyb3JzKGM6IElBcHBGb3JtIHwgQWJzdHJhY3RDb250cm9sLCBwcmVmaXg/OiBzdHJpbmcsIHBhdGg/OiBzdHJpbmcpIHtcbiAgICBwcmVmaXggPSBwcmVmaXggfHwgdGhpcy5fbG9nUHJlZml4O1xuICAgIC8vIElmIGVkaXRvclxuICAgIGlmIChjIGluc3RhbmNlb2YgQXBwRWRpdG9yKSB7XG4gICAgICBpZiAoIWMuZW1wdHkgJiYgIWMudmFsaWQpIHtcbiAgICAgICAgaWYgKGMucGVuZGluZykge1xuICAgICAgICAgIGNvbnN0IHBhdGggPSBjLmNvbnN0cnVjdG9yLm5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYCR7cHJlZml4fSAtPiAke3BhdGh9OiB3YWl0aW5nIHdoaWxlIHBlbmRpbmcuLi5gKTtcbiAgICAgICAgICBBcHBGb3JtVXRpbHMud2FpdFdoaWxlUGVuZGluZyhjLCB7IHRpbWVvdXQ6IDEwMDAgfSkudGhlbigoKSA9PiBjLmxvZ0Zvcm1FcnJvcnMocHJlZml4KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYy5sb2dGb3JtRXJyb3JzKHByZWZpeCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQW5ndWxhciBmb3JtIGNvbnRyb2xcbiAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgQWJzdHJhY3RDb250cm9sKSB7XG4gICAgICBBcHBGb3JtVXRpbHMubG9nRm9ybUVycm9ycyhjLCBwcmVmaXgsIHBhdGgpO1xuICAgIH1cbiAgICAvLyBJZiBmb3JtIHByb3ZpZGVyOiBnZXQgZGVsZWdhdGVcbiAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgQXBwRm9ybVByb3ZpZGVyKSB7XG4gICAgICBpZiAoIWMuZW1wdHkgJiYgIWMudmFsaWQpIHtcbiAgICAgICAgYy53YWl0RGVsZWdhdGUoeyB0aW1lb3V0OiAxMDAwIH0pLnRoZW4oKGRlbGVnYXRlKSA9PiB0aGlzLmxvZ0NoaWxkcmVuRXJyb3JzKGRlbGVnYXRlLCBwcmVmaXgsICdwcm92aWRlcicpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gSWYgdGFibGVcbiAgICBlbHNlIGlmIChjIGluc3RhbmNlb2YgQXBwVGFibGUpIHtcbiAgICAgIGlmIChjLmludmFsaWQgJiYgYy5lZGl0ZWRSb3cgJiYgYy5lZGl0ZWRSb3cudmFsaWRhdG9yKSB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBjLmNvbnN0cnVjdG9yLm5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgQXBwRm9ybVV0aWxzLmxvZ0Zvcm1FcnJvcnMoYy5lZGl0ZWRSb3cudmFsaWRhdG9yLCBwcmVmaXgsIHBhdGgpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiBmb3JtXG4gICAgZWxzZSBpZiAoYyBpbnN0YW5jZW9mIEFwcEZvcm0pIHtcbiAgICAgIGlmICghYy5lbXB0eSAmJiAhYy52YWxpZCkge1xuICAgICAgICBpZiAoYy5wZW5kaW5nKSB7XG4gICAgICAgICAgY29uc3QgcGF0aCA9IGMuY29uc3RydWN0b3IubmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgIGNvbnNvbGUud2FybihgJHtwcmVmaXh9IC0+ICR7cGF0aH06IHdhaXRpbmcgd2hpbGUgcGVuZGluZy4uLmApO1xuICAgICAgICAgIEFwcEZvcm1VdGlscy53YWl0V2hpbGVQZW5kaW5nKGMsIHsgdGltZW91dDogMTAwMCB9KS50aGVuKCgpID0+IHRoaXMubG9nQ2hpbGRyZW5FcnJvcnMoYy5mb3JtLCBwcmVmaXgsIHBhdGgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBBcHBGb3JtVXRpbHMubG9nRm9ybUVycm9ycyhjLmZvcm0sIHByZWZpeCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKGAke3ByZWZpeH0gVW5rbm93biBjaGlsZHJlbiBzdWItZm9ybTogYCwgYyk7XG4gICAgfVxuICB9XG59XG4iXX0=
|