@ngrx/store-devtools 18.1.0 → 19.0.0-beta.0
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/fesm2022/ngrx-store-devtools.mjs +13 -13
- package/fesm2022/ngrx-store-devtools.mjs.map +1 -1
- package/package.json +3 -5
- package/schematics-core/utility/libs-version.js +1 -1
- package/schematics-core/utility/libs-version.js.map +1 -1
- package/schematics-core/utility/visitors.js +2 -2
- package/esm2022/index.mjs +0 -7
- package/esm2022/ngrx-store-devtools.mjs +0 -5
- package/esm2022/public_api.mjs +0 -2
- package/esm2022/src/actions.mjs +0 -97
- package/esm2022/src/config.mjs +0 -69
- package/esm2022/src/devtools-dispatcher.mjs +0 -11
- package/esm2022/src/devtools.mjs +0 -143
- package/esm2022/src/extension.mjs +0 -172
- package/esm2022/src/index.mjs +0 -7
- package/esm2022/src/instrument.mjs +0 -22
- package/esm2022/src/provide-store-devtools.mjs +0 -72
- package/esm2022/src/reducer.mjs +0 -368
- package/esm2022/src/utils.mjs +0 -114
- package/esm2022/src/zone-config.mjs +0 -6
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { provideStoreDevtools } from './provide-store-devtools';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
export function createStateObservable(devtools) {
|
|
5
|
-
return devtools.state;
|
|
6
|
-
}
|
|
7
|
-
export class StoreDevtoolsModule {
|
|
8
|
-
static instrument(options = {}) {
|
|
9
|
-
return {
|
|
10
|
-
ngModule: StoreDevtoolsModule,
|
|
11
|
-
providers: [provideStoreDevtools(options)],
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: StoreDevtoolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
15
|
-
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.5", ngImport: i0, type: StoreDevtoolsModule }); }
|
|
16
|
-
/** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: StoreDevtoolsModule }); }
|
|
17
|
-
}
|
|
18
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: StoreDevtoolsModule, decorators: [{
|
|
19
|
-
type: NgModule,
|
|
20
|
-
args: [{}]
|
|
21
|
-
}] });
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdHJ1bWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL21vZHVsZXMvc3RvcmUtZGV2dG9vbHMvc3JjL2luc3RydW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUF1QixRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFJOUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7O0FBRWhFLE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsUUFBdUI7SUFFdkIsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDO0FBQ3hCLENBQUM7QUFHRCxNQUFNLE9BQU8sbUJBQW1CO0lBQzlCLE1BQU0sQ0FBQyxVQUFVLENBQ2YsVUFBZ0MsRUFBRTtRQUVsQyxPQUFPO1lBQ0wsUUFBUSxFQUFFLG1CQUFtQjtZQUM3QixTQUFTLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUMzQyxDQUFDO0lBQ0osQ0FBQztpSUFSVSxtQkFBbUI7a0lBQW5CLG1CQUFtQjtrSUFBbkIsbUJBQW1COzsyRkFBbkIsbUJBQW1CO2tCQUQvQixRQUFRO21CQUFDLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzLCBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3RhdGVPYnNlcnZhYmxlIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xuaW1wb3J0IHsgU3RvcmVEZXZ0b29sc09wdGlvbnMgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBTdG9yZURldnRvb2xzIH0gZnJvbSAnLi9kZXZ0b29scyc7XG5pbXBvcnQgeyBwcm92aWRlU3RvcmVEZXZ0b29scyB9IGZyb20gJy4vcHJvdmlkZS1zdG9yZS1kZXZ0b29scyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTdGF0ZU9ic2VydmFibGUoXG4gIGRldnRvb2xzOiBTdG9yZURldnRvb2xzXG4pOiBTdGF0ZU9ic2VydmFibGUge1xuICByZXR1cm4gZGV2dG9vbHMuc3RhdGU7XG59XG5cbkBOZ01vZHVsZSh7fSlcbmV4cG9ydCBjbGFzcyBTdG9yZURldnRvb2xzTW9kdWxlIHtcbiAgc3RhdGljIGluc3RydW1lbnQoXG4gICAgb3B0aW9uczogU3RvcmVEZXZ0b29sc09wdGlvbnMgPSB7fVxuICApOiBNb2R1bGVXaXRoUHJvdmlkZXJzPFN0b3JlRGV2dG9vbHNNb2R1bGU+IHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IFN0b3JlRGV2dG9vbHNNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFtwcm92aWRlU3RvcmVEZXZ0b29scyhvcHRpb25zKV0sXG4gICAgfTtcbiAgfVxufVxuIl19
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { InjectionToken, makeEnvironmentProviders, } from '@angular/core';
|
|
2
|
-
import { DevtoolsExtension, REDUX_DEVTOOLS_EXTENSION, } from './extension';
|
|
3
|
-
import { DevtoolsDispatcher } from './devtools-dispatcher';
|
|
4
|
-
import { createConfig, INITIAL_OPTIONS, noMonitor, STORE_DEVTOOLS_CONFIG, } from './config';
|
|
5
|
-
import { ReducerManagerDispatcher, StateObservable } from '@ngrx/store';
|
|
6
|
-
import { createStateObservable } from './instrument';
|
|
7
|
-
import { StoreDevtools } from './devtools';
|
|
8
|
-
export const IS_EXTENSION_OR_MONITOR_PRESENT = new InjectionToken('@ngrx/store-devtools Is Devtools Extension or Monitor Present');
|
|
9
|
-
export function createIsExtensionOrMonitorPresent(extension, config) {
|
|
10
|
-
return Boolean(extension) || config.monitor !== noMonitor;
|
|
11
|
-
}
|
|
12
|
-
export function createReduxDevtoolsExtension() {
|
|
13
|
-
const extensionKey = '__REDUX_DEVTOOLS_EXTENSION__';
|
|
14
|
-
if (typeof window === 'object' &&
|
|
15
|
-
typeof window[extensionKey] !== 'undefined') {
|
|
16
|
-
return window[extensionKey];
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Provides developer tools and instrumentation for `Store`.
|
|
24
|
-
*
|
|
25
|
-
* @usageNotes
|
|
26
|
-
*
|
|
27
|
-
* ```ts
|
|
28
|
-
* bootstrapApplication(AppComponent, {
|
|
29
|
-
* providers: [
|
|
30
|
-
* provideStoreDevtools({
|
|
31
|
-
* maxAge: 25,
|
|
32
|
-
* logOnly: !isDevMode(),
|
|
33
|
-
* }),
|
|
34
|
-
* ],
|
|
35
|
-
* });
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export function provideStoreDevtools(options = {}) {
|
|
39
|
-
return makeEnvironmentProviders([
|
|
40
|
-
DevtoolsExtension,
|
|
41
|
-
DevtoolsDispatcher,
|
|
42
|
-
StoreDevtools,
|
|
43
|
-
{
|
|
44
|
-
provide: INITIAL_OPTIONS,
|
|
45
|
-
useValue: options,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
provide: IS_EXTENSION_OR_MONITOR_PRESENT,
|
|
49
|
-
deps: [REDUX_DEVTOOLS_EXTENSION, STORE_DEVTOOLS_CONFIG],
|
|
50
|
-
useFactory: createIsExtensionOrMonitorPresent,
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
provide: REDUX_DEVTOOLS_EXTENSION,
|
|
54
|
-
useFactory: createReduxDevtoolsExtension,
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
provide: STORE_DEVTOOLS_CONFIG,
|
|
58
|
-
deps: [INITIAL_OPTIONS],
|
|
59
|
-
useFactory: createConfig,
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
provide: StateObservable,
|
|
63
|
-
deps: [StoreDevtools],
|
|
64
|
-
useFactory: createStateObservable,
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
provide: ReducerManagerDispatcher,
|
|
68
|
-
useExisting: DevtoolsDispatcher,
|
|
69
|
-
},
|
|
70
|
-
]);
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZS1zdG9yZS1kZXZ0b29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL21vZHVsZXMvc3RvcmUtZGV2dG9vbHMvc3JjL3Byb3ZpZGUtc3RvcmUtZGV2dG9vbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLGNBQWMsRUFDZCx3QkFBd0IsR0FFekIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLGlCQUFpQixFQUNqQix3QkFBd0IsR0FFekIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDM0QsT0FBTyxFQUNMLFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUNULHFCQUFxQixHQUd0QixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTNDLE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLElBQUksY0FBYyxDQUMvRCwrREFBK0QsQ0FDaEUsQ0FBQztBQUVGLE1BQU0sVUFBVSxpQ0FBaUMsQ0FDL0MsU0FBd0MsRUFDeEMsTUFBMkI7SUFFM0IsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUM7QUFDNUQsQ0FBQztBQUVELE1BQU0sVUFBVSw0QkFBNEI7SUFDMUMsTUFBTSxZQUFZLEdBQUcsOEJBQThCLENBQUM7SUFFcEQsSUFDRSxPQUFPLE1BQU0sS0FBSyxRQUFRO1FBQzFCLE9BQVEsTUFBYyxDQUFDLFlBQVksQ0FBQyxLQUFLLFdBQVcsRUFDcEQsQ0FBQztRQUNELE9BQVEsTUFBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FDbEMsVUFBZ0MsRUFBRTtJQUVsQyxPQUFPLHdCQUF3QixDQUFDO1FBQzlCLGlCQUFpQjtRQUNqQixrQkFBa0I7UUFDbEIsYUFBYTtRQUNiO1lBQ0UsT0FBTyxFQUFFLGVBQWU7WUFDeEIsUUFBUSxFQUFFLE9BQU87U0FDbEI7UUFDRDtZQUNFLE9BQU8sRUFBRSwrQkFBK0I7WUFDeEMsSUFBSSxFQUFFLENBQUMsd0JBQXdCLEVBQUUscUJBQXFCLENBQUM7WUFDdkQsVUFBVSxFQUFFLGlDQUFpQztTQUM5QztRQUNEO1lBQ0UsT0FBTyxFQUFFLHdCQUF3QjtZQUNqQyxVQUFVLEVBQUUsNEJBQTRCO1NBQ3pDO1FBQ0Q7WUFDRSxPQUFPLEVBQUUscUJBQXFCO1lBQzlCLElBQUksRUFBRSxDQUFDLGVBQWUsQ0FBQztZQUN2QixVQUFVLEVBQUUsWUFBWTtTQUN6QjtRQUNEO1lBQ0UsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDO1lBQ3JCLFVBQVUsRUFBRSxxQkFBcUI7U0FDbEM7UUFDRDtZQUNFLE9BQU8sRUFBRSx3QkFBd0I7WUFDakMsV0FBVyxFQUFFLGtCQUFrQjtTQUNoQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBFbnZpcm9ubWVudFByb3ZpZGVycyxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyxcbiAgUHJvdmlkZXIsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgRGV2dG9vbHNFeHRlbnNpb24sXG4gIFJFRFVYX0RFVlRPT0xTX0VYVEVOU0lPTixcbiAgUmVkdXhEZXZ0b29sc0V4dGVuc2lvbixcbn0gZnJvbSAnLi9leHRlbnNpb24nO1xuaW1wb3J0IHsgRGV2dG9vbHNEaXNwYXRjaGVyIH0gZnJvbSAnLi9kZXZ0b29scy1kaXNwYXRjaGVyJztcbmltcG9ydCB7XG4gIGNyZWF0ZUNvbmZpZyxcbiAgSU5JVElBTF9PUFRJT05TLFxuICBub01vbml0b3IsXG4gIFNUT1JFX0RFVlRPT0xTX0NPTkZJRyxcbiAgU3RvcmVEZXZ0b29sc0NvbmZpZyxcbiAgU3RvcmVEZXZ0b29sc09wdGlvbnMsXG59IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IFJlZHVjZXJNYW5hZ2VyRGlzcGF0Y2hlciwgU3RhdGVPYnNlcnZhYmxlIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xuaW1wb3J0IHsgY3JlYXRlU3RhdGVPYnNlcnZhYmxlIH0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFN0b3JlRGV2dG9vbHMgfSBmcm9tICcuL2RldnRvb2xzJztcblxuZXhwb3J0IGNvbnN0IElTX0VYVEVOU0lPTl9PUl9NT05JVE9SX1BSRVNFTlQgPSBuZXcgSW5qZWN0aW9uVG9rZW48Ym9vbGVhbj4oXG4gICdAbmdyeC9zdG9yZS1kZXZ0b29scyBJcyBEZXZ0b29scyBFeHRlbnNpb24gb3IgTW9uaXRvciBQcmVzZW50J1xuKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUlzRXh0ZW5zaW9uT3JNb25pdG9yUHJlc2VudChcbiAgZXh0ZW5zaW9uOiBSZWR1eERldnRvb2xzRXh0ZW5zaW9uIHwgbnVsbCxcbiAgY29uZmlnOiBTdG9yZURldnRvb2xzQ29uZmlnXG4pIHtcbiAgcmV0dXJuIEJvb2xlYW4oZXh0ZW5zaW9uKSB8fCBjb25maWcubW9uaXRvciAhPT0gbm9Nb25pdG9yO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVkdXhEZXZ0b29sc0V4dGVuc2lvbigpIHtcbiAgY29uc3QgZXh0ZW5zaW9uS2V5ID0gJ19fUkVEVVhfREVWVE9PTFNfRVhURU5TSU9OX18nO1xuXG4gIGlmIChcbiAgICB0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiAod2luZG93IGFzIGFueSlbZXh0ZW5zaW9uS2V5XSAhPT0gJ3VuZGVmaW5lZCdcbiAgKSB7XG4gICAgcmV0dXJuICh3aW5kb3cgYXMgYW55KVtleHRlbnNpb25LZXldO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogUHJvdmlkZXMgZGV2ZWxvcGVyIHRvb2xzIGFuZCBpbnN0cnVtZW50YXRpb24gZm9yIGBTdG9yZWAuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiBgYGB0c1xuICogYm9vdHN0cmFwQXBwbGljYXRpb24oQXBwQ29tcG9uZW50LCB7XG4gKiAgIHByb3ZpZGVyczogW1xuICogICAgIHByb3ZpZGVTdG9yZURldnRvb2xzKHtcbiAqICAgICAgIG1heEFnZTogMjUsXG4gKiAgICAgICBsb2dPbmx5OiAhaXNEZXZNb2RlKCksXG4gKiAgICAgfSksXG4gKiAgIF0sXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVN0b3JlRGV2dG9vbHMoXG4gIG9wdGlvbnM6IFN0b3JlRGV2dG9vbHNPcHRpb25zID0ge31cbik6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gICAgRGV2dG9vbHNFeHRlbnNpb24sXG4gICAgRGV2dG9vbHNEaXNwYXRjaGVyLFxuICAgIFN0b3JlRGV2dG9vbHMsXG4gICAge1xuICAgICAgcHJvdmlkZTogSU5JVElBTF9PUFRJT05TLFxuICAgICAgdXNlVmFsdWU6IG9wdGlvbnMsXG4gICAgfSxcbiAgICB7XG4gICAgICBwcm92aWRlOiBJU19FWFRFTlNJT05fT1JfTU9OSVRPUl9QUkVTRU5ULFxuICAgICAgZGVwczogW1JFRFVYX0RFVlRPT0xTX0VYVEVOU0lPTiwgU1RPUkVfREVWVE9PTFNfQ09ORklHXSxcbiAgICAgIHVzZUZhY3Rvcnk6IGNyZWF0ZUlzRXh0ZW5zaW9uT3JNb25pdG9yUHJlc2VudCxcbiAgICB9LFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IFJFRFVYX0RFVlRPT0xTX0VYVEVOU0lPTixcbiAgICAgIHVzZUZhY3Rvcnk6IGNyZWF0ZVJlZHV4RGV2dG9vbHNFeHRlbnNpb24sXG4gICAgfSxcbiAgICB7XG4gICAgICBwcm92aWRlOiBTVE9SRV9ERVZUT09MU19DT05GSUcsXG4gICAgICBkZXBzOiBbSU5JVElBTF9PUFRJT05TXSxcbiAgICAgIHVzZUZhY3Rvcnk6IGNyZWF0ZUNvbmZpZyxcbiAgICB9LFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IFN0YXRlT2JzZXJ2YWJsZSxcbiAgICAgIGRlcHM6IFtTdG9yZURldnRvb2xzXSxcbiAgICAgIHVzZUZhY3Rvcnk6IGNyZWF0ZVN0YXRlT2JzZXJ2YWJsZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IFJlZHVjZXJNYW5hZ2VyRGlzcGF0Y2hlcixcbiAgICAgIHVzZUV4aXN0aW5nOiBEZXZ0b29sc0Rpc3BhdGNoZXIsXG4gICAgfSxcbiAgXSk7XG59XG4iXX0=
|
package/esm2022/src/reducer.mjs
DELETED
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
import { UPDATE, INIT } from '@ngrx/store';
|
|
2
|
-
import { difference, liftAction, isActionFiltered } from './utils';
|
|
3
|
-
import * as DevtoolsActions from './actions';
|
|
4
|
-
import { PerformAction } from './actions';
|
|
5
|
-
export const INIT_ACTION = { type: INIT };
|
|
6
|
-
export const RECOMPUTE = '@ngrx/store-devtools/recompute';
|
|
7
|
-
export const RECOMPUTE_ACTION = { type: RECOMPUTE };
|
|
8
|
-
/**
|
|
9
|
-
* Computes the next entry in the log by applying an action.
|
|
10
|
-
*/
|
|
11
|
-
function computeNextEntry(reducer, action, state, error, errorHandler) {
|
|
12
|
-
if (error) {
|
|
13
|
-
return {
|
|
14
|
-
state,
|
|
15
|
-
error: 'Interrupted by an error up the chain',
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
let nextState = state;
|
|
19
|
-
let nextError;
|
|
20
|
-
try {
|
|
21
|
-
nextState = reducer(state, action);
|
|
22
|
-
}
|
|
23
|
-
catch (err) {
|
|
24
|
-
nextError = err.toString();
|
|
25
|
-
errorHandler.handleError(err);
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
state: nextState,
|
|
29
|
-
error: nextError,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Runs the reducer on invalidated actions to get a fresh computation log.
|
|
34
|
-
*/
|
|
35
|
-
function recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused) {
|
|
36
|
-
// Optimization: exit early and return the same reference
|
|
37
|
-
// if we know nothing could have changed.
|
|
38
|
-
if (minInvalidatedStateIndex >= computedStates.length &&
|
|
39
|
-
computedStates.length === stagedActionIds.length) {
|
|
40
|
-
return computedStates;
|
|
41
|
-
}
|
|
42
|
-
const nextComputedStates = computedStates.slice(0, minInvalidatedStateIndex);
|
|
43
|
-
// If the recording is paused, recompute all states up until the pause state,
|
|
44
|
-
// else recompute all states.
|
|
45
|
-
const lastIncludedActionId = stagedActionIds.length - (isPaused ? 1 : 0);
|
|
46
|
-
for (let i = minInvalidatedStateIndex; i < lastIncludedActionId; i++) {
|
|
47
|
-
const actionId = stagedActionIds[i];
|
|
48
|
-
const action = actionsById[actionId].action;
|
|
49
|
-
const previousEntry = nextComputedStates[i - 1];
|
|
50
|
-
const previousState = previousEntry ? previousEntry.state : committedState;
|
|
51
|
-
const previousError = previousEntry ? previousEntry.error : undefined;
|
|
52
|
-
const shouldSkip = skippedActionIds.indexOf(actionId) > -1;
|
|
53
|
-
const entry = shouldSkip
|
|
54
|
-
? previousEntry
|
|
55
|
-
: computeNextEntry(reducer, action, previousState, previousError, errorHandler);
|
|
56
|
-
nextComputedStates.push(entry);
|
|
57
|
-
}
|
|
58
|
-
// If the recording is paused, the last state will not be recomputed,
|
|
59
|
-
// because it's essentially not part of the state history.
|
|
60
|
-
if (isPaused) {
|
|
61
|
-
nextComputedStates.push(computedStates[computedStates.length - 1]);
|
|
62
|
-
}
|
|
63
|
-
return nextComputedStates;
|
|
64
|
-
}
|
|
65
|
-
export function liftInitialState(initialCommittedState, monitorReducer) {
|
|
66
|
-
return {
|
|
67
|
-
monitorState: monitorReducer(undefined, {}),
|
|
68
|
-
nextActionId: 1,
|
|
69
|
-
actionsById: { 0: liftAction(INIT_ACTION) },
|
|
70
|
-
stagedActionIds: [0],
|
|
71
|
-
skippedActionIds: [],
|
|
72
|
-
committedState: initialCommittedState,
|
|
73
|
-
currentStateIndex: 0,
|
|
74
|
-
computedStates: [],
|
|
75
|
-
isLocked: false,
|
|
76
|
-
isPaused: false,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Creates a history state reducer from an app's reducer.
|
|
81
|
-
*/
|
|
82
|
-
export function liftReducerWith(initialCommittedState, initialLiftedState, errorHandler, monitorReducer, options = {}) {
|
|
83
|
-
/**
|
|
84
|
-
* Manages how the history actions modify the history state.
|
|
85
|
-
*/
|
|
86
|
-
return (reducer) => (liftedState, liftedAction) => {
|
|
87
|
-
let { monitorState, actionsById, nextActionId, stagedActionIds, skippedActionIds, committedState, currentStateIndex, computedStates, isLocked, isPaused, } = liftedState || initialLiftedState;
|
|
88
|
-
if (!liftedState) {
|
|
89
|
-
// Prevent mutating initialLiftedState
|
|
90
|
-
actionsById = Object.create(actionsById);
|
|
91
|
-
}
|
|
92
|
-
function commitExcessActions(n) {
|
|
93
|
-
// Auto-commits n-number of excess actions.
|
|
94
|
-
let excess = n;
|
|
95
|
-
let idsToDelete = stagedActionIds.slice(1, excess + 1);
|
|
96
|
-
for (let i = 0; i < idsToDelete.length; i++) {
|
|
97
|
-
if (computedStates[i + 1].error) {
|
|
98
|
-
// Stop if error is found. Commit actions up to error.
|
|
99
|
-
excess = i;
|
|
100
|
-
idsToDelete = stagedActionIds.slice(1, excess + 1);
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
delete actionsById[idsToDelete[i]];
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
skippedActionIds = skippedActionIds.filter((id) => idsToDelete.indexOf(id) === -1);
|
|
108
|
-
stagedActionIds = [0, ...stagedActionIds.slice(excess + 1)];
|
|
109
|
-
committedState = computedStates[excess].state;
|
|
110
|
-
computedStates = computedStates.slice(excess);
|
|
111
|
-
currentStateIndex =
|
|
112
|
-
currentStateIndex > excess ? currentStateIndex - excess : 0;
|
|
113
|
-
}
|
|
114
|
-
function commitChanges() {
|
|
115
|
-
// Consider the last committed state the new starting point.
|
|
116
|
-
// Squash any staged actions into a single committed state.
|
|
117
|
-
actionsById = { 0: liftAction(INIT_ACTION) };
|
|
118
|
-
nextActionId = 1;
|
|
119
|
-
stagedActionIds = [0];
|
|
120
|
-
skippedActionIds = [];
|
|
121
|
-
committedState = computedStates[currentStateIndex].state;
|
|
122
|
-
currentStateIndex = 0;
|
|
123
|
-
computedStates = [];
|
|
124
|
-
}
|
|
125
|
-
// By default, aggressively recompute every state whatever happens.
|
|
126
|
-
// This has O(n) performance, so we'll override this to a sensible
|
|
127
|
-
// value whenever we feel like we don't have to recompute the states.
|
|
128
|
-
let minInvalidatedStateIndex = 0;
|
|
129
|
-
switch (liftedAction.type) {
|
|
130
|
-
case DevtoolsActions.LOCK_CHANGES: {
|
|
131
|
-
isLocked = liftedAction.status;
|
|
132
|
-
minInvalidatedStateIndex = Infinity;
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
case DevtoolsActions.PAUSE_RECORDING: {
|
|
136
|
-
isPaused = liftedAction.status;
|
|
137
|
-
if (isPaused) {
|
|
138
|
-
// Add a pause action to signal the devtools-user the recording is paused.
|
|
139
|
-
// The corresponding state will be overwritten on each update to always contain
|
|
140
|
-
// the latest state (see Actions.PERFORM_ACTION).
|
|
141
|
-
stagedActionIds = [...stagedActionIds, nextActionId];
|
|
142
|
-
actionsById[nextActionId] = new PerformAction({
|
|
143
|
-
type: '@ngrx/devtools/pause',
|
|
144
|
-
}, +Date.now());
|
|
145
|
-
nextActionId++;
|
|
146
|
-
minInvalidatedStateIndex = stagedActionIds.length - 1;
|
|
147
|
-
computedStates = computedStates.concat(computedStates[computedStates.length - 1]);
|
|
148
|
-
if (currentStateIndex === stagedActionIds.length - 2) {
|
|
149
|
-
currentStateIndex++;
|
|
150
|
-
}
|
|
151
|
-
minInvalidatedStateIndex = Infinity;
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
commitChanges();
|
|
155
|
-
}
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
case DevtoolsActions.RESET: {
|
|
159
|
-
// Get back to the state the store was created with.
|
|
160
|
-
actionsById = { 0: liftAction(INIT_ACTION) };
|
|
161
|
-
nextActionId = 1;
|
|
162
|
-
stagedActionIds = [0];
|
|
163
|
-
skippedActionIds = [];
|
|
164
|
-
committedState = initialCommittedState;
|
|
165
|
-
currentStateIndex = 0;
|
|
166
|
-
computedStates = [];
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
case DevtoolsActions.COMMIT: {
|
|
170
|
-
commitChanges();
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
case DevtoolsActions.ROLLBACK: {
|
|
174
|
-
// Forget about any staged actions.
|
|
175
|
-
// Start again from the last committed state.
|
|
176
|
-
actionsById = { 0: liftAction(INIT_ACTION) };
|
|
177
|
-
nextActionId = 1;
|
|
178
|
-
stagedActionIds = [0];
|
|
179
|
-
skippedActionIds = [];
|
|
180
|
-
currentStateIndex = 0;
|
|
181
|
-
computedStates = [];
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
case DevtoolsActions.TOGGLE_ACTION: {
|
|
185
|
-
// Toggle whether an action with given ID is skipped.
|
|
186
|
-
// Being skipped means it is a no-op during the computation.
|
|
187
|
-
const { id: actionId } = liftedAction;
|
|
188
|
-
const index = skippedActionIds.indexOf(actionId);
|
|
189
|
-
if (index === -1) {
|
|
190
|
-
skippedActionIds = [actionId, ...skippedActionIds];
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
skippedActionIds = skippedActionIds.filter((id) => id !== actionId);
|
|
194
|
-
}
|
|
195
|
-
// Optimization: we know history before this action hasn't changed
|
|
196
|
-
minInvalidatedStateIndex = stagedActionIds.indexOf(actionId);
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
case DevtoolsActions.SET_ACTIONS_ACTIVE: {
|
|
200
|
-
// Toggle whether an action with given ID is skipped.
|
|
201
|
-
// Being skipped means it is a no-op during the computation.
|
|
202
|
-
const { start, end, active } = liftedAction;
|
|
203
|
-
const actionIds = [];
|
|
204
|
-
for (let i = start; i < end; i++)
|
|
205
|
-
actionIds.push(i);
|
|
206
|
-
if (active) {
|
|
207
|
-
skippedActionIds = difference(skippedActionIds, actionIds);
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
skippedActionIds = [...skippedActionIds, ...actionIds];
|
|
211
|
-
}
|
|
212
|
-
// Optimization: we know history before this action hasn't changed
|
|
213
|
-
minInvalidatedStateIndex = stagedActionIds.indexOf(start);
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
case DevtoolsActions.JUMP_TO_STATE: {
|
|
217
|
-
// Without recomputing anything, move the pointer that tell us
|
|
218
|
-
// which state is considered the current one. Useful for sliders.
|
|
219
|
-
currentStateIndex = liftedAction.index;
|
|
220
|
-
// Optimization: we know the history has not changed.
|
|
221
|
-
minInvalidatedStateIndex = Infinity;
|
|
222
|
-
break;
|
|
223
|
-
}
|
|
224
|
-
case DevtoolsActions.JUMP_TO_ACTION: {
|
|
225
|
-
// Jumps to a corresponding state to a specific action.
|
|
226
|
-
// Useful when filtering actions.
|
|
227
|
-
const index = stagedActionIds.indexOf(liftedAction.actionId);
|
|
228
|
-
if (index !== -1)
|
|
229
|
-
currentStateIndex = index;
|
|
230
|
-
minInvalidatedStateIndex = Infinity;
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
case DevtoolsActions.SWEEP: {
|
|
234
|
-
// Forget any actions that are currently being skipped.
|
|
235
|
-
stagedActionIds = difference(stagedActionIds, skippedActionIds);
|
|
236
|
-
skippedActionIds = [];
|
|
237
|
-
currentStateIndex = Math.min(currentStateIndex, stagedActionIds.length - 1);
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
case DevtoolsActions.PERFORM_ACTION: {
|
|
241
|
-
// Ignore action and return state as is if recording is locked
|
|
242
|
-
if (isLocked) {
|
|
243
|
-
return liftedState || initialLiftedState;
|
|
244
|
-
}
|
|
245
|
-
if (isPaused ||
|
|
246
|
-
(liftedState &&
|
|
247
|
-
isActionFiltered(liftedState.computedStates[currentStateIndex], liftedAction, options.predicate, options.actionsSafelist, options.actionsBlocklist))) {
|
|
248
|
-
// If recording is paused or if the action should be ignored, overwrite the last state
|
|
249
|
-
// (corresponds to the pause action) and keep everything else as is.
|
|
250
|
-
// This way, the app gets the new current state while the devtools
|
|
251
|
-
// do not record another action.
|
|
252
|
-
const lastState = computedStates[computedStates.length - 1];
|
|
253
|
-
computedStates = [
|
|
254
|
-
...computedStates.slice(0, -1),
|
|
255
|
-
computeNextEntry(reducer, liftedAction.action, lastState.state, lastState.error, errorHandler),
|
|
256
|
-
];
|
|
257
|
-
minInvalidatedStateIndex = Infinity;
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
260
|
-
// Auto-commit as new actions come in.
|
|
261
|
-
if (options.maxAge && stagedActionIds.length === options.maxAge) {
|
|
262
|
-
commitExcessActions(1);
|
|
263
|
-
}
|
|
264
|
-
if (currentStateIndex === stagedActionIds.length - 1) {
|
|
265
|
-
currentStateIndex++;
|
|
266
|
-
}
|
|
267
|
-
const actionId = nextActionId++;
|
|
268
|
-
// Mutation! This is the hottest path, and we optimize on purpose.
|
|
269
|
-
// It is safe because we set a new key in a cache dictionary.
|
|
270
|
-
actionsById[actionId] = liftedAction;
|
|
271
|
-
stagedActionIds = [...stagedActionIds, actionId];
|
|
272
|
-
// Optimization: we know that only the new action needs computing.
|
|
273
|
-
minInvalidatedStateIndex = stagedActionIds.length - 1;
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
case DevtoolsActions.IMPORT_STATE: {
|
|
277
|
-
// Completely replace everything.
|
|
278
|
-
({
|
|
279
|
-
monitorState,
|
|
280
|
-
actionsById,
|
|
281
|
-
nextActionId,
|
|
282
|
-
stagedActionIds,
|
|
283
|
-
skippedActionIds,
|
|
284
|
-
committedState,
|
|
285
|
-
currentStateIndex,
|
|
286
|
-
computedStates,
|
|
287
|
-
isLocked,
|
|
288
|
-
isPaused,
|
|
289
|
-
} = liftedAction.nextLiftedState);
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
case INIT: {
|
|
293
|
-
// Always recompute states on hot reload and init.
|
|
294
|
-
minInvalidatedStateIndex = 0;
|
|
295
|
-
if (options.maxAge && stagedActionIds.length > options.maxAge) {
|
|
296
|
-
// States must be recomputed before committing excess.
|
|
297
|
-
computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
|
|
298
|
-
commitExcessActions(stagedActionIds.length - options.maxAge);
|
|
299
|
-
// Avoid double computation.
|
|
300
|
-
minInvalidatedStateIndex = Infinity;
|
|
301
|
-
}
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
case UPDATE: {
|
|
305
|
-
const stateHasErrors = computedStates.filter((state) => state.error).length > 0;
|
|
306
|
-
if (stateHasErrors) {
|
|
307
|
-
// Recompute all states
|
|
308
|
-
minInvalidatedStateIndex = 0;
|
|
309
|
-
if (options.maxAge && stagedActionIds.length > options.maxAge) {
|
|
310
|
-
// States must be recomputed before committing excess.
|
|
311
|
-
computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
|
|
312
|
-
commitExcessActions(stagedActionIds.length - options.maxAge);
|
|
313
|
-
// Avoid double computation.
|
|
314
|
-
minInvalidatedStateIndex = Infinity;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
// If not paused/locked, add a new action to signal devtools-user
|
|
319
|
-
// that there was a reducer update.
|
|
320
|
-
if (!isPaused && !isLocked) {
|
|
321
|
-
if (currentStateIndex === stagedActionIds.length - 1) {
|
|
322
|
-
currentStateIndex++;
|
|
323
|
-
}
|
|
324
|
-
// Add a new action to only recompute state
|
|
325
|
-
const actionId = nextActionId++;
|
|
326
|
-
actionsById[actionId] = new PerformAction(liftedAction, +Date.now());
|
|
327
|
-
stagedActionIds = [...stagedActionIds, actionId];
|
|
328
|
-
minInvalidatedStateIndex = stagedActionIds.length - 1;
|
|
329
|
-
computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
|
|
330
|
-
}
|
|
331
|
-
// Recompute state history with latest reducer and update action
|
|
332
|
-
computedStates = computedStates.map((cmp) => ({
|
|
333
|
-
...cmp,
|
|
334
|
-
state: reducer(cmp.state, RECOMPUTE_ACTION),
|
|
335
|
-
}));
|
|
336
|
-
currentStateIndex = stagedActionIds.length - 1;
|
|
337
|
-
if (options.maxAge && stagedActionIds.length > options.maxAge) {
|
|
338
|
-
commitExcessActions(stagedActionIds.length - options.maxAge);
|
|
339
|
-
}
|
|
340
|
-
// Avoid double computation.
|
|
341
|
-
minInvalidatedStateIndex = Infinity;
|
|
342
|
-
}
|
|
343
|
-
break;
|
|
344
|
-
}
|
|
345
|
-
default: {
|
|
346
|
-
// If the action is not recognized, it's a monitor action.
|
|
347
|
-
// Optimization: a monitor action can't change history.
|
|
348
|
-
minInvalidatedStateIndex = Infinity;
|
|
349
|
-
break;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
|
|
353
|
-
monitorState = monitorReducer(monitorState, liftedAction);
|
|
354
|
-
return {
|
|
355
|
-
monitorState,
|
|
356
|
-
actionsById,
|
|
357
|
-
nextActionId,
|
|
358
|
-
stagedActionIds,
|
|
359
|
-
skippedActionIds,
|
|
360
|
-
committedState,
|
|
361
|
-
currentStateIndex,
|
|
362
|
-
computedStates,
|
|
363
|
-
isLocked,
|
|
364
|
-
isPaused,
|
|
365
|
-
};
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL21vZHVsZXMvc3RvcmUtZGV2dG9vbHMvc3JjL3JlZHVjZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUF5QixNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWxFLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ25FLE9BQU8sS0FBSyxlQUFlLE1BQU0sV0FBVyxDQUFDO0FBRTdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFhMUMsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO0FBRTFDLE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxnQ0FBeUMsQ0FBQztBQUNuRSxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQztBQTZCcEQ7O0dBRUc7QUFDSCxTQUFTLGdCQUFnQixDQUN2QixPQUFnQyxFQUNoQyxNQUFjLEVBQ2QsS0FBVSxFQUNWLEtBQVUsRUFDVixZQUEwQjtJQUUxQixJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ1YsT0FBTztZQUNMLEtBQUs7WUFDTCxLQUFLLEVBQUUsc0NBQXNDO1NBQzlDLENBQUM7SUFDSixDQUFDO0lBRUQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLElBQUksU0FBUyxDQUFDO0lBQ2QsSUFBSSxDQUFDO1FBQ0gsU0FBUyxHQUFHLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUFDLE9BQU8sR0FBUSxFQUFFLENBQUM7UUFDbEIsU0FBUyxHQUFHLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMzQixZQUFZLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxD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LENBQUMsTUFBTSxJQUFJLGVBQWUsQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO3dCQUM5RCxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDL0QsQ0FBQztvQkFFRCw0QkFBNEI7b0JBQzVCLHdCQUF3QixHQUFHLFFBQVEsQ0FBQztnQkFDdEMsQ0FBQztnQkFFRCxNQUFNO1lBQ1IsQ0FBQztZQUNELE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ1IsMERBQTBEO2dCQUMxRCx1REFBdUQ7Z0JBQ3ZELHdCQUF3QixHQUFHLFFBQVEsQ0FBQztnQkFDcEMsTUFBTTtZQUNSLENBQUM7UUFDSCxDQUFDO1FBRUQsY0FBYyxHQUFHLGVBQWUsQ0FDOUIsY0FBYyxFQUNkLHdCQUF3QixFQUN4QixPQUFPLEVBQ1AsY0FBYyxFQUNkLFdBQVcsRUFDWCxlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLFlBQVksRUFDWixRQUFRLENBQ1QsQ0FBQztRQUNGLFlBQVksR0FBRyxjQUFjLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRTFELE9BQU87WUFDTCxZQUFZO1lBQ1osV0FBVztZQUNYLFlBQVk7WUFDWixlQUFlO1lBQ2YsZ0JBQWdCO1lBQ2hCLGNBQWM7WUFDZCxpQkFBaUI7WUFDakIsY0FBYztZQUNkLFFBQVE7WUFDUixRQUFRO1NBQ1QsQ0FBQztJQUNKLENBQUMsQ0FBQztBQUNOLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFcnJvckhhbmRsZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGlvbiwgQWN0aW9uUmVkdWNlciwgVVBEQVRFLCBJTklUIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xuXG5pbXBvcnQgeyBkaWZmZXJlbmNlLCBsaWZ0QWN0aW9uLCBpc0FjdGlvbkZpbHRlcmVkIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgKiBhcyBEZXZ0b29sc0FjdGlvbnMgZnJvbSAnLi9hY3Rpb25zJztcbmltcG9ydCB7IFN0b3JlRGV2dG9vbHNDb25maWcgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBQZXJmb3JtQWN0aW9uIH0gZnJvbSAnLi9hY3Rpb25zJztcblxuZXhwb3J0IHR5cGUgSW5pdEFjdGlvbiA9IHtcbiAgcmVhZG9ubHkgdHlwZTogdHlwZW9mIElOSVQ7XG59O1xuXG5leHBvcnQgdHlwZSBVcGRhdGVSZWR1Y2VyQWN0aW9uID0ge1xuICByZWFkb25seSB0eXBlOiB0eXBlb2YgVVBEQVRFO1xufTtcblxuZXhwb3J0IHR5cGUgQ29yZUFjdGlvbnMgPSBJbml0QWN0aW9uIHwgVXBkYXRlUmVkdWNlckFjdGlvbjtcbmV4cG9ydCB0eXBlIEFjdGlvbnMgPSBEZXZ0b29sc0FjdGlvbnMuQWxsIHwgQ29yZUFjdGlvbnM7XG5cbmV4cG9ydCBjb25zdCBJTklUX0FDVElPTiA9IHsgdHlwZTogSU5JVCB9O1xuXG5leHBvcnQgY29uc3QgUkVDT01QVVRFID0gJ0BuZ3J4L3N0b3JlLWRldnRvb2xzL3JlY29tcHV0ZScgYXMgY29uc3Q7XG5leHBvcnQgY29uc3QgUkVDT01QVVRFX0FDVElPTiA9IHsgdHlwZTogUkVDT01QVVRFIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZWRTdGF0ZSB7XG4gIHN0YXRlOiBhbnk7XG4gIGVycm9yOiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlmdGVkQWN0aW9uIHtcbiAgdHlwZTogc3RyaW5nO1xuICBhY3Rpb246IEFjdGlvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaWZ0ZWRBY3Rpb25zIHtcbiAgW2lkOiBudW1iZXJdOiBMaWZ0ZWRBY3Rpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlmdGVkU3RhdGUge1xuICBtb25pdG9yU3RhdGU6IGFueTtcbiAgbmV4dEFjdGlvbklkOiBudW1iZXI7XG4gIGFjdGlvbnNCeUlkOiBMaWZ0ZWRBY3Rpb25zO1xuICBzdGFnZWRBY3Rpb25JZHM6IG51bWJlcltdO1xuICBza2lwcGVkQWN0aW9uSWRzOiBudW1iZXJbXTtcbiAgY29tbWl0dGVkU3RhdGU6IGFueTtcbiAgY3VycmVudFN0YXRlSW5kZXg6IG51bWJlcjtcbiAgY29tcHV0ZWRTdGF0ZXM6IENvbXB1dGVkU3RhdGVbXTtcbiAgaXNMb2NrZWQ6IGJvb2xlYW47XG4gIGlzUGF1c2VkOiBib29sZWFuO1xufVxuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBuZXh0IGVudHJ5IGluIHRoZSBsb2cgYnkgYXBwbHlpbmcgYW4gYWN0aW9uLlxuICovXG5mdW5jdGlvbiBjb21wdXRlTmV4dEVudHJ5KFxuICByZWR1Y2VyOiBBY3Rpb25SZWR1Y2VyPGFueSwgYW55PixcbiAgYWN0aW9uOiBBY3Rpb24sXG4gIHN0YXRlOiBhbnksXG4gIGVycm9yOiBhbnksXG4gIGVycm9ySGFuZGxlcjogRXJyb3JIYW5kbGVyXG4pIHtcbiAgaWYgKGVycm9yKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXRlLFxuICAgICAgZXJyb3I6ICdJbnRlcnJ1cHRlZCBieSBhbiBlcnJvciB1cCB0aGUgY2hhaW4nLFxuICAgIH07XG4gIH1cblxuICBsZXQgbmV4dFN0YXRlID0gc3RhdGU7XG4gIGxldCBuZXh0RXJyb3I7XG4gIHRyeSB7XG4gICAgbmV4dFN0YXRlID0gcmVkdWNlcihzdGF0ZSwgYWN0aW9uKTtcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICBuZXh0RXJyb3IgPSBlcnIudG9TdHJpbmcoKTtcbiAgICBlcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZXJyKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3RhdGU6IG5leHRTdGF0ZSxcbiAgICBlcnJvcjogbmV4dEVycm9yLFxuICB9O1xufVxuXG4vKipcbiAqIFJ1bnMgdGhlIHJlZHVjZXIgb24gaW52YWxpZGF0ZWQgYWN0aW9ucyB0byBnZXQgYSBmcmVzaCBjb21wdXRhdGlvbiBsb2cuXG4gKi9cbmZ1bmN0aW9uIHJlY29tcHV0ZVN0YXRlcyhcbiAgY29tcHV0ZWRTdGF0ZXM6IENvbXB1dGVkU3RhdGVbXSxcbiAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4OiBudW1iZXIsXG4gIHJlZHVjZXI6IEFjdGlvblJlZHVjZXI8YW55LCBhbnk+LFxuICBjb21taXR0ZWRTdGF0ZTogYW55LFxuICBhY3Rpb25zQnlJZDogTGlmdGVkQWN0aW9ucyxcbiAgc3RhZ2VkQWN0aW9uSWRzOiBudW1iZXJbXSxcbiAgc2tpcHBlZEFjdGlvbklkczogbnVtYmVyW10sXG4gIGVycm9ySGFuZGxlcjogRXJyb3JIYW5kbGVyLFxuICBpc1BhdXNlZDogYm9vbGVhblxuKSB7XG4gIC8vIE9wdGltaXphdGlvbjogZXhpdCBlYXJseSBhbmQgcmV0dXJuIHRoZSBzYW1lIHJlZmVyZW5jZVxuICAvLyBpZiB3ZSBrbm93IG5vdGhpbmcgY291bGQgaGF2ZSBjaGFuZ2VkLlxuICBpZiAoXG4gICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID49IGNvbXB1dGVkU3RhdGVzLmxlbmd0aCAmJlxuICAgIGNvbXB1dGVkU3RhdGVzLmxlbmd0aCA9PT0gc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aFxuICApIHtcbiAgICByZXR1cm4gY29tcHV0ZWRTdGF0ZXM7XG4gIH1cblxuICBjb25zdCBuZXh0Q29tcHV0ZWRTdGF0ZXMgPSBjb21wdXRlZFN0YXRlcy5zbGljZSgwLCBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXgpO1xuICAvLyBJZiB0aGUgcmVjb3JkaW5nIGlzIHBhdXNlZCwgcmVjb21wdXRlIGFsbCBzdGF0ZXMgdXAgdW50aWwgdGhlIHBhdXNlIHN0YXRlLFxuICAvLyBlbHNlIHJlY29tcHV0ZSBhbGwgc3RhdGVzLlxuICBjb25zdCBsYXN0SW5jbHVkZWRBY3Rpb25JZCA9IHN0YWdlZEFjdGlvbklkcy5sZW5ndGggLSAoaXNQYXVzZWQgPyAxIDogMCk7XG4gIGZvciAobGV0IGkgPSBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXg7IGkgPCBsYXN0SW5jbHVkZWRBY3Rpb25JZDsgaSsrKSB7XG4gICAgY29uc3QgYWN0aW9uSWQgPSBzdGFnZWRBY3Rpb25JZHNbaV07XG4gICAgY29uc3QgYWN0aW9uID0gYWN0aW9uc0J5SWRbYWN0aW9uSWRdLmFjdGlvbjtcblxuICAgIGNvbnN0IHByZXZpb3VzRW50cnkgPSBuZXh0Q29tcHV0ZWRTdGF0ZXNbaSAtIDFdO1xuICAgIGNvbnN0IHByZXZpb3VzU3RhdGUgPSBwcmV2aW91c0VudHJ5ID8gcHJldmlvdXNFbnRyeS5zdGF0ZSA6IGNvbW1pdHRlZFN0YXRlO1xuICAgIGNvbnN0IHByZXZpb3VzRXJyb3IgPSBwcmV2aW91c0VudHJ5ID8gcHJldmlvdXNFbnRyeS5lcnJvciA6IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHNob3VsZFNraXAgPSBza2lwcGVkQWN0aW9uSWRzLmluZGV4T2YoYWN0aW9uSWQpID4gLTE7XG4gICAgY29uc3QgZW50cnk6IENvbXB1dGVkU3RhdGUgPSBzaG91bGRTa2lwXG4gICAgICA/IHByZXZpb3VzRW50cnlcbiAgICAgIDogY29tcHV0ZU5leHRFbnRyeShcbiAgICAgICAgICByZWR1Y2VyLFxuICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICBwcmV2aW91c1N0YXRlLFxuICAgICAgICAgIHByZXZpb3VzRXJyb3IsXG4gICAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgICAgICk7XG5cbiAgICBuZXh0Q29tcHV0ZWRTdGF0ZXMucHVzaChlbnRyeSk7XG4gIH1cbiAgLy8gSWYgdGhlIHJlY29yZGluZyBpcyBwYXVzZWQsIHRoZSBsYXN0IHN0YXRlIHdpbGwgbm90IGJlIHJlY29tcHV0ZWQsXG4gIC8vIGJlY2F1c2UgaXQncyBlc3NlbnRpYWxseSBub3QgcGFydCBvZiB0aGUgc3RhdGUgaGlzdG9yeS5cbiAgaWYgKGlzUGF1c2VkKSB7XG4gICAgbmV4dENvbXB1dGVkU3RhdGVzLnB1c2goY29tcHV0ZWRTdGF0ZXNbY29tcHV0ZWRTdGF0ZXMubGVuZ3RoIC0gMV0pO1xuICB9XG5cbiAgcmV0dXJuIG5leHRDb21wdXRlZFN0YXRlcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpZnRJbml0aWFsU3RhdGUoXG4gIGluaXRpYWxDb21taXR0ZWRTdGF0ZT86IGFueSxcbiAgbW9uaXRvclJlZHVjZXI/OiBhbnlcbik6IExpZnRlZFN0YXRlIHtcbiAgcmV0dXJuIHtcbiAgICBtb25pdG9yU3RhdGU6IG1vbml0b3JSZWR1Y2VyKHVuZGVmaW5lZCwge30pLFxuICAgIG5leHRBY3Rpb25JZDogMSxcbiAgICBhY3Rpb25zQnlJZDogeyAwOiBsaWZ0QWN0aW9uKElOSVRfQUNUSU9OKSB9LFxuICAgIHN0YWdlZEFjdGlvbklkczogWzBdLFxuICAgIHNraXBwZWRBY3Rpb25JZHM6IFtdLFxuICAgIGNvbW1pdHRlZFN0YXRlOiBpbml0aWFsQ29tbWl0dGVkU3RhdGUsXG4gICAgY3VycmVudFN0YXRlSW5kZXg6IDAsXG4gICAgY29tcHV0ZWRTdGF0ZXM6IFtdLFxuICAgIGlzTG9ja2VkOiBmYWxzZSxcbiAgICBpc1BhdXNlZDogZmFsc2UsXG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGhpc3Rvcnkgc3RhdGUgcmVkdWNlciBmcm9tIGFuIGFwcCdzIHJlZHVjZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaWZ0UmVkdWNlcldpdGgoXG4gIGluaXRpYWxDb21taXR0ZWRTdGF0ZTogYW55LFxuICBpbml0aWFsTGlmdGVkU3RhdGU6IExpZnRlZFN0YXRlLFxuICBlcnJvckhhbmRsZXI6IEVycm9ySGFuZGxlcixcbiAgbW9uaXRvclJlZHVjZXI/OiBhbnksXG4gIG9wdGlvbnM6IFBhcnRpYWw8U3RvcmVEZXZ0b29sc0NvbmZpZz4gPSB7fVxuKSB7XG4gIC8qKlxuICAgKiBNYW5hZ2VzIGhvdyB0aGUgaGlzdG9yeSBhY3Rpb25zIG1vZGlmeSB0aGUgaGlzdG9yeSBzdGF0ZS5cbiAgICovXG4gIHJldHVybiAoXG4gICAgICByZWR1Y2VyOiBBY3Rpb25SZWR1Y2VyPGFueSwgYW55PlxuICAgICk6IEFjdGlvblJlZHVjZXI8TGlmdGVkU3RhdGUsIEFjdGlvbnM+ID0+XG4gICAgKGxpZnRlZFN0YXRlLCBsaWZ0ZWRBY3Rpb24pID0+IHtcbiAgICAgIGxldCB7XG4gICAgICAgIG1vbml0b3JTdGF0ZSxcbiAgICAgICAgYWN0aW9uc0J5SWQsXG4gICAgICAgIG5leHRBY3Rpb25JZCxcbiAgICAgICAgc3RhZ2VkQWN0aW9uSWRzLFxuICAgICAgICBza2lwcGVkQWN0aW9uSWRzLFxuICAgICAgICBjb21taXR0ZWRTdGF0ZSxcbiAgICAgICAgY3VycmVudFN0YXRlSW5kZXgsXG4gICAgICAgIGNvbXB1dGVkU3RhdGVzLFxuICAgICAgICBpc0xvY2tlZCxcbiAgICAgICAgaXNQYXVzZWQsXG4gICAgICB9ID0gbGlmdGVkU3RhdGUgfHwgaW5pdGlhbExpZnRlZFN0YXRlO1xuXG4gICAgICBpZiAoIWxpZnRlZFN0YXRlKSB7XG4gICAgICAgIC8vIFByZXZlbnQgbXV0YXRpbmcgaW5pdGlhbExpZnRlZFN0YXRlXG4gICAgICAgIGFjdGlvbnNCeUlkID0gT2JqZWN0LmNyZWF0ZShhY3Rpb25zQnlJZCk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNvbW1pdEV4Y2Vzc0FjdGlvbnMobjogbnVtYmVyKSB7XG4gICAgICAgIC8vIEF1dG8tY29tbWl0cyBuLW51bWJlciBvZiBleGNlc3MgYWN0aW9ucy5cbiAgICAgICAgbGV0IGV4Y2VzcyA9IG47XG4gICAgICAgIGxldCBpZHNUb0RlbGV0ZSA9IHN0YWdlZEFjdGlvbklkcy5zbGljZSgxLCBleGNlc3MgKyAxKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlkc1RvRGVsZXRlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGNvbXB1dGVkU3RhdGVzW2kgKyAxXS5lcnJvcikge1xuICAgICAgICAgICAgLy8gU3RvcCBpZiBlcnJvciBpcyBmb3VuZC4gQ29tbWl0IGFjdGlvbnMgdXAgdG8gZXJyb3IuXG4gICAgICAgICAgICBleGNlc3MgPSBpO1xuICAgICAgICAgICAgaWRzVG9EZWxldGUgPSBzdGFnZWRBY3Rpb25JZHMuc2xpY2UoMSwgZXhjZXNzICsgMSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIGFjdGlvbnNCeUlkW2lkc1RvRGVsZXRlW2ldXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gc2tpcHBlZEFjdGlvbklkcy5maWx0ZXIoXG4gICAgICAgICAgKGlkKSA9PiBpZHNUb0RlbGV0ZS5pbmRleE9mKGlkKSA9PT0gLTFcbiAgICAgICAgKTtcbiAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWzAsIC4uLnN0YWdlZEFjdGlvbklkcy5zbGljZShleGNlc3MgKyAxKV07XG4gICAgICAgIGNvbW1pdHRlZFN0YXRlID0gY29tcHV0ZWRTdGF0ZXNbZXhjZXNzXS5zdGF0ZTtcbiAgICAgICAgY29tcHV0ZWRTdGF0ZXMgPSBjb21wdXRlZFN0YXRlcy5zbGljZShleGNlc3MpO1xuICAgICAgICBjdXJyZW50U3RhdGVJbmRleCA9XG4gICAgICAgICAgY3VycmVudFN0YXRlSW5kZXggPiBleGNlc3MgPyBjdXJyZW50U3RhdGVJbmRleCAtIGV4Y2VzcyA6IDA7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNvbW1pdENoYW5nZXMoKSB7XG4gICAgICAgIC8vIENvbnNpZGVyIHRoZSBsYXN0IGNvbW1pdHRlZCBzdGF0ZSB0aGUgbmV3IHN0YXJ0aW5nIHBvaW50LlxuICAgICAgICAvLyBTcXVhc2ggYW55IHN0YWdlZCBhY3Rpb25zIGludG8gYSBzaW5nbGUgY29tbWl0dGVkIHN0YXRlLlxuICAgICAgICBhY3Rpb25zQnlJZCA9IHsgMDogbGlmdEFjdGlvbihJTklUX0FDVElPTikgfTtcbiAgICAgICAgbmV4dEFjdGlvbklkID0gMTtcbiAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWzBdO1xuICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW107XG4gICAgICAgIGNvbW1pdHRlZFN0YXRlID0gY29tcHV0ZWRTdGF0ZXNbY3VycmVudFN0YXRlSW5kZXhdLnN0YXRlO1xuICAgICAgICBjdXJyZW50U3RhdGVJbmRleCA9IDA7XG4gICAgICAgIGNvbXB1dGVkU3RhdGVzID0gW107XG4gICAgICB9XG5cbiAgICAgIC8vIEJ5IGRlZmF1bHQsIGFnZ3Jlc3NpdmVseSByZWNvbXB1dGUgZXZlcnkgc3RhdGUgd2hhdGV2ZXIgaGFwcGVucy5cbiAgICAgIC8vIFRoaXMgaGFzIE8obikgcGVyZm9ybWFuY2UsIHNvIHdlJ2xsIG92ZXJyaWRlIHRoaXMgdG8gYSBzZW5zaWJsZVxuICAgICAgLy8gdmFsdWUgd2hlbmV2ZXIgd2UgZmVlbCBsaWtlIHdlIGRvbid0IGhhdmUgdG8gcmVjb21wdXRlIHRoZSBzdGF0ZXMuXG4gICAgICBsZXQgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gMDtcblxuICAgICAgc3dpdGNoIChsaWZ0ZWRBY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlIERldnRvb2xzQWN0aW9ucy5MT0NLX0NIQU5HRVM6IHtcbiAgICAgICAgICBpc0xvY2tlZCA9IGxpZnRlZEFjdGlvbi5zdGF0dXM7XG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBEZXZ0b29sc0FjdGlvbnMuUEFVU0VfUkVDT1JESU5HOiB7XG4gICAgICAgICAgaXNQYXVzZWQgPSBsaWZ0ZWRBY3Rpb24uc3RhdHVzO1xuICAgICAgICAgIGlmIChpc1BhdXNlZCkge1xuICAgICAgICAgICAgLy8gQWRkIGEgcGF1c2UgYWN0aW9uIHRvIHNpZ25hbCB0aGUgZGV2dG9vbHMtdXNlciB0aGUgcmVjb3JkaW5nIGlzIHBhdXNlZC5cbiAgICAgICAgICAgIC8vIFRoZSBjb3JyZXNwb25kaW5nIHN0YXRlIHdpbGwgYmUgb3ZlcndyaXR0ZW4gb24gZWFjaCB1cGRhdGUgdG8gYWx3YXlzIGNvbnRhaW5cbiAgICAgICAgICAgIC8vIHRoZSBsYXRlc3Qgc3RhdGUgKHNlZSBBY3Rpb25zLlBFUkZPUk1fQUNUSU9OKS5cbiAgICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyA9IFsuLi5zdGFnZWRBY3Rpb25JZHMsIG5leHRBY3Rpb25JZF07XG4gICAgICAgICAgICBhY3Rpb25zQnlJZFtuZXh0QWN0aW9uSWRdID0gbmV3IFBlcmZvcm1BY3Rpb24oXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnQG5ncngvZGV2dG9vbHMvcGF1c2UnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICArRGF0ZS5ub3coKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG5leHRBY3Rpb25JZCsrO1xuICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBjb21wdXRlZFN0YXRlcyA9IGNvbXB1dGVkU3RhdGVzLmNvbmNhdChcbiAgICAgICAgICAgICAgY29tcHV0ZWRTdGF0ZXNbY29tcHV0ZWRTdGF0ZXMubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50U3RhdGVJbmRleCA9PT0gc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aCAtIDIpIHtcbiAgICAgICAgICAgICAgY3VycmVudFN0YXRlSW5kZXgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IEluZmluaXR5O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb21taXRDaGFuZ2VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgRGV2dG9vbHNBY3Rpb25zLlJFU0VUOiB7XG4gICAgICAgICAgLy8gR2V0IGJhY2sgdG8gdGhlIHN0YXRlIHRoZSBzdG9yZSB3YXMgY3JlYXRlZCB3aXRoLlxuICAgICAgICAgIGFjdGlvbnNCeUlkID0geyAwOiBsaWZ0QWN0aW9uKElOSVRfQUNUSU9OKSB9O1xuICAgICAgICAgIG5leHRBY3Rpb25JZCA9IDE7XG4gICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWzBdO1xuICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMgPSBbXTtcbiAgICAgICAgICBjb21taXR0ZWRTdGF0ZSA9IGluaXRpYWxDb21taXR0ZWRTdGF0ZTtcbiAgICAgICAgICBjdXJyZW50U3RhdGVJbmRleCA9IDA7XG4gICAgICAgICAgY29tcHV0ZWRTdGF0ZXMgPSBbXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIERldnRvb2xzQWN0aW9ucy5DT01NSVQ6IHtcbiAgICAgICAgICBjb21taXRDaGFuZ2VzKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBEZXZ0b29sc0FjdGlvbnMuUk9MTEJBQ0s6IHtcbiAgICAgICAgICAvLyBGb3JnZXQgYWJvdXQgYW55IHN0YWdlZCBhY3Rpb25zLlxuICAgICAgICAgIC8vIFN0YXJ0IGFnYWluIGZyb20gdGhlIGxhc3QgY29tbWl0dGVkIHN0YXRlLlxuICAgICAgICAgIGFjdGlvbnNCeUlkID0geyAwOiBsaWZ0QWN0aW9uKElOSVRfQUNUSU9OKSB9O1xuICAgICAgICAgIG5leHRBY3Rpb25JZCA9IDE7XG4gICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWzBdO1xuICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMgPSBbXTtcbiAgICAgICAgICBjdXJyZW50U3RhdGVJbmRleCA9IDA7XG4gICAgICAgICAgY29tcHV0ZWRTdGF0ZXMgPSBbXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIERldnRvb2xzQWN0aW9ucy5UT0dHTEVfQUNUSU9OOiB7XG4gICAgICAgICAgLy8gVG9nZ2xlIHdoZXRoZXIgYW4gYWN0aW9uIHdpdGggZ2l2ZW4gSUQgaXMgc2tpcHBlZC5cbiAgICAgICAgICAvLyBCZWluZyBza2lwcGVkIG1lYW5zIGl0IGlzIGEgbm8tb3AgZHVyaW5nIHRoZSBjb21wdXRhdGlvbi5cbiAgICAgICAgICBjb25zdCB7IGlkOiBhY3Rpb25JZCB9ID0gbGlmdGVkQWN0aW9uO1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gc2tpcHBlZEFjdGlvbklkcy5pbmRleE9mKGFjdGlvbklkKTtcbiAgICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW2FjdGlvbklkLCAuLi5za2lwcGVkQWN0aW9uSWRzXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2tpcHBlZEFjdGlvbklkcyA9IHNraXBwZWRBY3Rpb25JZHMuZmlsdGVyKChpZCkgPT4gaWQgIT09IGFjdGlvbklkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gT3B0aW1pemF0aW9uOiB3ZSBrbm93IGhpc3RvcnkgYmVmb3JlIHRoaXMgYWN0aW9uIGhhc24ndCBjaGFuZ2VkXG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gc3RhZ2VkQWN0aW9uSWRzLmluZGV4T2YoYWN0aW9uSWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgRGV2dG9vbHNBY3Rpb25zLlNFVF9BQ1RJT05TX0FDVElWRToge1xuICAgICAgICAgIC8vIFRvZ2dsZSB3aGV0aGVyIGFuIGFjdGlvbiB3aXRoIGdpdmVuIElEIGlzIHNraXBwZWQuXG4gICAgICAgICAgLy8gQmVpbmcgc2tpcHBlZCBtZWFucyBpdCBpcyBhIG5vLW9wIGR1cmluZyB0aGUgY29tcHV0YXRpb24uXG4gICAgICAgICAgY29uc3QgeyBzdGFydCwgZW5kLCBhY3RpdmUgfSA9IGxpZnRlZEFjdGlvbjtcbiAgICAgICAgICBjb25zdCBhY3Rpb25JZHMgPSBbXTtcbiAgICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykgYWN0aW9uSWRzLnB1c2goaSk7XG4gICAgICAgICAgaWYgKGFjdGl2ZSkge1xuICAgICAgICAgICAgc2tpcHBlZEFjdGlvbklkcyA9IGRpZmZlcmVuY2Uoc2tpcHBlZEFjdGlvbklkcywgYWN0aW9uSWRzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2tpcHBlZEFjdGlvbklkcyA9IFsuLi5za2lwcGVkQWN0aW9uSWRzLCAuLi5hY3Rpb25JZHNdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogd2Uga25vdyBoaXN0b3J5IGJlZm9yZSB0aGlzIGFjdGlvbiBoYXNuJ3QgY2hhbmdlZFxuICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IHN0YWdlZEFjdGlvbklkcy5pbmRleE9mKHN0YXJ0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIERldnRvb2xzQWN0aW9ucy5KVU1QX1RPX1NUQVRFOiB7XG4gICAgICAgICAgLy8gV2l0aG91dCByZWNvbXB1dGluZyBhbnl0aGluZywgbW92ZSB0aGUgcG9pbnRlciB0aGF0IHRlbGwgdXNcbiAgICAgICAgICAvLyB3aGljaCBzdGF0ZSBpcyBjb25zaWRlcmVkIHRoZSBjdXJyZW50IG9uZS4gVXNlZnVsIGZvciBzbGlkZXJzLlxuICAgICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4ID0gbGlmdGVkQWN0aW9uLmluZGV4O1xuICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogd2Uga25vdyB0aGUgaGlzdG9yeSBoYXMgbm90IGNoYW5nZWQuXG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBEZXZ0b29sc0FjdGlvbnMuSlVNUF9UT19BQ1RJT046IHtcbiAgICAgICAgICAvLyBKdW1wcyB0byBhIGNvcnJlc3BvbmRpbmcgc3RhdGUgdG8gYSBzcGVjaWZpYyBhY3Rpb24uXG4gICAgICAgICAgLy8gVXNlZnVsIHdoZW4gZmlsdGVyaW5nIGFjdGlvbnMuXG4gICAgICAgICAgY29uc3QgaW5kZXggPSBzdGFnZWRBY3Rpb25JZHMuaW5kZXhPZihsaWZ0ZWRBY3Rpb24uYWN0aW9uSWQpO1xuICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIGN1cnJlbnRTdGF0ZUluZGV4ID0gaW5kZXg7XG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBEZXZ0b29sc0FjdGlvbnMuU1dFRVA6IHtcbiAgICAgICAgICAvLyBGb3JnZXQgYW55IGFjdGlvbnMgdGhhdCBhcmUgY3VycmVudGx5IGJlaW5nIHNraXBwZWQuXG4gICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gZGlmZmVyZW5jZShzdGFnZWRBY3Rpb25JZHMsIHNraXBwZWRBY3Rpb25JZHMpO1xuICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMgPSBbXTtcbiAgICAgICAgICBjdXJyZW50U3RhdGVJbmRleCA9IE1hdGgubWluKFxuICAgICAgICAgICAgY3VycmVudFN0YXRlSW5kZXgsXG4gICAgICAgICAgICBzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gMVxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBEZXZ0b29sc0FjdGlvbnMuUEVSRk9STV9BQ1RJT046IHtcbiAgICAgICAgICAvLyBJZ25vcmUgYWN0aW9uIGFuZCByZXR1cm4gc3RhdGUgYXMgaXMgaWYgcmVjb3JkaW5nIGlzIGxvY2tlZFxuICAgICAgICAgIGlmIChpc0xvY2tlZCkge1xuICAgICAgICAgICAgcmV0dXJuIGxpZnRlZFN0YXRlIHx8IGluaXRpYWxMaWZ0ZWRTdGF0ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpc1BhdXNlZCB8fFxuICAgICAgICAgICAgKGxpZnRlZFN0YXRlICYmXG4gICAgICAgICAgICAgIGlzQWN0aW9uRmlsdGVyZWQoXG4gICAgICAgICAgICAgICAgbGlmdGVkU3RhdGUuY29tcHV0ZWRTdGF0ZXNbY3VycmVudFN0YXRlSW5kZXhdLFxuICAgICAgICAgICAgICAgIGxpZnRlZEFjdGlvbixcbiAgICAgICAgICAgICAgICBvcHRpb25zLnByZWRpY2F0ZSxcbiAgICAgICAgICAgICAgICBvcHRpb25zLmFjdGlvbnNTYWZlbGlzdCxcbiAgICAgICAgICAgICAgICBvcHRpb25zLmFjdGlvbnNCbG9ja2xpc3RcbiAgICAgICAgICAgICAgKSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIElmIHJlY29yZGluZyBpcyBwYXVzZWQgb3IgaWYgdGhlIGFjdGlvbiBzaG91bGQgYmUgaWdub3JlZCwgb3ZlcndyaXRlIHRoZSBsYXN0IHN0YXRlXG4gICAgICAgICAgICAvLyAoY29ycmVzcG9uZHMgdG8gdGhlIHBhdXNlIGFjdGlvbikgYW5kIGtlZXAgZXZlcnl0aGluZyBlbHNlIGFzIGlzLlxuICAgICAgICAgICAgLy8gVGhpcyB3YXksIHRoZSBhcHAgZ2V0cyB0aGUgbmV3IGN1cnJlbnQgc3RhdGUgd2hpbGUgdGhlIGRldnRvb2xzXG4gICAgICAgICAgICAvLyBkbyBub3QgcmVjb3JkIGFub3RoZXIgYWN0aW9uLlxuICAgICAgICAgICAgY29uc3QgbGFzdFN0YXRlID0gY29tcHV0ZWRTdGF0ZXNbY29tcHV0ZWRTdGF0ZXMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBjb21wdXRlZFN0YXRlcyA9IFtcbiAgICAgICAgICAgICAgLi4uY29tcHV0ZWRTdGF0ZXMuc2xpY2UoMCwgLTEpLFxuICAgICAgICAgICAgICBjb21wdXRlTmV4dEVudHJ5KFxuICAgICAgICAgICAgICAgIHJlZHVjZXIsXG4gICAgICAgICAgICAgICAgbGlmdGVkQWN0aW9uLmFjdGlvbixcbiAgICAgICAgICAgICAgICBsYXN0U3RhdGUuc3RhdGUsXG4gICAgICAgICAgICAgICAgbGFzdFN0YXRlLmVycm9yLFxuICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlclxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IEluZmluaXR5O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gQXV0by1jb21taXQgYXMgbmV3IGFjdGlvbnMgY29tZSBpbi5cbiAgICAgICAgICBpZiAob3B0aW9ucy5tYXhBZ2UgJiYgc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aCA9PT0gb3B0aW9ucy5tYXhBZ2UpIHtcbiAgICAgICAgICAgIGNvbW1pdEV4Y2Vzc0FjdGlvbnMoMSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZUluZGV4ID09PSBzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgY3VycmVudFN0YXRlSW5kZXgrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgYWN0aW9uSWQgPSBuZXh0QWN0aW9uSWQrKztcbiAgICAgICAgICAvLyBNdXRhdGlvbiEgVGhpcyBpcyB0aGUgaG90dGVzdCBwYXRoLCBhbmQgd2Ugb3B0aW1pemUgb24gcHVycG9zZS5cbiAgICAgICAgICAvLyBJdCBpcyBzYWZlIGJlY2F1c2Ugd2Ugc2V0IGEgbmV3IGtleSBpbiBhIGNhY2hlIGRpY3Rpb25hcnkuXG4gICAgICAgICAgYWN0aW9uc0J5SWRbYWN0aW9uSWRdID0gbGlmdGVkQWN0aW9uO1xuXG4gICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWy4uLnN0YWdlZEFjdGlvbklkcywgYWN0aW9uSWRdO1xuICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogd2Uga25vdyB0aGF0IG9ubHkgdGhlIG5ldyBhY3Rpb24gbmVlZHMgY29tcHV0aW5nLlxuICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IHN0YWdlZEFjdGlvbklkcy5sZW5ndGggLSAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgRGV2dG9vbHNBY3Rpb25zLklNUE9SVF9TVEFURToge1xuICAgICAgICAgIC8vIENvbXBsZXRlbHkgcmVwbGFjZSBldmVyeXRoaW5nLlxuICAgICAgICAgICh7XG4gICAgICAgICAgICBtb25pdG9yU3RhdGUsXG4gICAgICAgICAgICBhY3Rpb25zQnlJZCxcbiAgICAgICAgICAgIG5leHRBY3Rpb25JZCxcbiAgICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyxcbiAgICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMsXG4gICAgICAgICAgICBjb21taXR0ZWRTdGF0ZSxcbiAgICAgICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4LFxuICAgICAgICAgICAgY29tcHV0ZWRTdGF0ZXMsXG4gICAgICAgICAgICBpc0xvY2tlZCxcbiAgICAgICAgICAgIGlzUGF1c2VkLFxuICAgICAgICAgIH0gPSBsaWZ0ZWRBY3Rpb24ubmV4dExpZnRlZFN0YXRlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIElOSVQ6IHtcbiAgICAgICAgICAvLyBBbHdheXMgcmVjb21wdXRlIHN0YXRlcyBvbiBob3QgcmVsb2FkIGFuZCBpbml0LlxuICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IDA7XG5cbiAgICAgICAgICBpZiAob3B0aW9ucy5tYXhBZ2UgJiYgc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aCA+IG9wdGlvbnMubWF4QWdlKSB7XG4gICAgICAgICAgICAvLyBTdGF0ZXMgbXVzdCBiZSByZWNvbXB1dGVkIGJlZm9yZSBjb21taXR0aW5nIGV4Y2Vzcy5cbiAgICAgICAgICAgIGNvbXB1dGVkU3RhdGVzID0gcmVjb21wdXRlU3RhdGVzKFxuICAgICAgICAgICAgICBjb21wdXRlZFN0YXRlcyxcbiAgICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4LFxuICAgICAgICAgICAgICByZWR1Y2VyLFxuICAgICAgICAgICAgICBjb21taXR0ZWRTdGF0ZSxcbiAgICAgICAgICAgICAgYWN0aW9uc0J5SWQsXG4gICAgICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyxcbiAgICAgICAgICAgICAgc2tpcHBlZEFjdGlvbklkcyxcbiAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLFxuICAgICAgICAgICAgICBpc1BhdXNlZFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29tbWl0RXhjZXNzQWN0aW9ucyhzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gb3B0aW9ucy5tYXhBZ2UpO1xuXG4gICAgICAgICAgICAvLyBBdm9pZCBkb3VibGUgY29tcHV0YXRpb24uXG4gICAgICAgICAgICBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXggPSBJbmZpbml0eTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIFVQREFURToge1xuICAgICAgICAgIGNvbnN0IHN0YXRlSGFzRXJyb3JzID1cbiAgICAgICAgICAgIGNvbXB1dGVkU3RhdGVzLmZpbHRlcigoc3RhdGUpID0+IHN0YXRlLmVycm9yKS5sZW5ndGggPiAwO1xuXG4gICAgICAgICAgaWYgKHN0YXRlSGFzRXJyb3JzKSB7XG4gICAgICAgICAgICAvLyBSZWNvbXB1dGUgYWxsIHN0YXRlc1xuICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gMDtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMubWF4QWdlICYmIHN0YWdlZEFjdGlvbklkcy5sZW5ndGggPiBvcHRpb25zLm1heEFnZSkge1xuICAgICAgICAgICAgICAvLyBTdGF0ZXMgbXVzdCBiZSByZWNvbXB1dGVkIGJlZm9yZSBjb21taXR0aW5nIGV4Y2Vzcy5cbiAgICAgICAgICAgICAgY29tcHV0ZWRTdGF0ZXMgPSByZWNvbXB1dGVTdGF0ZXMoXG4gICAgICAgICAgICAgICAgY29tcHV0ZWRTdGF0ZXMsXG4gICAgICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4LFxuICAgICAgICAgICAgICAgIHJlZHVjZXIsXG4gICAgICAgICAgICAgICAgY29tbWl0dGVkU3RhdGUsXG4gICAgICAgICAgICAgICAgYWN0aW9uc0J5SWQsXG4gICAgICAgICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzLFxuICAgICAgICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMsXG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLFxuICAgICAgICAgICAgICAgIGlzUGF1c2VkXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgY29tbWl0RXhjZXNzQWN0aW9ucyhzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gb3B0aW9ucy5tYXhBZ2UpO1xuXG4gICAgICAgICAgICAgIC8vIEF2b2lkIGRvdWJsZSBjb21wdXRhdGlvbi5cbiAgICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIElmIG5vdCBwYXVzZWQvbG9ja2VkLCBhZGQgYSBuZXcgYWN0aW9uIHRvIHNpZ25hbCBkZXZ0b29scy11c2VyXG4gICAgICAgICAgICAvLyB0aGF0IHRoZXJlIHdhcyBhIHJlZHVjZXIgdXBkYXRlLlxuICAgICAgICAgICAgaWYgKCFpc1BhdXNlZCAmJiAhaXNMb2NrZWQpIHtcbiAgICAgICAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZUluZGV4ID09PSBzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4Kys7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBBZGQgYSBuZXcgYWN0aW9uIHRvIG9ubHkgcmVjb21wdXRlIHN0YXRlXG4gICAgICAgICAgICAgIGNvbnN0IGFjdGlvbklkID0gbmV4dEFjdGlvbklkKys7XG4gICAgICAgICAgICAgIGFjdGlvbnNCeUlkW2FjdGlvbklkXSA9IG5ldyBQZXJmb3JtQWN0aW9uKFxuICAgICAgICAgICAgICAgIGxpZnRlZEFjdGlvbixcbiAgICAgICAgICAgICAgICArRGF0ZS5ub3coKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBzdGFnZWRBY3Rpb25JZHMgPSBbLi4uc3RhZ2VkQWN0aW9uSWRzLCBhY3Rpb25JZF07XG5cbiAgICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aCAtIDE7XG5cbiAgICAgICAgICAgICAgY29tcHV0ZWRTdGF0ZXMgPSByZWNvbXB1dGVTdGF0ZXMoXG4gICAgICAgICAgICAgICAgY29tcHV0ZWRTdGF0ZXMsXG4gICAgICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4LFxuICAgICAgICAgICAgICAgIHJlZHVjZXIsXG4gICAgICAgICAgICAgICAgY29tbWl0dGVkU3RhdGUsXG4gICAgICAgICAgICAgICAgYWN0aW9uc0J5SWQsXG4gICAgICAgICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzLFxuICAgICAgICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMsXG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLFxuICAgICAgICAgICAgICAgIGlzUGF1c2VkXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlY29tcHV0ZSBzdGF0ZSBoaXN0b3J5IHdpdGggbGF0ZXN0IHJlZHVjZXIgYW5kIHVwZGF0ZSBhY3Rpb25cbiAgICAgICAgICAgIGNvbXB1dGVkU3RhdGVzID0gY29tcHV0ZWRTdGF0ZXMubWFwKChjbXApID0+ICh7XG4gICAgICAgICAgICAgIC4uLmNtcCxcbiAgICAgICAgICAgICAgc3RhdGU6IHJlZHVjZXIoY21wLnN0YXRlLCBSRUNPTVBVVEVfQUNUSU9OKSxcbiAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgY3VycmVudFN0YXRlSW5kZXggPSBzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gMTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMubWF4QWdlICYmIHN0YWdlZEFjdGlvbklkcy5sZW5ndGggPiBvcHRpb25zLm1heEFnZSkge1xuICAgICAgICAgICAgICBjb21taXRFeGNlc3NBY3Rpb25zKHN0YWdlZEFjdGlvbklkcy5sZW5ndGggLSBvcHRpb25zLm1heEFnZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEF2b2lkIGRvdWJsZSBjb21wdXRhdGlvbi5cbiAgICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IEluZmluaXR5O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAvLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCByZWNvZ25pemVkLCBpdCdzIGEgbW9uaXRvciBhY3Rpb24uXG4gICAgICAgICAgLy8gT3B0aW1pemF0aW9uOiBhIG1vbml0b3IgYWN0aW9uIGNhbid0IGNoYW5nZSBoaXN0b3J5LlxuICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IEluZmluaXR5O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbXB1dGVkU3RhdGVzID0gcmVjb21wdXRlU3RhdGVzKFxuICAgICAgICBjb21wdXRlZFN0YXRlcyxcbiAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4LFxuICAgICAgICByZWR1Y2VyLFxuICAgICAgICBjb21taXR0ZWRTdGF0ZSxcbiAgICAgICAgYWN0aW9uc0J5SWQsXG4gICAgICAgIHN0YWdlZEFjdGlvbklkcyxcbiAgICAgICAgc2tpcHBlZEFjdGlvbklkcyxcbiAgICAgICAgZXJyb3JIYW5kbGVyLFxuICAgICAgICBpc1BhdXNlZFxuICAgICAgKTtcbiAgICAgIG1vbml0b3JTdGF0ZSA9IG1vbml0b3JSZWR1Y2VyKG1vbml0b3JTdGF0ZSwgbGlmdGVkQWN0aW9uKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbW9uaXRvclN0YXRlLFxuICAgICAgICBhY3Rpb25zQnlJZCxcbiAgICAgICAgbmV4dEFjdGlvbklkLFxuICAgICAgICBzdGFnZWRBY3Rpb25JZHMsXG4gICAgICAgIHNraXBwZWRBY3Rpb25JZHMsXG4gICAgICAgIGNvbW1pdHRlZFN0YXRlLFxuICAgICAgICBjdXJyZW50U3RhdGVJbmRleCxcbiAgICAgICAgY29tcHV0ZWRTdGF0ZXMsXG4gICAgICAgIGlzTG9ja2VkLFxuICAgICAgICBpc1BhdXNlZCxcbiAgICAgIH07XG4gICAgfTtcbn1cbiJdfQ==
|