@worktile/planet 12.1.2 → 13.0.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/application/planet-application-loader.d.ts +3 -0
- package/application/planet-application-loader.d.ts.map +1 -1
- package/application/planet-application.service.d.ts +3 -0
- package/application/planet-application.service.d.ts.map +1 -1
- package/assets-loader.d.ts +3 -0
- package/assets-loader.d.ts.map +1 -1
- package/component/planet-component-loader.d.ts +3 -0
- package/component/planet-component-loader.d.ts.map +1 -1
- package/empty/empty.component.d.ts +3 -0
- package/empty/empty.component.d.ts.map +1 -1
- package/esm2020/application/planet-application-loader.mjs +454 -0
- package/esm2020/application/planet-application-ref.mjs +94 -0
- package/{esm2015/application/planet-application.service.js → esm2020/application/planet-application.service.mjs} +9 -11
- package/{esm2015/application/portal-application.js → esm2020/application/portal-application.mjs} +0 -0
- package/{esm2015/assets-loader.js → esm2020/assets-loader.mjs} +9 -10
- package/esm2020/component/planet-component-loader.mjs +153 -0
- package/{esm2015/component/planet-component-ref.js → esm2020/component/planet-component-ref.mjs} +0 -0
- package/{esm2015/component/plant-component.config.js → esm2020/component/plant-component.config.mjs} +0 -0
- package/{esm2015/debug.js → esm2020/debug.mjs} +0 -0
- package/esm2020/empty/empty.component.mjs +15 -0
- package/{esm2015/global-event-dispatcher.js → esm2020/global-event-dispatcher.mjs} +9 -10
- package/esm2020/global-planet.mjs +53 -0
- package/{esm2015/helpers.js → esm2020/helpers.mjs} +0 -0
- package/esm2020/module.mjs +31 -0
- package/{esm2015/planet.class.js → esm2020/planet.class.mjs} +0 -0
- package/esm2020/planet.mjs +91 -0
- package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
- package/{esm2015/sandbox/constants.js → esm2020/sandbox/constants.mjs} +0 -0
- package/{esm2015/sandbox/exec.js → esm2020/sandbox/exec.mjs} +0 -0
- package/{esm2015/sandbox/index.js → esm2020/sandbox/index.mjs} +0 -0
- package/{esm2015/sandbox/proxy/patches/document.js → esm2020/sandbox/proxy/patches/document.mjs} +0 -0
- package/{esm2015/sandbox/proxy/patches/eventListener.js → esm2020/sandbox/proxy/patches/eventListener.mjs} +0 -0
- package/{esm2015/sandbox/proxy/patches/index.js → esm2020/sandbox/proxy/patches/index.mjs} +0 -0
- package/{esm2015/sandbox/proxy/patches/storage.js → esm2020/sandbox/proxy/patches/storage.mjs} +0 -0
- package/{esm2015/sandbox/proxy/patches/timer.js → esm2020/sandbox/proxy/patches/timer.mjs} +0 -0
- package/{esm2015/sandbox/proxy/proxies/common.js → esm2020/sandbox/proxy/proxies/common.mjs} +2 -2
- package/{esm2015/sandbox/proxy/proxies/document.js → esm2020/sandbox/proxy/proxies/document.mjs} +0 -0
- package/{esm2015/sandbox/proxy/proxies/window.js → esm2020/sandbox/proxy/proxies/window.mjs} +5 -2
- package/{esm2015/sandbox/proxy/proxy-sandbox.js → esm2020/sandbox/proxy/proxy-sandbox.mjs} +2 -2
- package/{esm2015/sandbox/proxy/types.js → esm2020/sandbox/proxy/types.mjs} +0 -0
- package/{esm2015/sandbox/sandbox.js → esm2020/sandbox/sandbox.mjs} +0 -0
- package/{esm2015/sandbox/snapshot/snapshot-sandbox.js → esm2020/sandbox/snapshot/snapshot-sandbox.mjs} +0 -0
- package/{esm2015/sandbox/types.js → esm2020/sandbox/types.mjs} +0 -0
- package/esm2020/worktile-planet.mjs +5 -0
- package/fesm2015/{worktile-planet.js → worktile-planet.mjs} +231 -230
- package/fesm2015/worktile-planet.mjs.map +1 -0
- package/fesm2020/worktile-planet.mjs +2046 -0
- package/fesm2020/worktile-planet.mjs.map +1 -0
- package/global-event-dispatcher.d.ts +3 -0
- package/global-event-dispatcher.d.ts.map +1 -1
- package/module.d.ts +6 -0
- package/module.d.ts.map +1 -1
- package/package.json +28 -12
- package/planet.d.ts +3 -0
- package/planet.d.ts.map +1 -1
- package/worktile-planet.d.ts +1 -1
- package/worktile-planet.d.ts.map +1 -1
- package/application/planet-application-loader.ngfactory.d.ts.map +0 -1
- package/application/planet-application.service.ngfactory.d.ts.map +0 -1
- package/assets-loader.ngfactory.d.ts.map +0 -1
- package/bundles/worktile-planet.umd.js +0 -2564
- package/bundles/worktile-planet.umd.js.map +0 -1
- package/component/planet-component-loader.ngfactory.d.ts.map +0 -1
- package/empty/empty.component.ngfactory.d.ts.map +0 -1
- package/esm2015/application/planet-application-loader.js +0 -457
- package/esm2015/application/planet-application-ref.js +0 -97
- package/esm2015/component/planet-component-loader.js +0 -155
- package/esm2015/empty/empty.component.js +0 -10
- package/esm2015/global-planet.js +0 -54
- package/esm2015/module.js +0 -27
- package/esm2015/planet.js +0 -91
- package/esm2015/worktile-planet.js +0 -6
- package/fesm2015/worktile-planet.js.map +0 -1
- package/global-event-dispatcher.ngfactory.d.ts.map +0 -1
- package/module.ngfactory.d.ts.map +0 -1
- package/planet.ngfactory.d.ts.map +0 -1
- package/worktile-planet.metadata.json +0 -1
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { Injectable, NgZone, ApplicationRef, Injector } from '@angular/core';
|
|
2
|
+
import { of, Subject, forkJoin, from } from 'rxjs';
|
|
3
|
+
import { AssetsLoader } from '../assets-loader';
|
|
4
|
+
import { SwitchModes } from '../planet.class';
|
|
5
|
+
import { switchMap, share, map, tap, distinctUntilChanged, take, filter, catchError } from 'rxjs/operators';
|
|
6
|
+
import { getHTMLElement, coerceArray, createElementByTemplate } from '../helpers';
|
|
7
|
+
import { PlanetPortalApplication } from './portal-application';
|
|
8
|
+
import { PlanetApplicationService } from './planet-application.service';
|
|
9
|
+
import { GlobalEventDispatcher } from '../global-event-dispatcher';
|
|
10
|
+
import { Router } from '@angular/router';
|
|
11
|
+
import { globalPlanet, getPlanetApplicationRef, getApplicationLoader } from '../global-planet';
|
|
12
|
+
import { createDebug } from '../debug';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "../assets-loader";
|
|
15
|
+
import * as i2 from "./planet-application.service";
|
|
16
|
+
import * as i3 from "@angular/router";
|
|
17
|
+
const debug = createDebug('app-loader');
|
|
18
|
+
export var ApplicationStatus;
|
|
19
|
+
(function (ApplicationStatus) {
|
|
20
|
+
ApplicationStatus[ApplicationStatus["assetsLoading"] = 1] = "assetsLoading";
|
|
21
|
+
ApplicationStatus[ApplicationStatus["assetsLoaded"] = 2] = "assetsLoaded";
|
|
22
|
+
ApplicationStatus[ApplicationStatus["bootstrapping"] = 3] = "bootstrapping";
|
|
23
|
+
ApplicationStatus[ApplicationStatus["bootstrapped"] = 4] = "bootstrapped";
|
|
24
|
+
ApplicationStatus[ApplicationStatus["active"] = 5] = "active";
|
|
25
|
+
ApplicationStatus[ApplicationStatus["loadError"] = 10] = "loadError";
|
|
26
|
+
})(ApplicationStatus || (ApplicationStatus = {}));
|
|
27
|
+
export class PlanetApplicationLoader {
|
|
28
|
+
constructor(assetsLoader, planetApplicationService, ngZone, router, injector, applicationRef) {
|
|
29
|
+
this.assetsLoader = assetsLoader;
|
|
30
|
+
this.planetApplicationService = planetApplicationService;
|
|
31
|
+
this.ngZone = ngZone;
|
|
32
|
+
this.firstLoad = true;
|
|
33
|
+
this.inProgressAppAssetsLoads = new Map();
|
|
34
|
+
this.appsStatus = new Map();
|
|
35
|
+
this.portalApp = new PlanetPortalApplication();
|
|
36
|
+
this.routeChange$ = new Subject();
|
|
37
|
+
this.appStatusChange$ = new Subject();
|
|
38
|
+
this.appsLoadingStart$ = new Subject();
|
|
39
|
+
this.loadingDone = false;
|
|
40
|
+
if (getApplicationLoader()) {
|
|
41
|
+
throw new Error('PlanetApplicationLoader has been injected in the portal, repeated injection is not allowed');
|
|
42
|
+
}
|
|
43
|
+
this.options = {
|
|
44
|
+
switchMode: SwitchModes.default,
|
|
45
|
+
errorHandler: (error) => {
|
|
46
|
+
console.error(error);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
this.portalApp.ngZone = ngZone;
|
|
50
|
+
this.portalApp.applicationRef = applicationRef;
|
|
51
|
+
this.portalApp.router = router;
|
|
52
|
+
this.portalApp.injector = injector;
|
|
53
|
+
this.portalApp.globalEventDispatcher = injector.get(GlobalEventDispatcher);
|
|
54
|
+
globalPlanet.portalApplication = this.portalApp;
|
|
55
|
+
this.setupRouteChange();
|
|
56
|
+
}
|
|
57
|
+
get appStatusChange() {
|
|
58
|
+
return this.appStatusChange$.asObservable();
|
|
59
|
+
}
|
|
60
|
+
get appsLoadingStart() {
|
|
61
|
+
return this.appsLoadingStart$.asObservable();
|
|
62
|
+
}
|
|
63
|
+
setAppStatus(app, status) {
|
|
64
|
+
this.ngZone.run(() => {
|
|
65
|
+
const fromStatus = this.appsStatus.get(app);
|
|
66
|
+
debug(`app(${app.name}) status change: ${fromStatus ? ApplicationStatus[fromStatus] : 'empty'} => ${ApplicationStatus[status]}`);
|
|
67
|
+
this.appsStatus.set(app, status);
|
|
68
|
+
this.appStatusChange$.next({
|
|
69
|
+
app: app,
|
|
70
|
+
status: status
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
getAppStatusChange$(app, status = ApplicationStatus.bootstrapped) {
|
|
75
|
+
return this.appStatusChange.pipe(filter(event => {
|
|
76
|
+
return event.app === app && event.status === status;
|
|
77
|
+
}), map(() => {
|
|
78
|
+
return app;
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
switchModeIsCoexist(app) {
|
|
82
|
+
if (app && app.switchMode) {
|
|
83
|
+
return app.switchMode === SwitchModes.coexist;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return this.options.switchMode === SwitchModes.coexist;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
errorHandler(error) {
|
|
90
|
+
this.ngZone.run(() => {
|
|
91
|
+
this.options.errorHandler(error);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
setLoadingDone() {
|
|
95
|
+
this.ngZone.run(() => {
|
|
96
|
+
this.loadingDone = true;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
getAppNames(apps) {
|
|
100
|
+
return apps.length === 0
|
|
101
|
+
? `[]`
|
|
102
|
+
: apps.map(item => {
|
|
103
|
+
return item.name;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
setupRouteChange() {
|
|
107
|
+
this.routeChange$
|
|
108
|
+
.pipe(distinctUntilChanged((x, y) => {
|
|
109
|
+
return (x && x.url) === (y && y.url);
|
|
110
|
+
}),
|
|
111
|
+
// Using switchMap so we cancel executing loading when a new one comes in
|
|
112
|
+
switchMap(event => {
|
|
113
|
+
// Return new observable use of and catchError,
|
|
114
|
+
// in order to prevent routeChange$ completed which never trigger new route change
|
|
115
|
+
return of(event).pipe(
|
|
116
|
+
// unload apps and return should load apps
|
|
117
|
+
map(() => {
|
|
118
|
+
debug(`route change, url is: ${event.url}`);
|
|
119
|
+
this.startRouteChangeEvent = event;
|
|
120
|
+
const shouldLoadApps = this.planetApplicationService.getAppsByMatchedUrl(event.url);
|
|
121
|
+
debug(`should load apps: ${this.getAppNames(shouldLoadApps)}`);
|
|
122
|
+
const shouldUnloadApps = this.getUnloadApps(shouldLoadApps);
|
|
123
|
+
this.appsLoadingStart$.next({
|
|
124
|
+
shouldLoadApps,
|
|
125
|
+
shouldUnloadApps
|
|
126
|
+
});
|
|
127
|
+
this.unloadApps(shouldUnloadApps, event);
|
|
128
|
+
debug(`unload apps: ${this.getAppNames(shouldUnloadApps)}`);
|
|
129
|
+
return shouldLoadApps;
|
|
130
|
+
}),
|
|
131
|
+
// Load app assets (static resources)
|
|
132
|
+
switchMap(shouldLoadApps => {
|
|
133
|
+
let hasAppsNeedLoadingAssets = false;
|
|
134
|
+
const loadApps$ = shouldLoadApps.map(app => {
|
|
135
|
+
const appStatus = this.appsStatus.get(app);
|
|
136
|
+
if (!appStatus ||
|
|
137
|
+
appStatus === ApplicationStatus.assetsLoading ||
|
|
138
|
+
appStatus === ApplicationStatus.loadError) {
|
|
139
|
+
debug(`app(${app.name}) status is ${ApplicationStatus[appStatus]}, start load assets`);
|
|
140
|
+
hasAppsNeedLoadingAssets = true;
|
|
141
|
+
return this.ngZone.runOutsideAngular(() => {
|
|
142
|
+
return this.startLoadAppAssets(app);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
return of(app);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
if (hasAppsNeedLoadingAssets) {
|
|
150
|
+
this.loadingDone = false;
|
|
151
|
+
}
|
|
152
|
+
return loadApps$.length > 0 ? forkJoin(loadApps$) : of([]);
|
|
153
|
+
}),
|
|
154
|
+
// Bootstrap or show apps
|
|
155
|
+
map(apps => {
|
|
156
|
+
const apps$ = apps.map(app => {
|
|
157
|
+
return of(app).pipe(switchMap(app => {
|
|
158
|
+
const appStatus = this.appsStatus.get(app);
|
|
159
|
+
if (appStatus === ApplicationStatus.bootstrapped) {
|
|
160
|
+
debug(`[routeChange] app(${app.name}) status is bootstrapped, show app and active`);
|
|
161
|
+
this.showApp(app);
|
|
162
|
+
const appRef = getPlanetApplicationRef(app.name);
|
|
163
|
+
appRef?.navigateByUrl(event.url);
|
|
164
|
+
this.setAppStatus(app, ApplicationStatus.active);
|
|
165
|
+
this.setLoadingDone();
|
|
166
|
+
return of(app);
|
|
167
|
+
}
|
|
168
|
+
else if (appStatus === ApplicationStatus.assetsLoaded) {
|
|
169
|
+
debug(`[routeChange] app(${app.name}) status is assetsLoaded, start bootstrapping`);
|
|
170
|
+
return this.bootstrapApp(app).pipe(map(() => {
|
|
171
|
+
debug(`app(${app.name}) bootstrapped success, active it`);
|
|
172
|
+
this.setAppStatus(app, ApplicationStatus.active);
|
|
173
|
+
this.setLoadingDone();
|
|
174
|
+
return app;
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
else if (appStatus === ApplicationStatus.active) {
|
|
178
|
+
debug(`[routeChange] app(${app.name}) is active, do nothings`);
|
|
179
|
+
const appRef = getPlanetApplicationRef(app.name);
|
|
180
|
+
// Backwards compatibility sub app use old version which has not getCurrentRouterStateUrl
|
|
181
|
+
const currentUrl = appRef?.getCurrentRouterStateUrl
|
|
182
|
+
? appRef.getCurrentRouterStateUrl()
|
|
183
|
+
: '';
|
|
184
|
+
if (currentUrl !== event.url) {
|
|
185
|
+
appRef?.navigateByUrl(event.url);
|
|
186
|
+
}
|
|
187
|
+
return of(app);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
debug(`[routeChange] app(${app.name}) status is ${ApplicationStatus[appStatus]}`);
|
|
191
|
+
return this.getAppStatusChange$(app).pipe(take(1), map(() => {
|
|
192
|
+
debug(`app(${app.name}) status is bootstrapped by subscribe status change, active it`);
|
|
193
|
+
this.setAppStatus(app, ApplicationStatus.active);
|
|
194
|
+
this.showApp(app);
|
|
195
|
+
return app;
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
}));
|
|
199
|
+
});
|
|
200
|
+
if (apps$.length > 0) {
|
|
201
|
+
debug(`start load and active apps: ${this.getAppNames(apps)}`);
|
|
202
|
+
// 切换到应用后会有闪烁现象,所以使用 setTimeout 后启动应用
|
|
203
|
+
// example: redirect to app1's dashboard from portal's about page
|
|
204
|
+
// If app's route has redirect, it doesn't work, it ok just in setTimeout, I don't know why.
|
|
205
|
+
// TODO:: remove it, it is ok in version Angular 9.x
|
|
206
|
+
setTimeout(() => {
|
|
207
|
+
// 此处判断是因为如果静态资源加载完毕还未启动被取消,还是会启动之前的应用,虽然可能性比较小,但是无法排除这种可能性,所以只有当 Event 是最后一个才会启动
|
|
208
|
+
if (this.startRouteChangeEvent === event) {
|
|
209
|
+
// runOutsideAngular for fix error: `Expected to not be in Angular Zone, but it is!`
|
|
210
|
+
this.ngZone.runOutsideAngular(() => {
|
|
211
|
+
forkJoin(apps$).subscribe(() => {
|
|
212
|
+
this.setLoadingDone();
|
|
213
|
+
this.ensurePreloadApps(apps);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
debug(`no apps need to be loaded, ensure preload apps`);
|
|
221
|
+
this.ensurePreloadApps(apps);
|
|
222
|
+
this.setLoadingDone();
|
|
223
|
+
}
|
|
224
|
+
}),
|
|
225
|
+
// Error handler
|
|
226
|
+
catchError(error => {
|
|
227
|
+
debug(`apps loader error: ${error}`);
|
|
228
|
+
this.errorHandler(error);
|
|
229
|
+
return [];
|
|
230
|
+
}));
|
|
231
|
+
}))
|
|
232
|
+
.subscribe();
|
|
233
|
+
}
|
|
234
|
+
startLoadAppAssets(app) {
|
|
235
|
+
if (this.inProgressAppAssetsLoads.get(app.name)) {
|
|
236
|
+
return this.inProgressAppAssetsLoads.get(app.name);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
const loadApp$ = this.assetsLoader.loadAppAssets(app).pipe(tap(() => {
|
|
240
|
+
this.inProgressAppAssetsLoads.delete(app.name);
|
|
241
|
+
this.setAppStatus(app, ApplicationStatus.assetsLoaded);
|
|
242
|
+
}), map(() => {
|
|
243
|
+
return app;
|
|
244
|
+
}), catchError(error => {
|
|
245
|
+
this.inProgressAppAssetsLoads.delete(app.name);
|
|
246
|
+
this.setAppStatus(app, ApplicationStatus.loadError);
|
|
247
|
+
throw error;
|
|
248
|
+
}), share());
|
|
249
|
+
this.inProgressAppAssetsLoads.set(app.name, loadApp$);
|
|
250
|
+
this.setAppStatus(app, ApplicationStatus.assetsLoading);
|
|
251
|
+
return loadApp$;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
hideApp(planetApp) {
|
|
255
|
+
const appRef = getPlanetApplicationRef(planetApp.name);
|
|
256
|
+
const appRootElement = document.querySelector(appRef?.selector || planetApp.selector);
|
|
257
|
+
if (appRootElement) {
|
|
258
|
+
appRootElement.setAttribute('style', 'display:none;');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
showApp(planetApp) {
|
|
262
|
+
const appRef = getPlanetApplicationRef(planetApp.name);
|
|
263
|
+
const appRootElement = document.querySelector(appRef?.selector || planetApp.selector);
|
|
264
|
+
if (appRootElement) {
|
|
265
|
+
appRootElement.setAttribute('style', '');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
destroyApp(planetApp) {
|
|
269
|
+
const appRef = getPlanetApplicationRef(planetApp.name);
|
|
270
|
+
if (appRef) {
|
|
271
|
+
appRef.destroy();
|
|
272
|
+
}
|
|
273
|
+
const container = getHTMLElement(planetApp.hostParent);
|
|
274
|
+
const appRootElement = container?.querySelector((appRef && appRef.selector) || planetApp.selector);
|
|
275
|
+
if (appRootElement) {
|
|
276
|
+
container?.removeChild(appRootElement);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
bootstrapApp(app, defaultStatus = 'display') {
|
|
280
|
+
debug(`app(${app.name}) start bootstrapping`);
|
|
281
|
+
this.setAppStatus(app, ApplicationStatus.bootstrapping);
|
|
282
|
+
const appRef = getPlanetApplicationRef(app.name);
|
|
283
|
+
if (appRef && appRef.bootstrap) {
|
|
284
|
+
const container = getHTMLElement(app.hostParent);
|
|
285
|
+
let appRootElement;
|
|
286
|
+
if (container) {
|
|
287
|
+
appRootElement = container.querySelector(appRef.selector || app.selector);
|
|
288
|
+
if (!appRootElement) {
|
|
289
|
+
if (appRef.template) {
|
|
290
|
+
appRootElement = createElementByTemplate(appRef.template);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
appRootElement = document.createElement(app.selector);
|
|
294
|
+
}
|
|
295
|
+
appRootElement.setAttribute('style', 'display:none;');
|
|
296
|
+
if (app.hostClass) {
|
|
297
|
+
appRootElement.classList.add(...coerceArray(app.hostClass));
|
|
298
|
+
}
|
|
299
|
+
if (app.stylePrefix) {
|
|
300
|
+
appRootElement.classList.add(...coerceArray(app.stylePrefix));
|
|
301
|
+
}
|
|
302
|
+
container.appendChild(appRootElement);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
let result = appRef.bootstrap(this.portalApp);
|
|
306
|
+
// Backwards compatibility promise for bootstrap
|
|
307
|
+
if (result['then']) {
|
|
308
|
+
result = from(result);
|
|
309
|
+
}
|
|
310
|
+
return result.pipe(tap(() => {
|
|
311
|
+
debug(`app(${app.name}) bootstrapped success for ${defaultStatus}`);
|
|
312
|
+
this.setAppStatus(app, ApplicationStatus.bootstrapped);
|
|
313
|
+
if (defaultStatus === 'display' && appRootElement) {
|
|
314
|
+
appRootElement.removeAttribute('style');
|
|
315
|
+
}
|
|
316
|
+
}), map(() => {
|
|
317
|
+
return appRef;
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
throw new Error(`[${app.name}] not found, make sure that the app has the correct name defined use defineApplication(${app.name}) and runtimeChunk and vendorChunk are set to true, details see https://github.com/worktile/ngx-planet#throw-error-cannot-read-property-call-of-undefined-at-__webpack_require__-bootstrap79`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
getUnloadApps(activeApps) {
|
|
325
|
+
const unloadApps = [];
|
|
326
|
+
this.appsStatus.forEach((value, app) => {
|
|
327
|
+
if (value === ApplicationStatus.active && !activeApps.find(item => item.name === app.name)) {
|
|
328
|
+
unloadApps.push(app);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
return unloadApps;
|
|
332
|
+
}
|
|
333
|
+
unloadApps(shouldUnloadApps, event) {
|
|
334
|
+
const hideApps = [];
|
|
335
|
+
const destroyApps = [];
|
|
336
|
+
shouldUnloadApps.forEach(app => {
|
|
337
|
+
if (this.switchModeIsCoexist(app)) {
|
|
338
|
+
debug(`hide app(${app.name}) for coexist mode`);
|
|
339
|
+
hideApps.push(app);
|
|
340
|
+
this.hideApp(app);
|
|
341
|
+
this.setAppStatus(app, ApplicationStatus.bootstrapped);
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
destroyApps.push(app);
|
|
345
|
+
// 销毁之前先隐藏,否则会出现闪烁,因为 destroy 是延迟执行的
|
|
346
|
+
// 如果销毁不延迟执行,会出现切换到主应用的时候会有视图卡顿现象
|
|
347
|
+
this.hideApp(app);
|
|
348
|
+
this.setAppStatus(app, ApplicationStatus.assetsLoaded);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
if (hideApps.length > 0 || destroyApps.length > 0) {
|
|
352
|
+
// 从其他应用切换到主应用的时候会有视图卡顿现象,所以先等主应用渲染完毕后再加载其他应用
|
|
353
|
+
// 此处尝试使用 this.ngZone.onStable.pipe(take(1)) 应用之间的切换会出现闪烁
|
|
354
|
+
setTimeout(() => {
|
|
355
|
+
hideApps.forEach(app => {
|
|
356
|
+
const appRef = getPlanetApplicationRef(app.name);
|
|
357
|
+
if (appRef) {
|
|
358
|
+
appRef.navigateByUrl(event.url);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
destroyApps.forEach(app => {
|
|
362
|
+
debug(`destroy app(${app.name})`);
|
|
363
|
+
this.destroyApp(app);
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
preloadApps(activeApps) {
|
|
369
|
+
setTimeout(() => {
|
|
370
|
+
const toPreloadApps = this.planetApplicationService.getAppsToPreload(activeApps ? activeApps.map(item => item.name) : undefined);
|
|
371
|
+
debug(`start preload apps: ${this.getAppNames(toPreloadApps)}`);
|
|
372
|
+
const loadApps$ = toPreloadApps.map(preloadApp => {
|
|
373
|
+
return this.preloadInternal(preloadApp);
|
|
374
|
+
});
|
|
375
|
+
forkJoin(loadApps$).subscribe({
|
|
376
|
+
error: error => {
|
|
377
|
+
this.errorHandler(error);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
ensurePreloadApps(activeApps) {
|
|
383
|
+
// Start preload apps
|
|
384
|
+
// Start preload when first time app loaded
|
|
385
|
+
if (this.firstLoad) {
|
|
386
|
+
this.preloadApps(activeApps);
|
|
387
|
+
this.firstLoad = false;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
setOptions(options) {
|
|
391
|
+
this.options = {
|
|
392
|
+
...this.options,
|
|
393
|
+
...options
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* reset route by current router
|
|
398
|
+
*/
|
|
399
|
+
reroute(event) {
|
|
400
|
+
this.routeChange$.next(event);
|
|
401
|
+
}
|
|
402
|
+
preloadInternal(app, immediate) {
|
|
403
|
+
const status = this.appsStatus.get(app);
|
|
404
|
+
if (!status || status === ApplicationStatus.loadError) {
|
|
405
|
+
debug(`preload app(${app.name}), status is empty, start to load assets`);
|
|
406
|
+
return this.startLoadAppAssets(app).pipe(switchMap(() => {
|
|
407
|
+
debug(`preload app(${app.name}), assets loaded, start bootstrap app, immediate: ${!!immediate}`);
|
|
408
|
+
if (immediate) {
|
|
409
|
+
return this.bootstrapApp(app, 'hidden');
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
return this.ngZone.runOutsideAngular(() => {
|
|
413
|
+
return this.bootstrapApp(app, 'hidden');
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
}), catchError(error => {
|
|
417
|
+
this.errorHandler(error);
|
|
418
|
+
return of(null);
|
|
419
|
+
}), map(() => {
|
|
420
|
+
return getPlanetApplicationRef(app.name);
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
else if ([ApplicationStatus.assetsLoading, ApplicationStatus.assetsLoaded, ApplicationStatus.bootstrapping].includes(status)) {
|
|
424
|
+
debug(`preload app(${app.name}), status is ${ApplicationStatus[status]}, return until bootstrapped`);
|
|
425
|
+
return this.getAppStatusChange$(app).pipe(take(1), map(() => {
|
|
426
|
+
return getPlanetApplicationRef(app.name);
|
|
427
|
+
}));
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
const appRef = getPlanetApplicationRef(app.name);
|
|
431
|
+
if (!appRef) {
|
|
432
|
+
throw new Error(`${app.name}'s status is ${ApplicationStatus[status]}, planetApplicationRef is null.`);
|
|
433
|
+
}
|
|
434
|
+
return of(appRef);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Preload planet application
|
|
439
|
+
* @param app app
|
|
440
|
+
* @param immediate bootstrap on stable by default, setting immediate is true, it will bootstrap immediate
|
|
441
|
+
*/
|
|
442
|
+
preload(app, immediate) {
|
|
443
|
+
return this.preloadInternal(app, immediate);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
PlanetApplicationLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.6", ngImport: i0, type: PlanetApplicationLoader, deps: [{ token: i1.AssetsLoader }, { token: i2.PlanetApplicationService }, { token: i0.NgZone }, { token: i3.Router }, { token: i0.Injector }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
447
|
+
PlanetApplicationLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.6", ngImport: i0, type: PlanetApplicationLoader, providedIn: 'root' });
|
|
448
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.6", ngImport: i0, type: PlanetApplicationLoader, decorators: [{
|
|
449
|
+
type: Injectable,
|
|
450
|
+
args: [{
|
|
451
|
+
providedIn: 'root'
|
|
452
|
+
}]
|
|
453
|
+
}], ctorParameters: function () { return [{ type: i1.AssetsLoader }, { type: i2.PlanetApplicationService }, { type: i0.NgZone }, { type: i3.Router }, { type: i0.Injector }, { type: i0.ApplicationRef }]; } });
|
|
454
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbmV0LWFwcGxpY2F0aW9uLWxvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL3BsYW5ldC9zcmMvYXBwbGljYXRpb24vcGxhbmV0LWFwcGxpY2F0aW9uLWxvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBRSxFQUFFLEVBQWMsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFBd0MsV0FBVyxFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ25HLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RyxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVsRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSx1QkFBdUIsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQy9GLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7Ozs7O0FBQ3ZDLE1BQU0sS0FBSyxHQUFHLFdBQVcs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QyxJQUFJLGdCQUFnQixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsaUNBQWlDLENBQUMsQ0FBQzthQUMxRztZQUNELE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3JCO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxPQUFPLENBQUMsR0FBc0IsRUFBRSxTQUFtQjtRQUN0RCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ2hELENBQUM7O29IQTlmUSx1QkFBdUI7d0hBQXZCLHVCQUF1QixjQUZwQixNQUFNOzJGQUVULHVCQUF1QjtrQkFIbkMsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBOZ1pvbmUsIEFwcGxpY2F0aW9uUmVmLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgb2YsIE9ic2VydmFibGUsIFN1YmplY3QsIGZvcmtKb2luLCBmcm9tLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBBc3NldHNMb2FkZXIgfSBmcm9tICcuLi9hc3NldHMtbG9hZGVyJztcbmltcG9ydCB7IFBsYW5ldEFwcGxpY2F0aW9uLCBQbGFuZXRSb3V0ZXJFdmVudCwgU3dpdGNoTW9kZXMsIFBsYW5ldE9wdGlvbnMgfSBmcm9tICcuLi9wbGFuZXQuY2xhc3MnO1xuaW1wb3J0IHsgc3dpdGNoTWFwLCBzaGFyZSwgbWFwLCB0YXAsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCB0YWtlLCBmaWx0ZXIsIGNhdGNoRXJyb3IgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBnZXRIVE1MRWxlbWVudCwgY29lcmNlQXJyYXksIGNyZWF0ZUVsZW1lbnRCeVRlbXBsYXRlIH0gZnJvbSAnLi4vaGVscGVycyc7XG5pbXBvcnQgeyBQbGFuZXRBcHBsaWNhdGlvblJlZiB9IGZyb20gJy4vcGxhbmV0LWFwcGxpY2F0aW9uLXJlZic7XG5pbXBvcnQgeyBQbGFuZXRQb3J0YWxBcHBsaWNhdGlvbiB9IGZyb20gJy4vcG9ydGFsLWFwcGxpY2F0aW9uJztcbmltcG9ydCB7IFBsYW5ldEFwcGxpY2F0aW9uU2VydmljZSB9IGZyb20gJy4vcGxhbmV0LWFwcGxpY2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgR2xvYmFsRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vZ2xvYmFsLWV2ZW50LWRpc3BhdGNoZXInO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IGdsb2JhbFBsYW5ldCwgZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYsIGdldEFwcGxpY2F0aW9uTG9hZGVyIH0gZnJvbSAnLi4vZ2xvYmFsLXBsYW5ldCc7XG5pbXBvcnQgeyBjcmVhdGVEZWJ1ZyB9IGZyb20gJy4uL2RlYnVnJztcbmNvbnN0IGRlYnVnID0gY3JlYXRlRGVidWcoJ2FwcC1sb2FkZXInKTtcblxuZXhwb3J0IGVudW0gQXBwbGljYXRpb25TdGF0dXMge1xuICAgIGFzc2V0c0xvYWRpbmcgPSAxLFxuICAgIGFzc2V0c0xvYWRlZCA9IDIsXG4gICAgYm9vdHN0cmFwcGluZyA9IDMsXG4gICAgYm9vdHN0cmFwcGVkID0gNCxcbiAgICBhY3RpdmUgPSA1LFxuICAgIGxvYWRFcnJvciA9IDEwXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwc0xvYWRpbmdTdGFydEV2ZW50IHtcbiAgICBzaG91bGRMb2FkQXBwczogUGxhbmV0QXBwbGljYXRpb25bXTtcbiAgICBzaG91bGRVbmxvYWRBcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFwcFN0YXR1c0NoYW5nZUV2ZW50IHtcbiAgICBhcHA6IFBsYW5ldEFwcGxpY2F0aW9uO1xuICAgIHN0YXR1czogQXBwbGljYXRpb25TdGF0dXM7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgUGxhbmV0QXBwbGljYXRpb25Mb2FkZXIge1xuICAgIHByaXZhdGUgZmlyc3RMb2FkID0gdHJ1ZTtcblxuICAgIHByaXZhdGUgc3RhcnRSb3V0ZUNoYW5nZUV2ZW50ITogUGxhbmV0Um91dGVyRXZlbnQ7XG5cbiAgICBwcml2YXRlIG9wdGlvbnM6IFBsYW5ldE9wdGlvbnM7XG5cbiAgICBwcml2YXRlIGluUHJvZ3Jlc3NBcHBBc3NldHNMb2FkcyA9IG5ldyBNYXA8c3RyaW5nLCBPYnNlcnZhYmxlPFBsYW5ldEFwcGxpY2F0aW9uPj4oKTtcblxuICAgIHByaXZhdGUgYXBwc1N0YXR1cyA9IG5ldyBNYXA8UGxhbmV0QXBwbGljYXRpb24sIEFwcGxpY2F0aW9uU3RhdHVzPigpO1xuXG4gICAgcHJpdmF0ZSBwb3J0YWxBcHAgPSBuZXcgUGxhbmV0UG9ydGFsQXBwbGljYXRpb24oKTtcblxuICAgIHByaXZhdGUgcm91dGVDaGFuZ2UkID0gbmV3IFN1YmplY3Q8UGxhbmV0Um91dGVyRXZlbnQ+KCk7XG5cbiAgICBwcml2YXRlIGFwcFN0YXR1c0NoYW5nZSQgPSBuZXcgU3ViamVjdDxBcHBTdGF0dXNDaGFuZ2VFdmVudD4oKTtcblxuICAgIHByaXZhdGUgYXBwc0xvYWRpbmdTdGFydCQgPSBuZXcgU3ViamVjdDxBcHBzTG9hZGluZ1N0YXJ0RXZlbnQ+KCk7XG5cbiAgICBwdWJsaWMgZ2V0IGFwcFN0YXR1c0NoYW5nZSgpOiBPYnNlcnZhYmxlPEFwcFN0YXR1c0NoYW5nZUV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcFN0YXR1c0NoYW5nZSQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhcHBzTG9hZGluZ1N0YXJ0KCk6IE9ic2VydmFibGU8QXBwc0xvYWRpbmdTdGFydEV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcHNMb2FkaW5nU3RhcnQkLmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2FkaW5nRG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgYXNzZXRzTG9hZGVyOiBBc3NldHNMb2FkZXIsXG4gICAgICAgIHByaXZhdGUgcGxhbmV0QXBwbGljYXRpb25TZXJ2aWNlOiBQbGFuZXRBcHBsaWNhdGlvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgICAgIHJvdXRlcjogUm91dGVyLFxuICAgICAgICBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgIGFwcGxpY2F0aW9uUmVmOiBBcHBsaWNhdGlvblJlZlxuICAgICkge1xuICAgICAgICBpZiAoZ2V0QXBwbGljYXRpb25Mb2FkZXIoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdQbGFuZXRBcHBsaWNhdGlvbkxvYWRlciBoYXMgYmVlbiBpbmplY3RlZCBpbiB0aGUgcG9ydGFsLCByZXBlYXRlZCBpbmplY3Rpb24gaXMgbm90IGFsbG93ZWQnXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgc3dpdGNoTW9kZTogU3dpdGNoTW9kZXMuZGVmYXVsdCxcbiAgICAgICAgICAgIGVycm9ySGFuZGxlcjogKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnBvcnRhbEFwcC5uZ1pvbmUgPSBuZ1pvbmU7XG4gICAgICAgIHRoaXMucG9ydGFsQXBwLmFwcGxpY2F0aW9uUmVmID0gYXBwbGljYXRpb25SZWY7XG4gICAgICAgIHRoaXMucG9ydGFsQXBwLnJvdXRlciA9IHJvdXRlcjtcbiAgICAgICAgdGhpcy5wb3J0YWxBcHAuaW5qZWN0b3IgPSBpbmplY3RvcjtcbiAgICAgICAgdGhpcy5wb3J0YWxBcHAuZ2xvYmFsRXZlbnREaXNwYXRjaGVyID0gaW5qZWN0b3IuZ2V0KEdsb2JhbEV2ZW50RGlzcGF0Y2hlcik7XG4gICAgICAgIGdsb2JhbFBsYW5ldC5wb3J0YWxBcHBsaWNhdGlvbiA9IHRoaXMucG9ydGFsQXBwO1xuICAgICAgICB0aGlzLnNldHVwUm91dGVDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEFwcFN0YXR1cyhhcHA6IFBsYW5ldEFwcGxpY2F0aW9uLCBzdGF0dXM6IEFwcGxpY2F0aW9uU3RhdHVzKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmcm9tU3RhdHVzID0gdGhpcy5hcHBzU3RhdHVzLmdldChhcHApO1xuICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgYGFwcCgke2FwcC5uYW1lfSkgc3RhdHVzIGNoYW5nZTogJHtmcm9tU3RhdHVzID8gQXBwbGljYXRpb25TdGF0dXNbZnJvbVN0YXR1c10gOiAnZW1wdHknfSA9PiAke1xuICAgICAgICAgICAgICAgICAgICBBcHBsaWNhdGlvblN0YXR1c1tzdGF0dXNdXG4gICAgICAgICAgICAgICAgfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmFwcHNTdGF0dXMuc2V0KGFwcCwgc3RhdHVzKTtcbiAgICAgICAgICAgIHRoaXMuYXBwU3RhdHVzQ2hhbmdlJC5uZXh0KHtcbiAgICAgICAgICAgICAgICBhcHA6IGFwcCxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1c1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0QXBwU3RhdHVzQ2hhbmdlJChcbiAgICAgICAgYXBwOiBQbGFuZXRBcHBsaWNhdGlvbixcbiAgICAgICAgc3RhdHVzID0gQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGVkXG4gICAgKTogT2JzZXJ2YWJsZTxQbGFuZXRBcHBsaWNhdGlvbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHBTdGF0dXNDaGFuZ2UucGlwZShcbiAgICAgICAgICAgIGZpbHRlcihldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmFwcCA9PT0gYXBwICYmIGV2ZW50LnN0YXR1cyA9PT0gc3RhdHVzO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcHA7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3dpdGNoTW9kZUlzQ29leGlzdChhcHA6IFBsYW5ldEFwcGxpY2F0aW9uKSB7XG4gICAgICAgIGlmIChhcHAgJiYgYXBwLnN3aXRjaE1vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBhcHAuc3dpdGNoTW9kZSA9PT0gU3dpdGNoTW9kZXMuY29leGlzdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuc3dpdGNoTW9kZSA9PT0gU3dpdGNoTW9kZXMuY29leGlzdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZXJyb3JIYW5kbGVyKGVycm9yOiBFcnJvcikge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLmVycm9ySGFuZGxlcihlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0TG9hZGluZ0RvbmUoKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmxvYWRpbmdEb25lID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRBcHBOYW1lcyhhcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdKTogc3RyaW5nIHwgc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gYXBwcy5sZW5ndGggPT09IDBcbiAgICAgICAgICAgID8gYFtdYFxuICAgICAgICAgICAgOiBhcHBzLm1hcChpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLm5hbWU7XG4gICAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0dXBSb3V0ZUNoYW5nZSgpIHtcbiAgICAgICAgdGhpcy5yb3V0ZUNoYW5nZSRcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCh4LCB5KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoeCAmJiB4LnVybCkgPT09ICh5ICYmIHkudXJsKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAvLyBVc2luZyBzd2l0Y2hNYXAgc28gd2UgY2FuY2VsIGV4ZWN1dGluZyBsb2FkaW5nIHdoZW4gYSBuZXcgb25lIGNvbWVzIGluXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmV0dXJuIG5ldyBvYnNlcnZhYmxlIHVzZSBvZiBhbmQgY2F0Y2hFcnJvcixcbiAgICAgICAgICAgICAgICAgICAgLy8gaW4gb3JkZXIgdG8gcHJldmVudCByb3V0ZUNoYW5nZSQgY29tcGxldGVkIHdoaWNoIG5ldmVyIHRyaWdnZXIgbmV3IHJvdXRlIGNoYW5nZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YoZXZlbnQpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmxvYWQgYXBwcyBhbmQgcmV0dXJuIHNob3VsZCBsb2FkIGFwcHNcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYHJvdXRlIGNoYW5nZSwgdXJsIGlzOiAke2V2ZW50LnVybH1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0Um91dGVDaGFuZ2VFdmVudCA9IGV2ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZExvYWRBcHBzID0gdGhpcy5wbGFuZXRBcHBsaWNhdGlvblNlcnZpY2UuZ2V0QXBwc0J5TWF0Y2hlZFVybChldmVudC51cmwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKGBzaG91bGQgbG9hZCBhcHBzOiAke3RoaXMuZ2V0QXBwTmFtZXMoc2hvdWxkTG9hZEFwcHMpfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZFVubG9hZEFwcHMgPSB0aGlzLmdldFVubG9hZEFwcHMoc2hvdWxkTG9hZEFwcHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwc0xvYWRpbmdTdGFydCQubmV4dCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZExvYWRBcHBzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGRVbmxvYWRBcHBzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bmxvYWRBcHBzKHNob3VsZFVubG9hZEFwcHMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhgdW5sb2FkIGFwcHM6ICR7dGhpcy5nZXRBcHBOYW1lcyhzaG91bGRVbmxvYWRBcHBzKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2hvdWxkTG9hZEFwcHM7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIExvYWQgYXBwIGFzc2V0cyAoc3RhdGljIHJlc291cmNlcylcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcChzaG91bGRMb2FkQXBwcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGhhc0FwcHNOZWVkTG9hZGluZ0Fzc2V0cyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvYWRBcHBzJCA9IHNob3VsZExvYWRBcHBzLm1hcChhcHAgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBTdGF0dXMgPSB0aGlzLmFwcHNTdGF0dXMuZ2V0KGFwcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFhcHBTdGF0dXMgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcFN0YXR1cyA9PT0gQXBwbGljYXRpb25TdGF0dXMuYXNzZXRzTG9hZGluZyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwU3RhdHVzID09PSBBcHBsaWNhdGlvblN0YXR1cy5sb2FkRXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgYXBwKCR7YXBwLm5hbWV9KSBzdGF0dXMgaXMgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBwbGljYXRpb25TdGF0dXNbYXBwU3RhdHVzIGFzIEFwcGxpY2F0aW9uU3RhdHVzXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIHN0YXJ0IGxvYWQgYXNzZXRzYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc0FwcHNOZWVkTG9hZGluZ0Fzc2V0cyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0TG9hZEFwcEFzc2V0cyhhcHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YoYXBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNBcHBzTmVlZExvYWRpbmdBc3NldHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nRG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbG9hZEFwcHMkLmxlbmd0aCA+IDAgPyBmb3JrSm9pbihsb2FkQXBwcyQpIDogb2YoW10gYXMgUGxhbmV0QXBwbGljYXRpb25bXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJvb3RzdHJhcCBvciBzaG93IGFwcHNcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcChhcHBzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBzJDogT2JzZXJ2YWJsZTxQbGFuZXRBcHBsaWNhdGlvbj5bXSA9IGFwcHMubWFwKGFwcCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihhcHApLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoYXBwID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBTdGF0dXMgPSB0aGlzLmFwcHNTdGF0dXMuZ2V0KGFwcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcFN0YXR1cyA9PT0gQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFtyb3V0ZUNoYW5nZV0gYXBwKCR7YXBwLm5hbWV9KSBzdGF0dXMgaXMgYm9vdHN0cmFwcGVkLCBzaG93IGFwcCBhbmQgYWN0aXZlYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dBcHAoYXBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXBwUmVmID0gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYoYXBwLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBSZWY/Lm5hdmlnYXRlQnlVcmwoZXZlbnQudXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5hY3RpdmUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldExvYWRpbmdEb25lKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihhcHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBwU3RhdHVzID09PSBBcHBsaWNhdGlvblN0YXR1cy5hc3NldHNMb2FkZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgW3JvdXRlQ2hhbmdlXSBhcHAoJHthcHAubmFtZX0pIHN0YXR1cyBpcyBhc3NldHNMb2FkZWQsIHN0YXJ0IGJvb3RzdHJhcHBpbmdgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJvb3RzdHJhcEFwcChhcHApLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKGBhcHAoJHthcHAubmFtZX0pIGJvb3RzdHJhcHBlZCBzdWNjZXNzLCBhY3RpdmUgaXRgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmFjdGl2ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRMb2FkaW5nRG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBwU3RhdHVzID09PSBBcHBsaWNhdGlvblN0YXR1cy5hY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYFtyb3V0ZUNoYW5nZV0gYXBwKCR7YXBwLm5hbWV9KSBpcyBhY3RpdmUsIGRvIG5vdGhpbmdzYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFwcFJlZiA9IGdldFBsYW5ldEFwcGxpY2F0aW9uUmVmKGFwcC5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmFja3dhcmRzIGNvbXBhdGliaWxpdHkgc3ViIGFwcCB1c2Ugb2xkIHZlcnNpb24gd2hpY2ggaGFzIG5vdCBnZXRDdXJyZW50Um91dGVyU3RhdGVVcmxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFVybCA9IGFwcFJlZj8uZ2V0Q3VycmVudFJvdXRlclN0YXRlVXJsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFwcFJlZi5nZXRDdXJyZW50Um91dGVyU3RhdGVVcmwoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRVcmwgIT09IGV2ZW50LnVybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwUmVmPy5uYXZpZ2F0ZUJ5VXJsKGV2ZW50LnVybCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKGFwcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgW3JvdXRlQ2hhbmdlXSBhcHAoJHthcHAubmFtZX0pIHN0YXR1cyBpcyAke1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwcGxpY2F0aW9uU3RhdHVzW2FwcFN0YXR1cyBhcyBBcHBsaWNhdGlvblN0YXR1c11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEFwcFN0YXR1c0NoYW5nZSQoYXBwKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBhcHAoJHthcHAubmFtZX0pIHN0YXR1cyBpcyBib290c3RyYXBwZWQgYnkgc3Vic2NyaWJlIHN0YXR1cyBjaGFuZ2UsIGFjdGl2ZSBpdGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QXBwU3RhdHVzKGFwcCwgQXBwbGljYXRpb25TdGF0dXMuYWN0aXZlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dBcHAoYXBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXBwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcHMkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYHN0YXJ0IGxvYWQgYW5kIGFjdGl2ZSBhcHBzOiAke3RoaXMuZ2V0QXBwTmFtZXMoYXBwcyl9YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIOWIh+aNouWIsOW6lOeUqOWQjuS8muaciemXqueDgeeOsOixoe+8jOaJgOS7peS9v+eUqCBzZXRUaW1lb3V0IOWQjuWQr+WKqOW6lOeUqFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleGFtcGxlOiByZWRpcmVjdCB0byBhcHAxJ3MgZGFzaGJvYXJkIGZyb20gcG9ydGFsJ3MgYWJvdXQgcGFnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBhcHAncyByb3V0ZSBoYXMgcmVkaXJlY3QsIGl0IGRvZXNuJ3Qgd29yaywgaXQgb2sganVzdCBpbiBzZXRUaW1lb3V0LCBJIGRvbid0IGtub3cgd2h5LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOjogcmVtb3ZlIGl0LCBpdCBpcyBvayBpbiB2ZXJzaW9uIEFuZ3VsYXIgOS54XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g5q2k5aSE5Yik5pat5piv5Zug5Li65aaC5p6c6Z2Z5oCB6LWE5rqQ5Yqg6L295a6M5q+V6L+Y5pyq5ZCv5Yqo6KKr5Y+W5raI77yM6L+Y5piv5Lya5ZCv5Yqo5LmL5YmN55qE5bqU55So77yM6Jm954S25Y+v6IO95oCn5q+U6L6D5bCP77yM5L2G5piv5peg5rOV5o6S6Zmk6L+Z56eN5Y+v6IO95oCn77yM5omA5Lul5Y+q5pyJ5b2TIEV2ZW50IOaYr+acgOWQjuS4gOS4quaJjeS8muWQr+WKqFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhcnRSb3V0ZUNoYW5nZUV2ZW50ID09PSBldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJ1bk91dHNpZGVBbmd1bGFyIGZvciBmaXggZXJyb3I6IGBFeHBlY3RlZCB0byBub3QgYmUgaW4gQW5ndWxhciBab25lLCBidXQgaXQgaXMhYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ya0pvaW4oYXBwcyQpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldExvYWRpbmdEb25lKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVuc3VyZVByZWxvYWRBcHBzKGFwcHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYG5vIGFwcHMgbmVlZCB0byBiZSBsb2FkZWQsIGVuc3VyZSBwcmVsb2FkIGFwcHNgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbnN1cmVQcmVsb2FkQXBwcyhhcHBzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRMb2FkaW5nRG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXJyb3IgaGFuZGxlclxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYGFwcHMgbG9hZGVyIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGFydExvYWRBcHBBc3NldHMoYXBwOiBQbGFuZXRBcHBsaWNhdGlvbik6IE9ic2VydmFibGU8UGxhbmV0QXBwbGljYXRpb24+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5Qcm9ncmVzc0FwcEFzc2V0c0xvYWRzLmdldChhcHAubmFtZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmluUHJvZ3Jlc3NBcHBBc3NldHNMb2Fkcy5nZXQoYXBwLm5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbG9hZEFwcCQgPSB0aGlzLmFzc2V0c0xvYWRlci5sb2FkQXBwQXNzZXRzKGFwcCkucGlwZShcbiAgICAgICAgICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluUHJvZ3Jlc3NBcHBBc3NldHNMb2Fkcy5kZWxldGUoYXBwLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRlZCk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFwcDtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pblByb2dyZXNzQXBwQXNzZXRzTG9hZHMuZGVsZXRlKGFwcC5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5sb2FkRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBzaGFyZSgpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5pblByb2dyZXNzQXBwQXNzZXRzTG9hZHMuc2V0KGFwcC5uYW1lLCBsb2FkQXBwJCk7XG4gICAgICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRpbmcpO1xuICAgICAgICAgICAgcmV0dXJuIGxvYWRBcHAkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoaWRlQXBwKHBsYW5ldEFwcDogUGxhbmV0QXBwbGljYXRpb24pIHtcbiAgICAgICAgY29uc3QgYXBwUmVmID0gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYocGxhbmV0QXBwLm5hbWUpO1xuICAgICAgICBjb25zdCBhcHBSb290RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYXBwUmVmPy5zZWxlY3RvciB8fCAocGxhbmV0QXBwLnNlbGVjdG9yIGFzIHN0cmluZykpO1xuICAgICAgICBpZiAoYXBwUm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGFwcFJvb3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnZGlzcGxheTpub25lOycpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzaG93QXBwKHBsYW5ldEFwcDogUGxhbmV0QXBwbGljYXRpb24pIHtcbiAgICAgICAgY29uc3QgYXBwUmVmID0gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYocGxhbmV0QXBwLm5hbWUpO1xuICAgICAgICBjb25zdCBhcHBSb290RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYXBwUmVmPy5zZWxlY3RvciB8fCAocGxhbmV0QXBwLnNlbGVjdG9yIGFzIHN0cmluZykpO1xuICAgICAgICBpZiAoYXBwUm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGFwcFJvb3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRlc3Ryb3lBcHAocGxhbmV0QXBwOiBQbGFuZXRBcHBsaWNhdGlvbikge1xuICAgICAgICBjb25zdCBhcHBSZWYgPSBnZXRQbGFuZXRBcHBsaWNhdGlvblJlZihwbGFuZXRBcHAubmFtZSk7XG4gICAgICAgIGlmIChhcHBSZWYpIHtcbiAgICAgICAgICAgIGFwcFJlZi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gZ2V0SFRNTEVsZW1lbnQocGxhbmV0QXBwLmhvc3RQYXJlbnQpO1xuICAgICAgICBjb25zdCBhcHBSb290RWxlbWVudCA9IGNvbnRhaW5lcj8ucXVlcnlTZWxlY3RvcigoYXBwUmVmICYmIGFwcFJlZi5zZWxlY3RvcikgfHwgKHBsYW5ldEFwcC5zZWxlY3RvciBhcyBzdHJpbmcpKTtcbiAgICAgICAgaWYgKGFwcFJvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICBjb250YWluZXI/LnJlbW92ZUNoaWxkKGFwcFJvb3RFbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYm9vdHN0cmFwQXBwKFxuICAgICAgICBhcHA6IFBsYW5ldEFwcGxpY2F0aW9uLFxuICAgICAgICBkZWZhdWx0U3RhdHVzOiAnaGlkZGVuJyB8ICdkaXNwbGF5JyA9ICdkaXNwbGF5J1xuICAgICk6IE9ic2VydmFibGU8UGxhbmV0QXBwbGljYXRpb25SZWY+IHtcbiAgICAgICAgZGVidWcoYGFwcCgke2FwcC5uYW1lfSkgc3RhcnQgYm9vdHN0cmFwcGluZ2ApO1xuICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmJvb3RzdHJhcHBpbmcpO1xuICAgICAgICBjb25zdCBhcHBSZWYgPSBnZXRQbGFuZXRBcHBsaWNhdGlvblJlZihhcHAubmFtZSk7XG4gICAgICAgIGlmIChhcHBSZWYgJiYgYXBwUmVmLmJvb3RzdHJhcCkge1xuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gZ2V0SFRNTEVsZW1lbnQoYXBwLmhvc3RQYXJlbnQpO1xuICAgICAgICAgICAgbGV0IGFwcFJvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICBhcHBSb290RWxlbWVudCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGFwcFJlZi5zZWxlY3RvciB8fCBhcHAuc2VsZWN0b3IhKSE7XG4gICAgICAgICAgICAgICAgaWYgKCFhcHBSb290RWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwUmVmLnRlbXBsYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBSb290RWxlbWVudCA9IGNyZWF0ZUVsZW1lbnRCeVRlbXBsYXRlKGFwcFJlZi50ZW1wbGF0ZSkhO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGFwcC5zZWxlY3RvciEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFwcFJvb3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnZGlzcGxheTpub25lOycpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwLmhvc3RDbGFzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCguLi5jb2VyY2VBcnJheShhcHAuaG9zdENsYXNzKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGFwcC5zdHlsZVByZWZpeCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCguLi5jb2VyY2VBcnJheShhcHAuc3R5bGVQcmVmaXgpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoYXBwUm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCByZXN1bHQgPSBhcHBSZWYuYm9vdHN0cmFwKHRoaXMucG9ydGFsQXBwKTtcbiAgICAgICAgICAgIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHByb21pc2UgZm9yIGJvb3RzdHJhcFxuICAgICAgICAgICAgaWYgKChyZXN1bHQgYXMgYW55KVsndGhlbiddKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZnJvbShyZXN1bHQpIGFzIE9ic2VydmFibGU8UGxhbmV0QXBwbGljYXRpb25SZWY+O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5waXBlKFxuICAgICAgICAgICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKGBhcHAoJHthcHAubmFtZX0pIGJvb3RzdHJhcHBlZCBzdWNjZXNzIGZvciAke2RlZmF1bHRTdGF0dXN9YCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QXBwU3RhdHVzKGFwcCwgQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGVkKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlZmF1bHRTdGF0dXMgPT09ICdkaXNwbGF5JyAmJiBhcHBSb290RWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFwcFJlZjtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgWyR7YXBwLm5hbWV9XSBub3QgZm91bmQsIG1ha2Ugc3VyZSB0aGF0IHRoZSBhcHAgaGFzIHRoZSBjb3JyZWN0IG5hbWUgZGVmaW5lZCB1c2UgZGVmaW5lQXBwbGljYXRpb24oJHthcHAubmFtZX0pIGFuZCBydW50aW1lQ2h1bmsgYW5kIHZlbmRvckNodW5rIGFyZSBzZXQgdG8gdHJ1ZSwgZGV0YWlscyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3dvcmt0aWxlL25neC1wbGFuZXQjdGhyb3ctZXJyb3ItY2Fubm90LXJlYWQtcHJvcGVydHktY2FsbC1vZi11bmRlZmluZWQtYXQtX193ZWJwYWNrX3JlcXVpcmVfXy1ib290c3RyYXA3OWBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFVubG9hZEFwcHMoYWN0aXZlQXBwczogUGxhbmV0QXBwbGljYXRpb25bXSkge1xuICAgICAgICBjb25zdCB1bmxvYWRBcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdID0gW107XG4gICAgICAgIHRoaXMuYXBwc1N0YXR1cy5mb3JFYWNoKCh2YWx1ZSwgYXBwKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IEFwcGxpY2F0aW9uU3RhdHVzLmFjdGl2ZSAmJiAhYWN0aXZlQXBwcy5maW5kKGl0ZW0gPT4gaXRlbS5uYW1lID09PSBhcHAubmFtZSkpIHtcbiAgICAgICAgICAgICAgICB1bmxvYWRBcHBzLnB1c2goYXBwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1bmxvYWRBcHBzO1xuICAgIH1cblxuICAgIHByaXZhdGUgdW5sb2FkQXBwcyhzaG91bGRVbmxvYWRBcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdLCBldmVudDogUGxhbmV0Um91dGVyRXZlbnQpIHtcbiAgICAgICAgY29uc3QgaGlkZUFwcHM6IFBsYW5ldEFwcGxpY2F0aW9uW10gPSBbXTtcbiAgICAgICAgY29uc3QgZGVzdHJveUFwcHM6IFBsYW5ldEFwcGxpY2F0aW9uW10gPSBbXTtcbiAgICAgICAgc2hvdWxkVW5sb2FkQXBwcy5mb3JFYWNoKGFwcCA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zd2l0Y2hNb2RlSXNDb2V4aXN0KGFwcCkpIHtcbiAgICAgICAgICAgICAgICBkZWJ1ZyhgaGlkZSBhcHAoJHthcHAubmFtZX0pIGZvciBjb2V4aXN0IG1vZGVgKTtcbiAgICAgICAgICAgICAgICBoaWRlQXBwcy5wdXNoKGFwcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQXBwKGFwcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5ib290c3RyYXBwZWQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZXN0cm95QXBwcy5wdXNoKGFwcCk7XG4gICAgICAgICAgICAgICAgLy8g6ZSA5q+B5LmL5YmN5YWI6ZqQ6JeP77yM5ZCm5YiZ5Lya5Ye6546w6Zeq54OB77yM5Zug5Li6IGRlc3Ryb3kg5piv5bu26L+f5omn6KGM55qEXG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c6ZSA5q+B5LiN5bu26L+f5omn6KGM77yM5Lya5Ye6546w5YiH5o2i5Yiw5Li75bqU55So55qE5pe25YCZ5Lya5pyJ6KeG5Zu+5Y2h6aG/546w6LGhXG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQXBwKGFwcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5hc3NldHNMb2FkZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoaGlkZUFwcHMubGVuZ3RoID4gMCB8fCBkZXN0cm95QXBwcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyDku47lhbbku5blupTnlKjliIfmjaLliLDkuLvlupTnlKjnmoTml7blgJnkvJrmnInop4blm77ljaHpob/njrDosaHvvIzmiYDku6XlhYjnrYnkuLvlupTnlKjmuLLmn5Plrozmr5XlkI7lho3liqDovb3lhbbku5blupTnlKhcbiAgICAgICAgICAgIC8vIOatpOWkhOWwneivleS9v+eUqCB0aGlzLm5nWm9uZS5vblN0YWJsZS5waXBlKHRha2UoMSkpIOW6lOeUqOS5i+mXtOeahOWIh+aNouS8muWHuueOsOmXqueDgVxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaGlkZUFwcHMuZm9yRWFjaChhcHAgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBSZWYgPSBnZXRQbGFuZXRBcHBsaWNhdGlvblJlZihhcHAubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHBSZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcFJlZi5uYXZpZ2F0ZUJ5VXJsKGV2ZW50LnVybCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBkZXN0cm95QXBwcy5mb3JFYWNoKGFwcCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKGBkZXN0cm95IGFwcCgke2FwcC5uYW1lfSlgKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95QXBwKGFwcCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcHJlbG9hZEFwcHMoYWN0aXZlQXBwcz86IFBsYW5ldEFwcGxpY2F0aW9uW10pIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0b1ByZWxvYWRBcHBzID0gdGhpcy5wbGFuZXRBcHBsaWNhdGlvblNlcnZpY2UuZ2V0QXBwc1RvUHJlbG9hZChcbiAgICAgICAgICAgICAgICBhY3RpdmVBcHBzID8gYWN0aXZlQXBwcy5tYXAoaXRlbSA9PiBpdGVtLm5hbWUpIDogdW5kZWZpbmVkXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZGVidWcoYHN0YXJ0IHByZWxvYWQgYXBwczogJHt0aGlzLmdldEFwcE5hbWVzKHRvUHJlbG9hZEFwcHMpfWApO1xuICAgICAgICAgICAgY29uc3QgbG9hZEFwcHMkID0gdG9QcmVsb2FkQXBwcy5tYXAocHJlbG9hZEFwcCA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJlbG9hZEludGVybmFsKHByZWxvYWRBcHApO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGZvcmtKb2luKGxvYWRBcHBzJCkuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZW5zdXJlUHJlbG9hZEFwcHMoYWN0aXZlQXBwcz86IFBsYW5ldEFwcGxpY2F0aW9uW10pIHtcbiAgICAgICAgLy8gU3RhcnQgcHJlbG9hZCBhcHBzXG4gICAgICAgIC8vIFN0YXJ0IHByZWxvYWQgd2hlbiBmaXJzdCB0aW1lIGFwcCBsb2FkZWRcbiAgICAgICAgaWYgKHRoaXMuZmlyc3RMb2FkKSB7XG4gICAgICAgICAgICB0aGlzLnByZWxvYWRBcHBzKGFjdGl2ZUFwcHMpO1xuICAgICAgICAgICAgdGhpcy5maXJzdExvYWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZXRPcHRpb25zKG9wdGlvbnM6IFBhcnRpYWw8UGxhbmV0T3B0aW9ucz4pIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgLi4udGhpcy5vcHRpb25zLFxuICAgICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJlc2V0IHJvdXRlIGJ5IGN1cnJlbnQgcm91dGVyXG4gICAgICovXG4gICAgcHVibGljIHJlcm91dGUoZXZlbnQ6IFBsYW5ldFJvdXRlckV2ZW50KSB7XG4gICAgICAgIHRoaXMucm91dGVDaGFuZ2UkLm5leHQoZXZlbnQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHJlbG9hZEludGVybmFsKGFwcDogUGxhbmV0QXBwbGljYXRpb24sIGltbWVkaWF0ZT86IGJvb2xlYW4pOiBPYnNlcnZhYmxlPFBsYW5ldEFwcGxpY2F0aW9uUmVmIHwgbnVsbD4ge1xuICAgICAgICBjb25zdCBzdGF0dXMgPSB0aGlzLmFwcHNTdGF0dXMuZ2V0KGFwcCk7XG4gICAgICAgIGlmICghc3RhdHVzIHx8IHN0YXR1cyA9PT0gQXBwbGljYXRpb25TdGF0dXMubG9hZEVycm9yKSB7XG4gICAgICAgICAgICBkZWJ1ZyhgcHJlbG9hZCBhcHAoJHthcHAubmFtZX0pLCBzdGF0dXMgaXMgZW1wdHksIHN0YXJ0IHRvIGxvYWQgYXNzZXRzYCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydExvYWRBcHBBc3NldHMoYXBwKS5waXBlKFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKGBwcmVsb2FkIGFwcCgke2FwcC5uYW1lfSksIGFzc2V0cyBsb2FkZWQsIHN0YXJ0IGJvb3RzdHJhcCBhcHAsIGltbWVkaWF0ZTogJHshIWltbWVkaWF0ZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGltbWVkaWF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYm9vdHN0cmFwQXBwKGFwcCwgJ2hpZGRlbicpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ib290c3RyYXBBcHAoYXBwLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYoYXBwLm5hbWUpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgW0FwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRpbmcsIEFwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRlZCwgQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGluZ10uaW5jbHVkZXMoXG4gICAgICAgICAgICAgICAgc3RhdHVzXG4gICAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgICAgZGVidWcoYHByZWxvYWQgYXBwKCR7YXBwLm5hbWV9KSwgc3RhdHVzIGlzICR7QXBwbGljYXRpb25TdGF0dXNbc3RhdHVzXX0sIHJldHVybiB1bnRpbCBib290c3RyYXBwZWRgKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEFwcFN0YXR1c0NoYW5nZSQoYXBwKS5waXBlKFxuICAgICAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldFBsYW5ldEFwcGxpY2F0aW9uUmVmKGFwcC5uYW1lKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGFwcFJlZiA9IGdldFBsYW5ldEFwcGxpY2F0aW9uUmVmKGFwcC5uYW1lKTtcbiAgICAgICAgICAgIGlmICghYXBwUmVmKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2FwcC5uYW1lfSdzIHN0YXR1cyBpcyAke0FwcGxpY2F0aW9uU3RhdHVzW3N0YXR1c119LCBwbGFuZXRBcHBsaWNhdGlvblJlZiBpcyBudWxsLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9mKGFwcFJlZik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmVsb2FkIHBsYW5ldCBhcHBsaWNhdGlvblxuICAgICAqIEBwYXJhbSBhcHAgYXBwXG4gICAgICogQHBhcmFtIGltbWVkaWF0ZSBib290c3RyYXAgb24gc3RhYmxlIGJ5IGRlZmF1bHQsIHNldHRpbmcgaW1tZWRpYXRlIGlzIHRydWUsIGl0IHdpbGwgYm9vdHN0cmFwIGltbWVkaWF0ZVxuICAgICAqL1xuICAgIHB1YmxpYyBwcmVsb2FkKGFwcDogUGxhbmV0QXBwbGljYXRpb24sIGltbWVkaWF0ZT86IGJvb2xlYW4pOiBPYnNlcnZhYmxlPFBsYW5ldEFwcGxpY2F0aW9uUmVmPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByZWxvYWRJbnRlcm5hbChhcHAsIGltbWVkaWF0ZSk7XG4gICAgfVxufVxuIl19
|