@ionic/angular 8.8.9-dev.11780690416.19d0d667 → 8.8.9-dev.11780692883.1099c873
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/css/core.css +1 -1
- package/css/core.css.map +1 -1
- package/css/display.css +1 -1
- package/css/display.css.map +1 -1
- package/css/flex-utils.css +1 -1
- package/css/flex-utils.css.map +1 -1
- package/css/float-elements.css.map +1 -1
- package/css/global.bundle.css.map +1 -1
- package/css/ionic-swiper.css +1 -1
- package/css/ionic-swiper.css.map +1 -1
- package/css/ionic.bundle.css +1 -1
- package/css/ionic.bundle.css.map +1 -1
- package/css/normalize.css.map +1 -1
- package/css/padding.css.map +1 -1
- package/css/palettes/dark.always.css.map +1 -1
- package/css/palettes/dark.class.css.map +1 -1
- package/css/palettes/dark.system.css.map +1 -1
- package/css/palettes/high-contrast-dark.always.css.map +1 -1
- package/css/palettes/high-contrast-dark.class.css.map +1 -1
- package/css/palettes/high-contrast-dark.system.css.map +1 -1
- package/css/palettes/high-contrast.always.css.map +1 -1
- package/css/palettes/high-contrast.class.css.map +1 -1
- package/css/palettes/high-contrast.system.css.map +1 -1
- package/css/structure.css.map +1 -1
- package/css/text-alignment.css.map +1 -1
- package/css/text-transformation.css.map +1 -1
- package/css/typography.css.map +1 -1
- package/css/utils.bundle.css +1 -1
- package/css/utils.bundle.css.map +1 -1
- package/fesm2022/ionic-angular-common.mjs +87 -84
- package/fesm2022/ionic-angular-common.mjs.map +1 -1
- package/fesm2022/ionic-angular-standalone.mjs +903 -911
- package/fesm2022/ionic-angular-standalone.mjs.map +1 -1
- package/fesm2022/ionic-angular.mjs +1065 -771
- package/fesm2022/ionic-angular.mjs.map +1 -1
- package/package.json +16 -16
- package/schematics/add/index.js +1 -1
- package/schematics/utils/ast.js +1 -2
- package/schematics/utils/config.js +10 -11
- package/schematics/utils/package.js +1 -2
- package/types/ionic-angular-common.d.ts +1013 -0
- package/types/ionic-angular-standalone.d.ts +1560 -0
- package/{directives/proxies.d.ts → types/ionic-angular.d.ts} +703 -478
- package/app-initialize.d.ts +0 -3
- package/common/directives/control-value-accessors/index.d.ts +0 -1
- package/common/directives/control-value-accessors/value-accessor.d.ts +0 -36
- package/common/directives/navigation/back-button.d.ts +0 -23
- package/common/directives/navigation/nav-params.d.ts +0 -45
- package/common/directives/navigation/nav.d.ts +0 -21
- package/common/directives/navigation/router-link-delegate.d.ts +0 -60
- package/common/directives/navigation/router-outlet.d.ts +0 -104
- package/common/directives/navigation/stack-controller.d.ts +0 -42
- package/common/directives/navigation/stack-utils.d.ts +0 -38
- package/common/directives/navigation/tabs.d.ts +0 -83
- package/common/index.d.ts +0 -22
- package/common/overlays/modal.d.ts +0 -62
- package/common/overlays/popover.d.ts +0 -46
- package/common/providers/angular-delegate.d.ts +0 -28
- package/common/providers/config.d.ts +0 -11
- package/common/providers/dom-controller.d.ts +0 -16
- package/common/providers/menu-controller.d.ts +0 -78
- package/common/providers/nav-controller.d.ts +0 -116
- package/common/providers/platform.d.ts +0 -174
- package/common/types/interfaces.d.ts +0 -8
- package/common/types/ionic-lifecycle-hooks.d.ts +0 -27
- package/common/types/overlay-options.d.ts +0 -16
- package/common/utils/overlay.d.ts +0 -21
- package/common/utils/proxy.d.ts +0 -8
- package/common/utils/routing.d.ts +0 -28
- package/common/utils/util.d.ts +0 -1
- package/css/ionic/bundle.ionic.css +0 -1
- package/css/ionic/bundle.ionic.css.map +0 -1
- package/css/ionic/core.ionic.css +0 -1
- package/css/ionic/core.ionic.css.map +0 -1
- package/css/ionic/global.bundle.ionic.css +0 -1
- package/css/ionic/global.bundle.ionic.css.map +0 -1
- package/css/ionic/ionic-swiper.ionic.css +0 -1
- package/css/ionic/ionic-swiper.ionic.css.map +0 -1
- package/css/ionic/link.ionic.css +0 -1
- package/css/ionic/link.ionic.css.map +0 -1
- package/css/ionic/structure.ionic.css +0 -1
- package/css/ionic/structure.ionic.css.map +0 -1
- package/css/ionic/typography.ionic.css +0 -1
- package/css/ionic/typography.ionic.css.map +0 -1
- package/css/ionic/utils.bundle.ionic.css +0 -1
- package/css/ionic/utils.bundle.ionic.css.map +0 -1
- package/directives/angular-component-lib/utils.d.ts +0 -9
- package/directives/control-value-accessors/boolean-value-accessor.d.ts +0 -10
- package/directives/control-value-accessors/index.d.ts +0 -4
- package/directives/control-value-accessors/numeric-value-accessor.d.ts +0 -11
- package/directives/control-value-accessors/select-value-accessor.d.ts +0 -9
- package/directives/control-value-accessors/text-value-accessor.d.ts +0 -9
- package/directives/navigation/ion-back-button.d.ts +0 -9
- package/directives/navigation/ion-nav.d.ts +0 -8
- package/directives/navigation/ion-router-outlet.d.ts +0 -25
- package/directives/navigation/ion-tabs.d.ts +0 -13
- package/directives/navigation/router-link-delegate.d.ts +0 -16
- package/directives/overlays/modal.d.ts +0 -6
- package/directives/overlays/popover.d.ts +0 -6
- package/directives/proxies-list.d.ts +0 -2
- package/directives/validators/index.d.ts +0 -2
- package/directives/validators/max-validator.d.ts +0 -12
- package/directives/validators/min-validator.d.ts +0 -12
- package/esm2022/app-initialize.mjs +0 -29
- package/esm2022/common/directives/control-value-accessors/index.mjs +0 -2
- package/esm2022/common/directives/control-value-accessors/value-accessor.mjs +0 -153
- package/esm2022/common/directives/navigation/back-button.mjs +0 -61
- package/esm2022/common/directives/navigation/nav-params.mjs +0 -47
- package/esm2022/common/directives/navigation/nav.mjs +0 -49
- package/esm2022/common/directives/navigation/router-link-delegate.mjs +0 -156
- package/esm2022/common/directives/navigation/router-outlet.mjs +0 -480
- package/esm2022/common/directives/navigation/stack-controller.mjs +0 -280
- package/esm2022/common/directives/navigation/stack-utils.mjs +0 -73
- package/esm2022/common/directives/navigation/tabs.mjs +0 -279
- package/esm2022/common/index.mjs +0 -20
- package/esm2022/common/ionic-angular-common.mjs +0 -5
- package/esm2022/common/overlays/modal.mjs +0 -103
- package/esm2022/common/overlays/popover.mjs +0 -91
- package/esm2022/common/providers/angular-delegate.mjs +0 -203
- package/esm2022/common/providers/config.mjs +0 -45
- package/esm2022/common/providers/dom-controller.mjs +0 -45
- package/esm2022/common/providers/menu-controller.mjs +0 -114
- package/esm2022/common/providers/nav-controller.mjs +0 -235
- package/esm2022/common/providers/platform.mjs +0 -258
- package/esm2022/common/types/interfaces.mjs +0 -2
- package/esm2022/common/types/ionic-lifecycle-hooks.mjs +0 -5
- package/esm2022/common/types/overlay-options.mjs +0 -2
- package/esm2022/common/utils/overlay.mjs +0 -26
- package/esm2022/common/utils/proxy.mjs +0 -47
- package/esm2022/common/utils/routing.mjs +0 -55
- package/esm2022/common/utils/util.mjs +0 -10
- package/esm2022/directives/angular-component-lib/utils.mjs +0 -59
- package/esm2022/directives/control-value-accessors/boolean-value-accessor.mjs +0 -42
- package/esm2022/directives/control-value-accessors/index.mjs +0 -5
- package/esm2022/directives/control-value-accessors/numeric-value-accessor.mjs +0 -50
- package/esm2022/directives/control-value-accessors/select-value-accessor.mjs +0 -39
- package/esm2022/directives/control-value-accessors/text-value-accessor.mjs +0 -38
- package/esm2022/directives/navigation/ion-back-button.mjs +0 -24
- package/esm2022/directives/navigation/ion-nav.mjs +0 -21
- package/esm2022/directives/navigation/ion-router-outlet.mjs +0 -52
- package/esm2022/directives/navigation/ion-tabs.mjs +0 -59
- package/esm2022/directives/navigation/router-link-delegate.mjs +0 -32
- package/esm2022/directives/overlays/modal.mjs +0 -22
- package/esm2022/directives/overlays/popover.mjs +0 -18
- package/esm2022/directives/proxies-list.mjs +0 -93
- package/esm2022/directives/proxies.mjs +0 -2465
- package/esm2022/directives/validators/index.mjs +0 -3
- package/esm2022/directives/validators/max-validator.mjs +0 -27
- package/esm2022/directives/validators/min-validator.mjs +0 -27
- package/esm2022/index.mjs +0 -32
- package/esm2022/ionic-angular.mjs +0 -5
- package/esm2022/ionic-module.mjs +0 -111
- package/esm2022/providers/action-sheet-controller.mjs +0 -19
- package/esm2022/providers/alert-controller.mjs +0 -19
- package/esm2022/providers/animation-controller.mjs +0 -38
- package/esm2022/providers/gesture-controller.mjs +0 -33
- package/esm2022/providers/loading-controller.mjs +0 -19
- package/esm2022/providers/menu-controller.mjs +0 -19
- package/esm2022/providers/modal-controller.mjs +0 -26
- package/esm2022/providers/picker-controller.mjs +0 -22
- package/esm2022/providers/popover-controller.mjs +0 -19
- package/esm2022/providers/toast-controller.mjs +0 -19
- package/esm2022/standalone/directives/angular-component-lib/utils.mjs +0 -59
- package/esm2022/standalone/directives/checkbox.mjs +0 -76
- package/esm2022/standalone/directives/datetime.mjs +0 -95
- package/esm2022/standalone/directives/icon.mjs +0 -35
- package/esm2022/standalone/directives/index.mjs +0 -13
- package/esm2022/standalone/directives/input-otp.mjs +0 -90
- package/esm2022/standalone/directives/input.mjs +0 -113
- package/esm2022/standalone/directives/proxies.mjs +0 -2356
- package/esm2022/standalone/directives/radio-group.mjs +0 -60
- package/esm2022/standalone/directives/range.mjs +0 -78
- package/esm2022/standalone/directives/searchbar.mjs +0 -82
- package/esm2022/standalone/directives/segment.mjs +0 -60
- package/esm2022/standalone/directives/select.mjs +0 -84
- package/esm2022/standalone/directives/textarea.mjs +0 -91
- package/esm2022/standalone/directives/toggle.mjs +0 -76
- package/esm2022/standalone/index.mjs +0 -25
- package/esm2022/standalone/ionic-angular-standalone.mjs +0 -5
- package/esm2022/standalone/navigation/back-button.mjs +0 -32
- package/esm2022/standalone/navigation/nav.mjs +0 -28
- package/esm2022/standalone/navigation/router-link-delegate.mjs +0 -28
- package/esm2022/standalone/navigation/router-outlet.mjs +0 -60
- package/esm2022/standalone/navigation/tabs.mjs +0 -58
- package/esm2022/standalone/overlays/modal.mjs +0 -32
- package/esm2022/standalone/overlays/popover.mjs +0 -28
- package/esm2022/standalone/providers/action-sheet-controller.mjs +0 -21
- package/esm2022/standalone/providers/alert-controller.mjs +0 -21
- package/esm2022/standalone/providers/animation-controller.mjs +0 -38
- package/esm2022/standalone/providers/gesture-controller.mjs +0 -33
- package/esm2022/standalone/providers/ionic-angular.mjs +0 -38
- package/esm2022/standalone/providers/loading-controller.mjs +0 -21
- package/esm2022/standalone/providers/menu-controller.mjs +0 -19
- package/esm2022/standalone/providers/modal-controller.mjs +0 -28
- package/esm2022/standalone/providers/picker-controller.mjs +0 -24
- package/esm2022/standalone/providers/popover-controller.mjs +0 -21
- package/esm2022/standalone/providers/toast-controller.mjs +0 -21
- package/index.d.ts +0 -27
- package/ionic-module.d.ts +0 -28
- package/providers/action-sheet-controller.d.ts +0 -8
- package/providers/alert-controller.d.ts +0 -8
- package/providers/animation-controller.d.ts +0 -25
- package/providers/gesture-controller.d.ts +0 -13
- package/providers/loading-controller.d.ts +0 -8
- package/providers/menu-controller.d.ts +0 -7
- package/providers/modal-controller.d.ts +0 -12
- package/providers/picker-controller.d.ts +0 -11
- package/providers/popover-controller.d.ts +0 -9
- package/providers/toast-controller.d.ts +0 -8
- package/standalone/directives/angular-component-lib/utils.d.ts +0 -9
- package/standalone/directives/checkbox.d.ts +0 -30
- package/standalone/directives/datetime.d.ts +0 -30
- package/standalone/directives/icon.d.ts +0 -9
- package/standalone/directives/index.d.ts +0 -12
- package/standalone/directives/input-otp.d.ts +0 -49
- package/standalone/directives/input.d.ts +0 -47
- package/standalone/directives/proxies.d.ts +0 -1062
- package/standalone/directives/radio-group.d.ts +0 -18
- package/standalone/directives/range.d.ts +0 -47
- package/standalone/directives/searchbar.d.ts +0 -45
- package/standalone/directives/segment.d.ts +0 -19
- package/standalone/directives/select.d.ts +0 -34
- package/standalone/directives/textarea.d.ts +0 -37
- package/standalone/directives/toggle.d.ts +0 -28
- package/standalone/index.d.ts +0 -23
- package/standalone/navigation/back-button.d.ts +0 -9
- package/standalone/navigation/nav.d.ts +0 -8
- package/standalone/navigation/router-link-delegate.d.ts +0 -10
- package/standalone/navigation/router-outlet.d.ts +0 -25
- package/standalone/navigation/tabs.d.ts +0 -13
- package/standalone/overlays/modal.d.ts +0 -6
- package/standalone/overlays/popover.d.ts +0 -6
- package/standalone/providers/action-sheet-controller.d.ts +0 -8
- package/standalone/providers/alert-controller.d.ts +0 -8
- package/standalone/providers/animation-controller.d.ts +0 -25
- package/standalone/providers/gesture-controller.d.ts +0 -13
- package/standalone/providers/ionic-angular.d.ts +0 -7
- package/standalone/providers/loading-controller.d.ts +0 -8
- package/standalone/providers/menu-controller.d.ts +0 -7
- package/standalone/providers/modal-controller.d.ts +0 -12
- package/standalone/providers/picker-controller.d.ts +0 -11
- package/standalone/providers/popover-controller.d.ts +0 -9
- package/standalone/providers/toast-controller.d.ts +0 -8
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
import { ViewContainerRef, inject, Attribute, Directive, EventEmitter, Optional, Output, SkipSelf, EnvironmentInjector, Input, InjectionToken, Injectable, reflectComponentType, } from '@angular/core';
|
|
2
|
-
import { Router, ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET } from '@angular/router';
|
|
3
|
-
import { componentOnReady } from '@ionic/core/components';
|
|
4
|
-
import { BehaviorSubject, combineLatest, of } from 'rxjs';
|
|
5
|
-
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
|
|
6
|
-
import { Config } from '../../providers/config';
|
|
7
|
-
import { NavController } from '../../providers/nav-controller';
|
|
8
|
-
import { StackController } from './stack-controller';
|
|
9
|
-
import { getUrl, isTabSwitch } from './stack-utils';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "@angular/common";
|
|
12
|
-
import * as i2 from "@angular/router";
|
|
13
|
-
// TODO(FW-2827): types
|
|
14
|
-
class IonRouterOutlet {
|
|
15
|
-
parentOutlet;
|
|
16
|
-
nativeEl;
|
|
17
|
-
activatedView = null;
|
|
18
|
-
tabsPrefix;
|
|
19
|
-
_swipeGesture;
|
|
20
|
-
stackCtrl;
|
|
21
|
-
// Maintain map of activated route proxies for each component instance
|
|
22
|
-
proxyMap = new WeakMap();
|
|
23
|
-
// Keep the latest activated route in a subject for the proxy routes to switch map to
|
|
24
|
-
currentActivatedRoute$ = new BehaviorSubject(null);
|
|
25
|
-
activated = null;
|
|
26
|
-
/** @internal */
|
|
27
|
-
get activatedComponentRef() {
|
|
28
|
-
return this.activated;
|
|
29
|
-
}
|
|
30
|
-
_activatedRoute = null;
|
|
31
|
-
/**
|
|
32
|
-
* The name of the outlet
|
|
33
|
-
*/
|
|
34
|
-
name = PRIMARY_OUTLET;
|
|
35
|
-
/** @internal */
|
|
36
|
-
stackWillChange = new EventEmitter();
|
|
37
|
-
/** @internal */
|
|
38
|
-
stackDidChange = new EventEmitter();
|
|
39
|
-
// eslint-disable-next-line @angular-eslint/no-output-rename
|
|
40
|
-
activateEvents = new EventEmitter();
|
|
41
|
-
// eslint-disable-next-line @angular-eslint/no-output-rename
|
|
42
|
-
deactivateEvents = new EventEmitter();
|
|
43
|
-
parentContexts = inject(ChildrenOutletContexts);
|
|
44
|
-
location = inject(ViewContainerRef);
|
|
45
|
-
environmentInjector = inject(EnvironmentInjector);
|
|
46
|
-
inputBinder = inject(INPUT_BINDER, { optional: true });
|
|
47
|
-
/** @nodoc */
|
|
48
|
-
supportsBindingToComponentInputs = true;
|
|
49
|
-
// Ionic providers
|
|
50
|
-
config = inject(Config);
|
|
51
|
-
navCtrl = inject(NavController);
|
|
52
|
-
set animation(animation) {
|
|
53
|
-
this.nativeEl.animation = animation;
|
|
54
|
-
}
|
|
55
|
-
set animated(animated) {
|
|
56
|
-
this.nativeEl.animated = animated;
|
|
57
|
-
}
|
|
58
|
-
set swipeGesture(swipe) {
|
|
59
|
-
this._swipeGesture = swipe;
|
|
60
|
-
this.nativeEl.swipeHandler = swipe
|
|
61
|
-
? {
|
|
62
|
-
canStart: () => this.stackCtrl.canGoBack(1) && !this.stackCtrl.hasRunningTask(),
|
|
63
|
-
onStart: () => this.stackCtrl.startBackTransition(),
|
|
64
|
-
onEnd: (shouldContinue) => this.stackCtrl.endBackTransition(shouldContinue),
|
|
65
|
-
}
|
|
66
|
-
: undefined;
|
|
67
|
-
}
|
|
68
|
-
constructor(name, tabs, commonLocation, elementRef, router, zone, activatedRoute, parentOutlet) {
|
|
69
|
-
this.parentOutlet = parentOutlet;
|
|
70
|
-
this.nativeEl = elementRef.nativeElement;
|
|
71
|
-
this.name = name || PRIMARY_OUTLET;
|
|
72
|
-
this.tabsPrefix = tabs === 'true' ? getUrl(router, activatedRoute) : undefined;
|
|
73
|
-
this.stackCtrl = new StackController(this.tabsPrefix, this.nativeEl, router, this.navCtrl, zone, commonLocation);
|
|
74
|
-
this.parentContexts.onChildOutletCreated(this.name, this);
|
|
75
|
-
}
|
|
76
|
-
ngOnDestroy() {
|
|
77
|
-
this.stackCtrl.destroy();
|
|
78
|
-
this.inputBinder?.unsubscribeFromRouteData(this);
|
|
79
|
-
}
|
|
80
|
-
getContext() {
|
|
81
|
-
return this.parentContexts.getContext(this.name);
|
|
82
|
-
}
|
|
83
|
-
ngOnInit() {
|
|
84
|
-
this.initializeOutletWithName();
|
|
85
|
-
}
|
|
86
|
-
// Note: Ionic deviates from the Angular Router implementation here
|
|
87
|
-
initializeOutletWithName() {
|
|
88
|
-
if (!this.activated) {
|
|
89
|
-
// If the outlet was not instantiated at the time the route got activated we need to populate
|
|
90
|
-
// the outlet when it is initialized (ie inside a NgIf)
|
|
91
|
-
const context = this.getContext();
|
|
92
|
-
if (context?.route) {
|
|
93
|
-
this.activateWith(context.route, context.injector);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
new Promise((resolve) => componentOnReady(this.nativeEl, resolve)).then(() => {
|
|
97
|
-
if (this._swipeGesture === undefined) {
|
|
98
|
-
this.swipeGesture = this.config.getBoolean('swipeBackEnabled', this.nativeEl.mode === 'ios');
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
get isActivated() {
|
|
103
|
-
return !!this.activated;
|
|
104
|
-
}
|
|
105
|
-
get component() {
|
|
106
|
-
if (!this.activated) {
|
|
107
|
-
throw new Error('Outlet is not activated');
|
|
108
|
-
}
|
|
109
|
-
return this.activated.instance;
|
|
110
|
-
}
|
|
111
|
-
get activatedRoute() {
|
|
112
|
-
if (!this.activated) {
|
|
113
|
-
throw new Error('Outlet is not activated');
|
|
114
|
-
}
|
|
115
|
-
return this._activatedRoute;
|
|
116
|
-
}
|
|
117
|
-
get activatedRouteData() {
|
|
118
|
-
if (this._activatedRoute) {
|
|
119
|
-
return this._activatedRoute.snapshot.data;
|
|
120
|
-
}
|
|
121
|
-
return {};
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Called when the `RouteReuseStrategy` instructs to detach the subtree
|
|
125
|
-
*/
|
|
126
|
-
detach() {
|
|
127
|
-
throw new Error('incompatible reuse strategy');
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
|
|
131
|
-
*/
|
|
132
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
133
|
-
attach(_ref, _activatedRoute) {
|
|
134
|
-
throw new Error('incompatible reuse strategy');
|
|
135
|
-
}
|
|
136
|
-
deactivate() {
|
|
137
|
-
if (this.activated) {
|
|
138
|
-
if (this.activatedView) {
|
|
139
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
140
|
-
const context = this.getContext();
|
|
141
|
-
this.activatedView.savedData = new Map(context.children['contexts']);
|
|
142
|
-
/**
|
|
143
|
-
* Angular v11.2.10 introduced a change
|
|
144
|
-
* where this route context is cleared out when
|
|
145
|
-
* a router-outlet is deactivated, However,
|
|
146
|
-
* we need this route information in order to
|
|
147
|
-
* return a user back to the correct tab when
|
|
148
|
-
* leaving and then going back to the tab context.
|
|
149
|
-
*/
|
|
150
|
-
const primaryOutlet = this.activatedView.savedData.get('primary');
|
|
151
|
-
if (primaryOutlet && context.route) {
|
|
152
|
-
primaryOutlet.route = { ...context.route };
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Ensure we are saving the NavigationExtras
|
|
156
|
-
* data otherwise it will be lost
|
|
157
|
-
*/
|
|
158
|
-
this.activatedView.savedExtras = {};
|
|
159
|
-
if (context.route) {
|
|
160
|
-
const contextSnapshot = context.route.snapshot;
|
|
161
|
-
this.activatedView.savedExtras.queryParams = contextSnapshot.queryParams;
|
|
162
|
-
this.activatedView.savedExtras.fragment = contextSnapshot.fragment;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
const c = this.component;
|
|
166
|
-
this.activatedView = null;
|
|
167
|
-
this.activated = null;
|
|
168
|
-
this._activatedRoute = null;
|
|
169
|
-
this.deactivateEvents.emit(c);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
activateWith(activatedRoute, environmentInjector) {
|
|
173
|
-
if (this.isActivated) {
|
|
174
|
-
throw new Error('Cannot activate an already activated outlet');
|
|
175
|
-
}
|
|
176
|
-
this._activatedRoute = activatedRoute;
|
|
177
|
-
let cmpRef;
|
|
178
|
-
let enteringView = this.stackCtrl.getExistingView(activatedRoute);
|
|
179
|
-
if (enteringView) {
|
|
180
|
-
cmpRef = this.activated = enteringView.ref;
|
|
181
|
-
const saved = enteringView.savedData;
|
|
182
|
-
if (saved) {
|
|
183
|
-
// self-restore
|
|
184
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
185
|
-
const context = this.getContext();
|
|
186
|
-
context.children['contexts'] = saved;
|
|
187
|
-
}
|
|
188
|
-
// Updated activated route proxy for this component
|
|
189
|
-
this.updateActivatedRouteProxy(cmpRef.instance, activatedRoute);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
const snapshot = activatedRoute._futureSnapshot;
|
|
193
|
-
/**
|
|
194
|
-
* Angular 14 introduces a new `loadComponent` property to the route config.
|
|
195
|
-
* This function will assign a `component` property to the route snapshot.
|
|
196
|
-
* We check for the presence of this property to determine if the route is
|
|
197
|
-
* using standalone components.
|
|
198
|
-
*/
|
|
199
|
-
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
|
|
200
|
-
// We create an activated route proxy object that will maintain future updates for this component
|
|
201
|
-
// over its lifecycle in the stack.
|
|
202
|
-
const component$ = new BehaviorSubject(null);
|
|
203
|
-
const activatedRouteProxy = this.createActivatedRouteProxy(component$, activatedRoute);
|
|
204
|
-
const injector = new OutletInjector(activatedRouteProxy, childContexts, this.location.injector);
|
|
205
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
206
|
-
const component = snapshot.routeConfig.component ?? snapshot.component;
|
|
207
|
-
/**
|
|
208
|
-
* View components need to be added as a child of ion-router-outlet
|
|
209
|
-
* for page transitions and swipe to go back.
|
|
210
|
-
* However, createComponent mounts components as siblings of the
|
|
211
|
-
* ViewContainerRef. As a result, outletContent must reference
|
|
212
|
-
* an ng-container inside of ion-router-outlet and not
|
|
213
|
-
* ion-router-outlet itself.
|
|
214
|
-
*/
|
|
215
|
-
cmpRef = this.activated = this.outletContent.createComponent(component, {
|
|
216
|
-
index: this.outletContent.length,
|
|
217
|
-
injector,
|
|
218
|
-
environmentInjector: environmentInjector ?? this.environmentInjector,
|
|
219
|
-
});
|
|
220
|
-
// Once the component is created we can push it to our local subject supplied to the proxy
|
|
221
|
-
component$.next(cmpRef.instance);
|
|
222
|
-
// Calling `markForCheck` to make sure we will run the change detection when the
|
|
223
|
-
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
|
|
224
|
-
/**
|
|
225
|
-
* At this point this.activated has been set earlier
|
|
226
|
-
* in this function, so it is guaranteed to be non-null.
|
|
227
|
-
*/
|
|
228
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
229
|
-
enteringView = this.stackCtrl.createView(this.activated, activatedRoute);
|
|
230
|
-
// Store references to the proxy by component
|
|
231
|
-
this.proxyMap.set(cmpRef.instance, activatedRouteProxy);
|
|
232
|
-
this.currentActivatedRoute$.next({ component: cmpRef.instance, activatedRoute });
|
|
233
|
-
}
|
|
234
|
-
this.inputBinder?.bindActivatedRouteToOutletComponent(this);
|
|
235
|
-
this.activatedView = enteringView;
|
|
236
|
-
/**
|
|
237
|
-
* The top outlet is set prior to the entering view's transition completing,
|
|
238
|
-
* so that when we have nested outlets (e.g. ion-tabs inside an ion-router-outlet),
|
|
239
|
-
* the tabs outlet will be assigned as the top outlet when a view inside tabs is
|
|
240
|
-
* activated.
|
|
241
|
-
*
|
|
242
|
-
* In this scenario, activeWith is called for both the tabs and the root router outlet.
|
|
243
|
-
* To avoid a race condition, we assign the top outlet synchronously.
|
|
244
|
-
*/
|
|
245
|
-
this.navCtrl.setTopOutlet(this);
|
|
246
|
-
const leavingView = this.stackCtrl.getActiveView();
|
|
247
|
-
this.stackWillChange.emit({
|
|
248
|
-
enteringView,
|
|
249
|
-
tabSwitch: isTabSwitch(enteringView, leavingView),
|
|
250
|
-
});
|
|
251
|
-
this.stackCtrl.setActive(enteringView).then((data) => {
|
|
252
|
-
this.activateEvents.emit(cmpRef.instance);
|
|
253
|
-
this.stackDidChange.emit(data);
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Returns `true` if there are pages in the stack to go back.
|
|
258
|
-
*/
|
|
259
|
-
canGoBack(deep = 1, stackId) {
|
|
260
|
-
return this.stackCtrl.canGoBack(deep, stackId);
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Resolves to `true` if it the outlet was able to sucessfully pop the last N pages.
|
|
264
|
-
*/
|
|
265
|
-
pop(deep = 1, stackId) {
|
|
266
|
-
return this.stackCtrl.pop(deep, stackId);
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Returns the URL of the active page of each stack.
|
|
270
|
-
*/
|
|
271
|
-
getLastUrl(stackId) {
|
|
272
|
-
const active = this.stackCtrl.getLastUrl(stackId);
|
|
273
|
-
return active ? active.url : undefined;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Returns the RouteView of the active page of each stack.
|
|
277
|
-
* @internal
|
|
278
|
-
*/
|
|
279
|
-
getLastRouteView(stackId) {
|
|
280
|
-
return this.stackCtrl.getLastUrl(stackId);
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Returns the root view in the tab stack.
|
|
284
|
-
* @internal
|
|
285
|
-
*/
|
|
286
|
-
getRootView(stackId) {
|
|
287
|
-
return this.stackCtrl.getRootUrl(stackId);
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Returns the active stack ID. In the context of ion-tabs, it means the active tab.
|
|
291
|
-
*/
|
|
292
|
-
getActiveStackId() {
|
|
293
|
-
return this.stackCtrl.getActiveStackId();
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Since the activated route can change over the life time of a component in an ion router outlet, we create
|
|
297
|
-
* a proxy so that we can update the values over time as a user navigates back to components already in the stack.
|
|
298
|
-
*/
|
|
299
|
-
createActivatedRouteProxy(component$, activatedRoute) {
|
|
300
|
-
const proxy = new ActivatedRoute();
|
|
301
|
-
proxy._futureSnapshot = activatedRoute._futureSnapshot;
|
|
302
|
-
proxy._routerState = activatedRoute._routerState;
|
|
303
|
-
proxy.snapshot = activatedRoute.snapshot;
|
|
304
|
-
proxy.outlet = activatedRoute.outlet;
|
|
305
|
-
proxy.component = activatedRoute.component;
|
|
306
|
-
// Setup wrappers for the observables so consumers don't have to worry about switching to new observables as the state updates
|
|
307
|
-
proxy._paramMap = this.proxyObservable(component$, 'paramMap');
|
|
308
|
-
proxy._queryParamMap = this.proxyObservable(component$, 'queryParamMap');
|
|
309
|
-
proxy.url = this.proxyObservable(component$, 'url');
|
|
310
|
-
proxy.params = this.proxyObservable(component$, 'params');
|
|
311
|
-
proxy.queryParams = this.proxyObservable(component$, 'queryParams');
|
|
312
|
-
proxy.fragment = this.proxyObservable(component$, 'fragment');
|
|
313
|
-
proxy.data = this.proxyObservable(component$, 'data');
|
|
314
|
-
return proxy;
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Create a wrapped observable that will switch to the latest activated route matched by the given component
|
|
318
|
-
*/
|
|
319
|
-
proxyObservable(component$, path) {
|
|
320
|
-
return component$.pipe(
|
|
321
|
-
// First wait until the component instance is pushed
|
|
322
|
-
filter((component) => !!component), switchMap((component) => this.currentActivatedRoute$.pipe(filter((current) => current !== null && current.component === component), switchMap((current) => current && current.activatedRoute[path]), distinctUntilChanged())));
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Updates the activated route proxy for the given component to the new incoming router state
|
|
326
|
-
*/
|
|
327
|
-
updateActivatedRouteProxy(component, activatedRoute) {
|
|
328
|
-
const proxy = this.proxyMap.get(component);
|
|
329
|
-
if (!proxy) {
|
|
330
|
-
throw new Error(`Could not find activated route proxy for view`);
|
|
331
|
-
}
|
|
332
|
-
proxy._futureSnapshot = activatedRoute._futureSnapshot;
|
|
333
|
-
proxy._routerState = activatedRoute._routerState;
|
|
334
|
-
proxy.snapshot = activatedRoute.snapshot;
|
|
335
|
-
proxy.outlet = activatedRoute.outlet;
|
|
336
|
-
proxy.component = activatedRoute.component;
|
|
337
|
-
this.currentActivatedRoute$.next({ component, activatedRoute });
|
|
338
|
-
}
|
|
339
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IonRouterOutlet, deps: [{ token: 'name', attribute: true }, { token: 'tabs', attribute: true, optional: true }, { token: i1.Location }, { token: i0.ElementRef }, { token: i2.Router }, { token: i0.NgZone }, { token: i2.ActivatedRoute }, { token: IonRouterOutlet, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive });
|
|
340
|
-
/** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: IonRouterOutlet, selector: "ion-router-outlet", inputs: { animated: "animated", animation: "animation", mode: "mode", swipeGesture: "swipeGesture", name: "name" }, outputs: { stackWillChange: "stackWillChange", stackDidChange: "stackDidChange", activateEvents: "activate", deactivateEvents: "deactivate" }, exportAs: ["outlet"], ngImport: i0 });
|
|
341
|
-
}
|
|
342
|
-
export { IonRouterOutlet };
|
|
343
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IonRouterOutlet, decorators: [{
|
|
344
|
-
type: Directive,
|
|
345
|
-
args: [{
|
|
346
|
-
selector: 'ion-router-outlet',
|
|
347
|
-
exportAs: 'outlet',
|
|
348
|
-
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
|
349
|
-
inputs: ['animated', 'animation', 'mode', 'swipeGesture'],
|
|
350
|
-
}]
|
|
351
|
-
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
352
|
-
type: Attribute,
|
|
353
|
-
args: ['name']
|
|
354
|
-
}] }, { type: undefined, decorators: [{
|
|
355
|
-
type: Optional
|
|
356
|
-
}, {
|
|
357
|
-
type: Attribute,
|
|
358
|
-
args: ['tabs']
|
|
359
|
-
}] }, { type: i1.Location }, { type: i0.ElementRef }, { type: i2.Router }, { type: i0.NgZone }, { type: i2.ActivatedRoute }, { type: IonRouterOutlet, decorators: [{
|
|
360
|
-
type: SkipSelf
|
|
361
|
-
}, {
|
|
362
|
-
type: Optional
|
|
363
|
-
}] }]; }, propDecorators: { name: [{
|
|
364
|
-
type: Input
|
|
365
|
-
}], stackWillChange: [{
|
|
366
|
-
type: Output
|
|
367
|
-
}], stackDidChange: [{
|
|
368
|
-
type: Output
|
|
369
|
-
}], activateEvents: [{
|
|
370
|
-
type: Output,
|
|
371
|
-
args: ['activate']
|
|
372
|
-
}], deactivateEvents: [{
|
|
373
|
-
type: Output,
|
|
374
|
-
args: ['deactivate']
|
|
375
|
-
}] } });
|
|
376
|
-
class OutletInjector {
|
|
377
|
-
route;
|
|
378
|
-
childContexts;
|
|
379
|
-
parent;
|
|
380
|
-
constructor(route, childContexts, parent) {
|
|
381
|
-
this.route = route;
|
|
382
|
-
this.childContexts = childContexts;
|
|
383
|
-
this.parent = parent;
|
|
384
|
-
}
|
|
385
|
-
get(token, notFoundValue) {
|
|
386
|
-
if (token === ActivatedRoute) {
|
|
387
|
-
return this.route;
|
|
388
|
-
}
|
|
389
|
-
if (token === ChildrenOutletContexts) {
|
|
390
|
-
return this.childContexts;
|
|
391
|
-
}
|
|
392
|
-
return this.parent.get(token, notFoundValue);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
// TODO: FW-4785 - Remove this once Angular 15 support is dropped
|
|
396
|
-
const INPUT_BINDER = new InjectionToken('');
|
|
397
|
-
/**
|
|
398
|
-
* Injectable used as a tree-shakable provider for opting in to binding router data to component
|
|
399
|
-
* inputs.
|
|
400
|
-
*
|
|
401
|
-
* The RouterOutlet registers itself with this service when an `ActivatedRoute` is attached or
|
|
402
|
-
* activated. When this happens, the service subscribes to the `ActivatedRoute` observables (params,
|
|
403
|
-
* queryParams, data) and sets the inputs of the component using `ComponentRef.setInput`.
|
|
404
|
-
* Importantly, when an input does not have an item in the route data with a matching key, this
|
|
405
|
-
* input is set to `undefined`. If it were not done this way, the previous information would be
|
|
406
|
-
* retained if the data got removed from the route (i.e. if a query parameter is removed).
|
|
407
|
-
*
|
|
408
|
-
* The `RouterOutlet` should unregister itself when destroyed via `unsubscribeFromRouteData` so that
|
|
409
|
-
* the subscriptions are cleaned up.
|
|
410
|
-
*/
|
|
411
|
-
class RoutedComponentInputBinder {
|
|
412
|
-
outletDataSubscriptions = new Map();
|
|
413
|
-
bindActivatedRouteToOutletComponent(outlet) {
|
|
414
|
-
this.unsubscribeFromRouteData(outlet);
|
|
415
|
-
this.subscribeToRouteData(outlet);
|
|
416
|
-
}
|
|
417
|
-
unsubscribeFromRouteData(outlet) {
|
|
418
|
-
this.outletDataSubscriptions.get(outlet)?.unsubscribe();
|
|
419
|
-
this.outletDataSubscriptions.delete(outlet);
|
|
420
|
-
}
|
|
421
|
-
subscribeToRouteData(outlet) {
|
|
422
|
-
const { activatedRoute } = outlet;
|
|
423
|
-
const dataSubscription = combineLatest([activatedRoute.queryParams, activatedRoute.params, activatedRoute.data])
|
|
424
|
-
.pipe(switchMap(([queryParams, params, data], index) => {
|
|
425
|
-
data = { ...queryParams, ...params, ...data };
|
|
426
|
-
// Get the first result from the data subscription synchronously so it's available to
|
|
427
|
-
// the component as soon as possible (and doesn't require a second change detection).
|
|
428
|
-
if (index === 0) {
|
|
429
|
-
return of(data);
|
|
430
|
-
}
|
|
431
|
-
// Promise.resolve is used to avoid synchronously writing the wrong data when
|
|
432
|
-
// two of the Observables in the `combineLatest` stream emit one after
|
|
433
|
-
// another.
|
|
434
|
-
return Promise.resolve(data);
|
|
435
|
-
}))
|
|
436
|
-
.subscribe((data) => {
|
|
437
|
-
// Outlet may have been deactivated or changed names to be associated with a different
|
|
438
|
-
// route
|
|
439
|
-
if (!outlet.isActivated ||
|
|
440
|
-
!outlet.activatedComponentRef ||
|
|
441
|
-
outlet.activatedRoute !== activatedRoute ||
|
|
442
|
-
activatedRoute.component === null) {
|
|
443
|
-
this.unsubscribeFromRouteData(outlet);
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
const mirror = reflectComponentType(activatedRoute.component);
|
|
447
|
-
if (!mirror) {
|
|
448
|
-
this.unsubscribeFromRouteData(outlet);
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
for (const { templateName } of mirror.inputs) {
|
|
452
|
-
outlet.activatedComponentRef.setInput(templateName, data[templateName]);
|
|
453
|
-
}
|
|
454
|
-
});
|
|
455
|
-
this.outletDataSubscriptions.set(outlet, dataSubscription);
|
|
456
|
-
}
|
|
457
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RoutedComponentInputBinder, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
458
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RoutedComponentInputBinder });
|
|
459
|
-
}
|
|
460
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RoutedComponentInputBinder, decorators: [{
|
|
461
|
-
type: Injectable
|
|
462
|
-
}] });
|
|
463
|
-
export const provideComponentInputBinding = () => {
|
|
464
|
-
return {
|
|
465
|
-
provide: INPUT_BINDER,
|
|
466
|
-
useFactory: componentInputBindingFactory,
|
|
467
|
-
deps: [Router],
|
|
468
|
-
};
|
|
469
|
-
};
|
|
470
|
-
function componentInputBindingFactory(router) {
|
|
471
|
-
/**
|
|
472
|
-
* We cast the router to any here, since the componentInputBindingEnabled
|
|
473
|
-
* property is not available until Angular v16.
|
|
474
|
-
*/
|
|
475
|
-
if (router?.componentInputBindingEnabled) {
|
|
476
|
-
return new RoutedComponentInputBinder();
|
|
477
|
-
}
|
|
478
|
-
return null;
|
|
479
|
-
}
|
|
480
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLW91dGxldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2NvbW1vbi9zcmMvZGlyZWN0aXZlcy9uYXZpZ2F0aW9uL3JvdXRlci1vdXRsZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQU9MLGdCQUFnQixFQUNoQixNQUFNLEVBQ04sU0FBUyxFQUNULFNBQVMsRUFDVCxZQUFZLEVBQ1osUUFBUSxFQUNSLE1BQU0sRUFDTixRQUFRLEVBQ1IsbUJBQW1CLEVBQ25CLEtBQUssRUFDTCxjQUFjLEVBQ2QsVUFBVSxFQUNWLG9CQUFvQixHQUNyQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQWlCLE1BQU0sRUFBRSxjQUFjLEVBQUUsc0JBQXNCLEVBQUUsY0FBYyxFQUFRLE1BQU0saUJBQWlCLENBQUM7QUFDdEgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFMUQsT0FBTyxFQUFjLGVBQWUsRUFBZ0IsYUFBYSxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFL0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sRUFBd0QsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7OztBQUUxRyx1QkFBdUI7QUFFdkIsTUFPc0IsZUFBZTtJQTRFQTtJQXpFbkMsUUFBUSxDQUE2QjtJQUNyQyxhQUFhLEdBQXFCLElBQUksQ0FBQztJQUN2QyxVQUFVLENBQXFCO0lBRXZCLGFBQWEsQ0FBVztJQUN4QixTQUFTLENBQWtCO0lBRW5DLHNFQUFz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Uyw0QkFBNEIsQ0FBQyxNQUFlO0lBQ25EOzs7T0FHRztJQUNILElBQUssTUFBYyxFQUFFLDRCQUE0QixFQUFFO1FBQ2pELE9BQU8sSUFBSSwwQkFBMEIsRUFBRSxDQUFDO0tBQ3pDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50UmVmLFxuICBFbGVtZW50UmVmLFxuICBJbmplY3RvcixcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0NvbnRhaW5lclJlZixcbiAgaW5qZWN0LFxuICBBdHRyaWJ1dGUsXG4gIERpcmVjdGl2ZSxcbiAgRXZlbnRFbWl0dGVyLFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTa2lwU2VsZixcbiAgRW52aXJvbm1lbnRJbmplY3RvcixcbiAgSW5wdXQsXG4gIEluamVjdGlvblRva2VuLFxuICBJbmplY3RhYmxlLFxuICByZWZsZWN0Q29tcG9uZW50VHlwZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgdHlwZSB7IFByb3ZpZGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPdXRsZXRDb250ZXh0LCBSb3V0ZXIsIEFjdGl2YXRlZFJvdXRlLCBDaGlsZHJlbk91dGxldENvbnRleHRzLCBQUklNQVJZX09VVExFVCwgRGF0YSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBjb21wb25lbnRPblJlYWR5IH0gZnJvbSAnQGlvbmljL2NvcmUvY29tcG9uZW50cyc7XG5pbXBvcnQgdHlwZSB7IEFuaW1hdGlvbkJ1aWxkZXIgfSBmcm9tICdAaW9uaWMvY29yZS9jb21wb25lbnRzJztcbmltcG9ydCB7IE9ic2VydmFibGUsIEJlaGF2aW9yU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBjb21iaW5lTGF0ZXN0LCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi8uLi9wcm92aWRlcnMvY29uZmlnJztcbmltcG9ydCB7IE5hdkNvbnRyb2xsZXIgfSBmcm9tICcuLi8uLi9wcm92aWRlcnMvbmF2LWNvbnRyb2xsZXInO1xuXG5pbXBvcnQgeyBTdGFja0NvbnRyb2xsZXIgfSBmcm9tICcuL3N0YWNrLWNvbnRyb2xsZXInO1xuaW1wb3J0IHsgUm91dGVWaWV3LCBTdGFja0RpZENoYW5nZUV2ZW50LCBTdGFja1dpbGxDaGFuZ2VFdmVudCwgZ2V0VXJsLCBpc1RhYlN3aXRjaCB9IGZyb20gJy4vc3RhY2stdXRpbHMnO1xuXG4vLyBUT0RPKEZXLTI4MjcpOiB0eXBlc1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdpb24tcm91dGVyLW91dGxldCcsXG4gIGV4cG9ydEFzOiAnb3V0bGV0JyxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1pbnB1dHMtbWV0YWRhdGEtcHJvcGVydHlcbiAgaW5wdXRzOiBbJ2FuaW1hdGVkJywgJ2FuaW1hdGlvbicsICdtb2RlJywgJ3N3aXBlR2VzdHVyZSddLFxufSlcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLWNsYXNzLXN1ZmZpeFxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIElvblJvdXRlck91dGxldCBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25Jbml0IHtcbiAgYWJzdHJhY3Qgb3V0bGV0Q29udGVudDogYW55O1xuXG4gIG5hdGl2ZUVsOiBIVE1MSW9uUm91dGVyT3V0bGV0RWxlbWVudDtcbiAgYWN0aXZhdGVkVmlldzogUm91dGVWaWV3IHwgbnVsbCA9IG51bGw7XG4gIHRhYnNQcmVmaXg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIF9zd2lwZUdlc3R1cmU/OiBib29sZWFuO1xuICBwcml2YXRlIHN0YWNrQ3RybDogU3RhY2tDb250cm9sbGVyO1xuXG4gIC8vIE1haW50YWluIG1hcCBvZiBhY3RpdmF0ZWQgcm91dGUgcHJveGllcyBmb3IgZWFjaCBjb21wb25lbnQgaW5zdGFuY2VcbiAgcHJpdmF0ZSBwcm94eU1hcCA9IG5ldyBXZWFrTWFwPGFueSwgQWN0aXZhdGVkUm91dGU+KCk7XG4gIC8vIEtlZXAgdGhlIGxhdGVzdCBhY3RpdmF0ZWQgcm91dGUgaW4gYSBzdWJqZWN0IGZvciB0aGUgcHJveHkgcm91dGVzIHRvIHN3aXRjaCBtYXAgdG9cbiAgcHJpdmF0ZSBjdXJyZW50QWN0aXZhdGVkUm91dGUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDx7IGNvbXBvbmVudDogYW55OyBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUgfSB8IG51bGw+KG51bGwpO1xuXG4gIHByaXZhdGUgYWN0aXZhdGVkOiBDb21wb25lbnRSZWY8YW55PiB8IG51bGwgPSBudWxsO1xuICAvKiogQGludGVybmFsICovXG4gIGdldCBhY3RpdmF0ZWRDb21wb25lbnRSZWYoKTogQ29tcG9uZW50UmVmPGFueT4gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmF0ZWQ7XG4gIH1cbiAgcHJpdmF0ZSBfYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBvdXRsZXRcbiAgICovXG4gIEBJbnB1dCgpIG5hbWUgPSBQUklNQVJZX09VVExFVDtcblxuICAvKiogQGludGVybmFsICovXG4gIEBPdXRwdXQoKSBzdGFja1dpbGxDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFN0YWNrV2lsbENoYW5nZUV2ZW50PigpO1xuICAvKiogQGludGVybmFsICovXG4gIEBPdXRwdXQoKSBzdGFja0RpZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8U3RhY2tEaWRDaGFuZ2VFdmVudD4oKTtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1yZW5hbWVcbiAgQE91dHB1dCgnYWN0aXZhdGUnKSBhY3RpdmF0ZUV2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1yZW5hbWVcbiAgQE91dHB1dCgnZGVhY3RpdmF0ZScpIGRlYWN0aXZhdGVFdmVudHMgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBwcml2YXRlIHBhcmVudENvbnRleHRzID0gaW5qZWN0KENoaWxkcmVuT3V0bGV0Q29udGV4dHMpO1xuICBwcml2YXRlIGxvY2F0aW9uID0gaW5qZWN0KFZpZXdDb250YWluZXJSZWYpO1xuICBwcml2YXRlIGVudmlyb25tZW50SW5qZWN0b3IgPSBpbmplY3QoRW52aXJvbm1lbnRJbmplY3Rvcik7XG4gIHByaXZhdGUgaW5wdXRCaW5kZXIgPSBpbmplY3QoSU5QVVRfQklOREVSLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICAvKiogQG5vZG9jICovXG4gIHJlYWRvbmx5IHN1cHBvcnRzQmluZGluZ1RvQ29tcG9uZW50SW5wdXRzID0gdHJ1ZTtcblxuICAvLyBJb25pYyBwcm92aWRlcnNcbiAgcHJpdmF0ZSBjb25maWcgPSBpbmplY3QoQ29uZmlnKTtcbiAgcHJpdmF0ZSBuYXZDdHJsID0gaW5qZWN0KE5hdkNvbnRyb2xsZXIpO1xuXG4gIHNldCBhbmltYXRpb24oYW5pbWF0aW9uOiBBbmltYXRpb25CdWlsZGVyKSB7XG4gICAgdGhpcy5uYXRpdmVFbC5hbmltYXRpb24gPSBhbmltYXRpb247XG4gIH1cblxuICBzZXQgYW5pbWF0ZWQoYW5pbWF0ZWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLm5hdGl2ZUVsLmFuaW1hdGVkID0gYW5pbWF0ZWQ7XG4gIH1cblxuICBzZXQgc3dpcGVHZXN0dXJlKHN3aXBlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fc3dpcGVHZXN0dXJlID0gc3dpcGU7XG5cbiAgICB0aGlzLm5hdGl2ZUVsLnN3aXBlSGFuZGxlciA9IHN3aXBlXG4gICAgICA/IHtcbiAgICAgICAgICBjYW5TdGFydDogKCkgPT4gdGhpcy5zdGFja0N0cmwuY2FuR29CYWNrKDEpICYmICF0aGlzLnN0YWNrQ3RybC5oYXNSdW5uaW5nVGFzaygpLFxuICAgICAgICAgIG9uU3RhcnQ6ICgpID0+IHRoaXMuc3RhY2tDdHJsLnN0YXJ0QmFja1RyYW5zaXRpb24oKSxcbiAgICAgICAgICBvbkVuZDogKHNob3VsZENvbnRpbnVlKSA9PiB0aGlzLnN0YWNrQ3RybC5lbmRCYWNrVHJhbnNpdGlvbihzaG91bGRDb250aW51ZSksXG4gICAgICAgIH1cbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEF0dHJpYnV0ZSgnbmFtZScpIG5hbWU6IHN0cmluZyxcbiAgICBAT3B0aW9uYWwoKSBAQXR0cmlidXRlKCd0YWJzJykgdGFiczogc3RyaW5nLFxuICAgIGNvbW1vbkxvY2F0aW9uOiBMb2NhdGlvbixcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHJvdXRlcjogUm91dGVyLFxuICAgIHpvbmU6IE5nWm9uZSxcbiAgICBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgQFNraXBTZWxmKCkgQE9wdGlvbmFsKCkgcmVhZG9ubHkgcGFyZW50T3V0bGV0PzogSW9uUm91dGVyT3V0bGV0XG4gICkge1xuICAgIHRoaXMubmF0aXZlRWwgPSBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5uYW1lID0gbmFtZSB8fCBQUklNQVJZX09VVExFVDtcbiAgICB0aGlzLnRhYnNQcmVmaXggPSB0YWJzID09PSAndHJ1ZScgPyBnZXRVcmwocm91dGVyLCBhY3RpdmF0ZWRSb3V0ZSkgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5zdGFja0N0cmwgPSBuZXcgU3RhY2tDb250cm9sbGVyKHRoaXMudGFic1ByZWZpeCwgdGhpcy5uYXRpdmVFbCwgcm91dGVyLCB0aGlzLm5hdkN0cmwsIHpvbmUsIGNvbW1vbkxvY2F0aW9uKTtcbiAgICB0aGlzLnBhcmVudENvbnRleHRzLm9uQ2hpbGRPdXRsZXRDcmVhdGVkKHRoaXMubmFtZSwgdGhpcyBhcyBhbnkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdGFja0N0cmwuZGVzdHJveSgpO1xuICAgIHRoaXMuaW5wdXRCaW5kZXI/LnVuc3Vic2NyaWJlRnJvbVJvdXRlRGF0YSh0aGlzKTtcbiAgfVxuXG4gIGdldENvbnRleHQoKTogT3V0bGV0Q29udGV4dCB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnBhcmVudENvbnRleHRzLmdldENvbnRleHQodGhpcy5uYW1lKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdGlhbGl6ZU91dGxldFdpdGhOYW1lKCk7XG4gIH1cblxuICAvLyBOb3RlOiBJb25pYyBkZXZpYXRlcyBmcm9tIHRoZSBBbmd1bGFyIFJvdXRlciBpbXBsZW1lbnRhdGlvbiBoZXJlXG4gIHByaXZhdGUgaW5pdGlhbGl6ZU91dGxldFdpdGhOYW1lKCkge1xuICAgIGlmICghdGhpcy5hY3RpdmF0ZWQpIHtcbiAgICAgIC8vIElmIHRoZSBvdXRsZXQgd2FzIG5vdCBpbnN0YW50aWF0ZWQgYXQgdGhlIHRpbWUgdGhlIHJvdXRlIGdvdCBhY3RpdmF0ZWQgd2UgbmVlZCB0byBwb3B1bGF0ZVxuICAgICAgLy8gdGhlIG91dGxldCB3aGVuIGl0IGlzIGluaXRpYWxpemVkIChpZSBpbnNpZGUgYSBOZ0lmKVxuICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuZ2V0Q29udGV4dCgpO1xuICAgICAgaWYgKGNvbnRleHQ/LnJvdXRlKSB7XG4gICAgICAgIHRoaXMuYWN0aXZhdGVXaXRoKGNvbnRleHQucm91dGUsIGNvbnRleHQuaW5qZWN0b3IpO1xuICAgICAgfVxuICAgIH1cblxuICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBjb21wb25lbnRPblJlYWR5KHRoaXMubmF0aXZlRWwsIHJlc29sdmUpKS50aGVuKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9zd2lwZUdlc3R1cmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLnN3aXBlR2VzdHVyZSA9IHRoaXMuY29uZmlnLmdldEJvb2xlYW4oJ3N3aXBlQmFja0VuYWJsZWQnLCAodGhpcy5uYXRpdmVFbCBhcyBhbnkpLm1vZGUgPT09ICdpb3MnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldCBpc0FjdGl2YXRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmFjdGl2YXRlZDtcbiAgfVxuXG4gIGdldCBjb21wb25lbnQoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIGlmICghdGhpcy5hY3RpdmF0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT3V0bGV0IGlzIG5vdCBhY3RpdmF0ZWQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZhdGVkLmluc3RhbmNlO1xuICB9XG5cbiAgZ2V0IGFjdGl2YXRlZFJvdXRlKCk6IEFjdGl2YXRlZFJvdXRlIHtcbiAgICBpZiAoIXRoaXMuYWN0aXZhdGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ091dGxldCBpcyBub3QgYWN0aXZhdGVkJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hY3RpdmF0ZWRSb3V0ZSBhcyBBY3RpdmF0ZWRSb3V0ZTtcbiAgfVxuXG4gIGdldCBhY3RpdmF0ZWRSb3V0ZURhdGEoKTogRGF0YSB7XG4gICAgaWYgKHRoaXMuX2FjdGl2YXRlZFJvdXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYWN0aXZhdGVkUm91dGUuc25hcHNob3QuZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBgUm91dGVSZXVzZVN0cmF0ZWd5YCBpbnN0cnVjdHMgdG8gZGV0YWNoIHRoZSBzdWJ0cmVlXG4gICAqL1xuICBkZXRhY2goKTogQ29tcG9uZW50UmVmPGFueT4ge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5jb21wYXRpYmxlIHJldXNlIHN0cmF0ZWd5Jyk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIGBSb3V0ZVJldXNlU3RyYXRlZ3lgIGluc3RydWN0cyB0byByZS1hdHRhY2ggYSBwcmV2aW91c2x5IGRldGFjaGVkIHN1YnRyZWVcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYXR0YWNoKF9yZWY6IENvbXBvbmVudFJlZjxhbnk+LCBfYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlKTogdm9pZCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbmNvbXBhdGlibGUgcmV1c2Ugc3RyYXRlZ3knKTtcbiAgfVxuXG4gIGRlYWN0aXZhdGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWN0aXZhdGVkKSB7XG4gICAgICBpZiAodGhpcy5hY3RpdmF0ZWRWaWV3KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldENvbnRleHQoKSE7XG4gICAgICAgIHRoaXMuYWN0aXZhdGVkVmlldy5zYXZlZERhdGEgPSBuZXcgTWFwKGNvbnRleHQuY2hpbGRyZW5bJ2NvbnRleHRzJ10pO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbmd1bGFyIHYxMS4yLjEwIGludHJvZHVjZWQgYSBjaGFuZ2VcbiAgICAgICAgICogd2hlcmUgdGhpcyByb3V0ZSBjb250ZXh0IGlzIGNsZWFyZWQgb3V0IHdoZW5cbiAgICAgICAgICogYSByb3V0ZXItb3V0bGV0IGlzIGRlYWN0aXZhdGVkLCBIb3dldmVyLFxuICAgICAgICAgKiB3ZSBuZWVkIHRoaXMgcm91dGUgaW5mb3JtYXRpb24gaW4gb3JkZXIgdG9cbiAgICAgICAgICogcmV0dXJuIGEgdXNlciBiYWNrIHRvIHRoZSBjb3JyZWN0IHRhYiB3aGVuXG4gICAgICAgICAqIGxlYXZpbmcgYW5kIHRoZW4gZ29pbmcgYmFjayB0byB0aGUgdGFiIGNvbnRleHQuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBwcmltYXJ5T3V0bGV0ID0gdGhpcy5hY3RpdmF0ZWRWaWV3LnNhdmVkRGF0YS5nZXQoJ3ByaW1hcnknKTtcbiAgICAgICAgaWYgKHByaW1hcnlPdXRsZXQgJiYgY29udGV4dC5yb3V0ZSkge1xuICAgICAgICAgIHByaW1hcnlPdXRsZXQucm91dGUgPSB7IC4uLmNvbnRleHQucm91dGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbnN1cmUgd2UgYXJlIHNhdmluZyB0aGUgTmF2aWdhdGlvbkV4dHJhc1xuICAgICAgICAgKiBkYXRhIG90aGVyd2lzZSBpdCB3aWxsIGJlIGxvc3RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYWN0aXZhdGVkVmlldy5zYXZlZEV4dHJhcyA9IHt9O1xuICAgICAgICBpZiAoY29udGV4dC5yb3V0ZSkge1xuICAgICAgICAgIGNvbnN0IGNvbnRleHRTbmFwc2hvdCA9IGNvbnRleHQucm91dGUuc25hcHNob3Q7XG5cbiAgICAgICAgICB0aGlzLmFjdGl2YXRlZFZpZXcuc2F2ZWRFeHRyYXMucXVlcnlQYXJhbXMgPSBjb250ZXh0U25hcHNob3QucXVlcnlQYXJhbXM7XG4gICAgICAgICAgKHRoaXMuYWN0aXZhdGVkVmlldy5zYXZlZEV4dHJhcy5mcmFnbWVudCBhcyBzdHJpbmcgfCBudWxsKSA9IGNvbnRleHRTbmFwc2hvdC5mcmFnbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgYyA9IHRoaXMuY29tcG9uZW50O1xuICAgICAgdGhpcy5hY3RpdmF0ZWRWaWV3ID0gbnVsbDtcbiAgICAgIHRoaXMuYWN0aXZhdGVkID0gbnVsbDtcbiAgICAgIHRoaXMuX2FjdGl2YXRlZFJvdXRlID0gbnVsbDtcbiAgICAgIHRoaXMuZGVhY3RpdmF0ZUV2ZW50cy5lbWl0KGMpO1xuICAgIH1cbiAgfVxuXG4gIGFjdGl2YXRlV2l0aChhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsIGVudmlyb25tZW50SW5qZWN0b3I6IEVudmlyb25tZW50SW5qZWN0b3IgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNBY3RpdmF0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGFjdGl2YXRlIGFuIGFscmVhZHkgYWN0aXZhdGVkIG91dGxldCcpO1xuICAgIH1cbiAgICB0aGlzLl9hY3RpdmF0ZWRSb3V0ZSA9IGFjdGl2YXRlZFJvdXRlO1xuXG4gICAgbGV0IGNtcFJlZjogYW55O1xuICAgIGxldCBlbnRlcmluZ1ZpZXcgPSB0aGlzLnN0YWNrQ3RybC5nZXRFeGlzdGluZ1ZpZXcoYWN0aXZhdGVkUm91dGUpO1xuICAgIGlmIChlbnRlcmluZ1ZpZXcpIHtcbiAgICAgIGNtcFJlZiA9IHRoaXMuYWN0aXZhdGVkID0gZW50ZXJpbmdWaWV3LnJlZjtcbiAgICAgIGNvbnN0IHNhdmVkID0gZW50ZXJpbmdWaWV3LnNhdmVkRGF0YTtcbiAgICAgIGlmIChzYXZlZCkge1xuICAgICAgICAvLyBzZWxmLXJlc3RvcmVcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuZ2V0Q29udGV4dCgpITtcbiAgICAgICAgY29udGV4dC5jaGlsZHJlblsnY29udGV4dHMnXSA9IHNhdmVkO1xuICAgICAgfVxuICAgICAgLy8gVXBkYXRlZCBhY3RpdmF0ZWQgcm91dGUgcHJveHkgZm9yIHRoaXMgY29tcG9uZW50XG4gICAgICB0aGlzLnVwZGF0ZUFjdGl2YXRlZFJvdXRlUHJveHkoY21wUmVmLmluc3RhbmNlLCBhY3RpdmF0ZWRSb3V0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHNuYXBzaG90ID0gKGFjdGl2YXRlZFJvdXRlIGFzIGFueSkuX2Z1dHVyZVNuYXBzaG90O1xuXG4gICAgICAvKipcbiAgICAgICAqIEFuZ3VsYXIgMTQgaW50cm9kdWNlcyBhIG5ldyBgbG9hZENvbXBvbmVudGAgcHJvcGVydHkgdG8gdGhlIHJvdXRlIGNvbmZpZy5cbiAgICAgICAqIFRoaXMgZnVuY3Rpb24gd2lsbCBhc3NpZ24gYSBgY29tcG9uZW50YCBwcm9wZXJ0eSB0byB0aGUgcm91dGUgc25hcHNob3QuXG4gICAgICAgKiBXZSBjaGVjayBmb3IgdGhlIHByZXNlbmNlIG9mIHRoaXMgcHJvcGVydHkgdG8gZGV0ZXJtaW5lIGlmIHRoZSByb3V0ZSBpc1xuICAgICAgICogdXNpbmcgc3RhbmRhbG9uZSBjb21wb25lbnRzLlxuICAgICAgICovXG4gICAgICBjb25zdCBjaGlsZENvbnRleHRzID0gdGhpcy5wYXJlbnRDb250ZXh0cy5nZXRPckNyZWF0ZUNvbnRleHQodGhpcy5uYW1lKS5jaGlsZHJlbjtcblxuICAgICAgLy8gV2UgY3JlYXRlIGFuIGFjdGl2YXRlZCByb3V0ZSBwcm94eSBvYmplY3QgdGhhdCB3aWxsIG1haW50YWluIGZ1dHVyZSB1cGRhdGVzIGZvciB0aGlzIGNvbXBvbmVudFxuICAgICAgLy8gb3ZlciBpdHMgbGlmZWN5Y2xlIGluIHRoZSBzdGFjay5cbiAgICAgIGNvbnN0IGNvbXBvbmVudCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7XG4gICAgICBjb25zdCBhY3RpdmF0ZWRSb3V0ZVByb3h5ID0gdGhpcy5jcmVhdGVBY3RpdmF0ZWRSb3V0ZVByb3h5KGNvbXBvbmVudCQsIGFjdGl2YXRlZFJvdXRlKTtcblxuICAgICAgY29uc3QgaW5qZWN0b3IgPSBuZXcgT3V0bGV0SW5qZWN0b3IoYWN0aXZhdGVkUm91dGVQcm94eSwgY2hpbGRDb250ZXh0cywgdGhpcy5sb2NhdGlvbi5pbmplY3Rvcik7XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICBjb25zdCBjb21wb25lbnQgPSBzbmFwc2hvdC5yb3V0ZUNvbmZpZyEuY29tcG9uZW50ID8/IHNuYXBzaG90LmNvbXBvbmVudDtcblxuICAgICAgLyoqXG4gICAgICAgKiBWaWV3IGNvbXBvbmVudHMgbmVlZCB0byBiZSBhZGRlZCBhcyBhIGNoaWxkIG9mIGlvbi1yb3V0ZXItb3V0bGV0XG4gICAgICAgKiBmb3IgcGFnZSB0cmFuc2l0aW9ucyBhbmQgc3dpcGUgdG8gZ28gYmFjay5cbiAgICAgICAqIEhvd2V2ZXIsIGNyZWF0ZUNvbXBvbmVudCBtb3VudHMgY29tcG9uZW50cyBhcyBzaWJsaW5ncyBvZiB0aGVcbiAgICAgICAqIFZpZXdDb250YWluZXJSZWYuIEFzIGEgcmVzdWx0LCBvdXRsZXRDb250ZW50IG11c3QgcmVmZXJlbmNlXG4gICAgICAgKiBhbiBuZy1jb250YWluZXIgaW5zaWRlIG9mIGlvbi1yb3V0ZXItb3V0bGV0IGFuZCBub3RcbiAgICAgICAqIGlvbi1yb3V0ZXItb3V0bGV0IGl0c2VsZi5cbiAgICAgICAqL1xuICAgICAgY21wUmVmID0gdGhpcy5hY3RpdmF0ZWQgPSB0aGlzLm91dGxldENvbnRlbnQuY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudCwge1xuICAgICAgICBpbmRleDogdGhpcy5vdXRsZXRDb250ZW50Lmxlbmd0aCxcbiAgICAgICAgaW5qZWN0b3IsXG4gICAgICAgIGVudmlyb25tZW50SW5qZWN0b3I6IGVudmlyb25tZW50SW5qZWN0b3IgPz8gdGhpcy5lbnZpcm9ubWVudEluamVjdG9yLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE9uY2UgdGhlIGNvbXBvbmVudCBpcyBjcmVhdGVkIHdlIGNhbiBwdXNoIGl0IHRvIG91ciBsb2NhbCBzdWJqZWN0IHN1cHBsaWVkIHRvIHRoZSBwcm94eVxuICAgICAgY29tcG9uZW50JC5uZXh0KGNtcFJlZi5pbnN0YW5jZSk7XG5cbiAgICAgIC8vIENhbGxpbmcgYG1hcmtGb3JDaGVja2AgdG8gbWFrZSBzdXJlIHdlIHdpbGwgcnVuIHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIHdoZW4gdGhlXG4gICAgICAvLyBgUm91dGVyT3V0bGV0YCBpcyBpbnNpZGUgYSBgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoYCBjb21wb25lbnQuXG5cbiAgICAgIC8qKlxuICAgICAgICogQXQgdGhpcyBwb2ludCB0aGlzLmFjdGl2YXRlZCBoYXMgYmVlbiBzZXQgZWFybGllclxuICAgICAgICogaW4gdGhpcyBmdW5jdGlvbiwgc28gaXQgaXMgZ3VhcmFudGVlZCB0byBiZSBub24tbnVsbC5cbiAgICAgICAqL1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgIGVudGVyaW5nVmlldyA9IHRoaXMuc3RhY2tDdHJsLmNyZWF0ZVZpZXcodGhpcy5hY3RpdmF0ZWQhLCBhY3RpdmF0ZWRSb3V0ZSk7XG5cbiAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZXMgdG8gdGhlIHByb3h5IGJ5IGNvbXBvbmVudFxuICAgICAgdGhpcy5wcm94eU1hcC5zZXQoY21wUmVmLmluc3RhbmNlLCBhY3RpdmF0ZWRSb3V0ZVByb3h5KTtcbiAgICAgIHRoaXMuY3VycmVudEFjdGl2YXRlZFJvdXRlJC5uZXh0KHsgY29tcG9uZW50OiBjbXBSZWYuaW5zdGFuY2UsIGFjdGl2YXRlZFJvdXRlIH0pO1xuICAgIH1cblxuICAgIHRoaXMuaW5wdXRCaW5kZXI/LmJpbmRBY3RpdmF0ZWRSb3V0ZVRvT3V0bGV0Q29tcG9uZW50KHRoaXMpO1xuXG4gICAgdGhpcy5hY3RpdmF0ZWRWaWV3ID0gZW50ZXJpbmdWaWV3O1xuXG4gICAgLyoqXG4gICAgICogVGhlIHRvcCBvdXRsZXQgaXMgc2V0IHByaW9yIHRvIHRoZSBlbnRlcmluZyB2aWV3J3MgdHJhbnNpdGlvbiBjb21wbGV0aW5nLFxuICAgICAqIHNvIHRoYXQgd2hlbiB3ZSBoYXZlIG5lc3RlZCBvdXRsZXRzIChlLmcuIGlvbi10YWJzIGluc2lkZSBhbiBpb24tcm91dGVyLW91dGxldCksXG4gICAgICogdGhlIHRhYnMgb3V0bGV0IHdpbGwgYmUgYXNzaWduZWQgYXMgdGhlIHRvcCBvdXRsZXQgd2hlbiBhIHZpZXcgaW5zaWRlIHRhYnMgaXNcbiAgICAgKiBhY3RpdmF0ZWQuXG4gICAgICpcbiAgICAgKiBJbiB0aGlzIHNjZW5hcmlvLCBhY3RpdmVXaXRoIGlzIGNhbGxlZCBmb3IgYm90aCB0aGUgdGFicyBhbmQgdGhlIHJvb3Qgcm91dGVyIG91dGxldC5cbiAgICAgKiBUbyBhdm9pZCBhIHJhY2UgY29uZGl0aW9uLCB3ZSBhc3NpZ24gdGhlIHRvcCBvdXRsZXQgc3luY2hyb25vdXNseS5cbiAgICAgKi9cbiAgICB0aGlzLm5hdkN0cmwuc2V0VG9wT3V0bGV0KHRoaXMpO1xuXG4gICAgY29uc3QgbGVhdmluZ1ZpZXcgPSB0aGlzLnN0YWNrQ3RybC5nZXRBY3RpdmVWaWV3KCk7XG5cbiAgICB0aGlzLnN0YWNrV2lsbENoYW5nZS5lbWl0KHtcbiAgICAgIGVudGVyaW5nVmlldyxcbiAgICAgIHRhYlN3aXRjaDogaXNUYWJTd2l0Y2goZW50ZXJpbmdWaWV3LCBsZWF2aW5nVmlldyksXG4gICAgfSk7XG5cbiAgICB0aGlzLnN0YWNrQ3RybC5zZXRBY3RpdmUoZW50ZXJpbmdWaWV3KS50aGVuKChkYXRhKSA9PiB7XG4gICAgICB0aGlzLmFjdGl2YXRlRXZlbnRzLmVtaXQoY21wUmVmLmluc3RhbmNlKTtcbiAgICAgIHRoaXMuc3RhY2tEaWRDaGFuZ2UuZW1pdChkYXRhKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGVyZSBhcmUgcGFnZXMgaW4gdGhlIHN0YWNrIHRvIGdvIGJhY2suXG4gICAqL1xuICBjYW5Hb0JhY2soZGVlcCA9IDEsIHN0YWNrSWQ/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja0N0cmwuY2FuR29CYWNrKGRlZXAsIHN0YWNrSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRvIGB0cnVlYCBpZiBpdCB0aGUgb3V0bGV0IHdhcyBhYmxlIHRvIHN1Y2Vzc2Z1bGx5IHBvcCB0aGUgbGFzdCBOIHBhZ2VzLlxuICAgKi9cbiAgcG9wKGRlZXAgPSAxLCBzdGFja0lkPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tDdHJsLnBvcChkZWVwLCBzdGFja0lkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBVUkwgb2YgdGhlIGFjdGl2ZSBwYWdlIG9mIGVhY2ggc3RhY2suXG4gICAqL1xuICBnZXRMYXN0VXJsKHN0YWNrSWQ/OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFjdGl2ZSA9IHRoaXMuc3RhY2tDdHJsLmdldExhc3RVcmwoc3RhY2tJZCk7XG4gICAgcmV0dXJuIGFjdGl2ZSA/IGFjdGl2ZS51cmwgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgUm91dGVWaWV3IG9mIHRoZSBhY3RpdmUgcGFnZSBvZiBlYWNoIHN0YWNrLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldExhc3RSb3V0ZVZpZXcoc3RhY2tJZD86IHN0cmluZyk6IFJvdXRlVmlldyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tDdHJsLmdldExhc3RVcmwoc3RhY2tJZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcm9vdCB2aWV3IGluIHRoZSB0YWIgc3RhY2suXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZ2V0Um9vdFZpZXcoc3RhY2tJZD86IHN0cmluZyk6IFJvdXRlVmlldyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tDdHJsLmdldFJvb3RVcmwoc3RhY2tJZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYWN0aXZlIHN0YWNrIElELiBJbiB0aGUgY29udGV4dCBvZiBpb24tdGFicywgaXQgbWVhbnMgdGhlIGFjdGl2ZSB0YWIuXG4gICAqL1xuICBnZXRBY3RpdmVTdGFja0lkKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhY2tDdHJsLmdldEFjdGl2ZVN0YWNrSWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaW5jZSB0aGUgYWN0aXZhdGVkIHJvdXRlIGNhbiBjaGFuZ2Ugb3ZlciB0aGUgbGlmZSB0aW1lIG9mIGEgY29tcG9uZW50IGluIGFuIGlvbiByb3V0ZXIgb3V0bGV0LCB3ZSBjcmVhdGVcbiAgICogYSBwcm94eSBzbyB0aGF0IHdlIGNhbiB1cGRhdGUgdGhlIHZhbHVlcyBvdmVyIHRpbWUgYXMgYSB1c2VyIG5hdmlnYXRlcyBiYWNrIHRvIGNvbXBvbmVudHMgYWxyZWFkeSBpbiB0aGUgc3RhY2suXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUFjdGl2YXRlZFJvdXRlUHJveHkoY29tcG9uZW50JDogT2JzZXJ2YWJsZTxhbnk+LCBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUpOiBBY3RpdmF0ZWRSb3V0ZSB7XG4gICAgY29uc3QgcHJveHk6IGFueSA9IG5ldyBBY3RpdmF0ZWRSb3V0ZSgpO1xuXG4gICAgcHJveHkuX2Z1dHVyZVNuYXBzaG90ID0gKGFjdGl2YXRlZFJvdXRlIGFzIGFueSkuX2Z1dHVyZVNuYXBzaG90O1xuICAgIHByb3h5Ll9yb3V0ZXJTdGF0ZSA9IChhY3RpdmF0ZWRSb3V0ZSBhcyBhbnkpLl9yb3V0ZXJTdGF0ZTtcbiAgICBwcm94eS5zbmFwc2hvdCA9IGFjdGl2YXRlZFJvdXRlLnNuYXBzaG90O1xuICAgIHByb3h5Lm91dGxldCA9IGFjdGl2YXRlZFJvdXRlLm91dGxldDtcbiAgICBwcm94eS5jb21wb25lbnQgPSBhY3RpdmF0ZWRSb3V0ZS5jb21wb25lbnQ7XG5cbiAgICAvLyBTZXR1cCB3cmFwcGVycyBmb3IgdGhlIG9ic2VydmFibGVzIHNvIGNvbnN1bWVycyBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHN3aXRjaGluZyB0byBuZXcgb2JzZXJ2YWJsZXMgYXMgdGhlIHN0YXRlIHVwZGF0ZXNcbiAgICAocHJveHkgYXMgYW55KS5fcGFyYW1NYXAgPSB0aGlzLnByb3h5T2JzZXJ2YWJsZShjb21wb25lbnQkLCAncGFyYW1NYXAnKTtcbiAgICAocHJveHkgYXMgYW55KS5fcXVlcnlQYXJhbU1hcCA9IHRoaXMucHJveHlPYnNlcnZhYmxlKGNvbXBvbmVudCQsICdxdWVyeVBhcmFtTWFwJyk7XG4gICAgcHJveHkudXJsID0gdGhpcy5wcm94eU9ic2VydmFibGUoY29tcG9uZW50JCwgJ3VybCcpO1xuICAgIHByb3h5LnBhcmFtcyA9IHRoaXMucHJveHlPYnNlcnZhYmxlKGNvbXBvbmVudCQsICdwYXJhbXMnKTtcbiAgICBwcm94eS5xdWVyeVBhcmFtcyA9IHRoaXMucHJveHlPYnNlcnZhYmxlKGNvbXBvbmVudCQsICdxdWVyeVBhcmFtcycpO1xuICAgIHByb3h5LmZyYWdtZW50ID0gdGhpcy5wcm94eU9ic2VydmFibGUoY29tcG9uZW50JCwgJ2ZyYWdtZW50Jyk7XG4gICAgcHJveHkuZGF0YSA9IHRoaXMucHJveHlPYnNlcnZhYmxlKGNvbXBvbmVudCQsICdkYXRhJyk7XG5cbiAgICByZXR1cm4gcHJveHkgYXMgQWN0aXZhdGVkUm91dGU7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgd3JhcHBlZCBvYnNlcnZhYmxlIHRoYXQgd2lsbCBzd2l0Y2ggdG8gdGhlIGxhdGVzdCBhY3RpdmF0ZWQgcm91dGUgbWF0Y2hlZCBieSB0aGUgZ2l2ZW4gY29tcG9uZW50XG4gICAqL1xuICBwcml2YXRlIHByb3h5T2JzZXJ2YWJsZShjb21wb25lbnQkOiBPYnNlcnZhYmxlPGFueT4sIHBhdGg6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIGNvbXBvbmVudCQucGlwZShcbiAgICAgIC8vIEZpcnN0IHdhaXQgdW50aWwgdGhlIGNvbXBvbmVudCBpbnN0YW5jZSBpcyBwdXNoZWRcbiAgICAgIGZpbHRlcigoY29tcG9uZW50KSA9PiAhIWNvbXBvbmVudCksXG4gICAgICBzd2l0Y2hNYXAoKGNvbXBvbmVudCkgPT5cbiAgICAgICAgdGhpcy5jdXJyZW50QWN0aXZhdGVkUm91dGUkLnBpcGUoXG4gICAgICAgICAgZmlsdGVyKChjdXJyZW50KSA9PiBjdXJyZW50ICE9PSBudWxsICYmIGN1cnJlbnQuY29tcG9uZW50ID09PSBjb21wb25lbnQpLFxuICAgICAgICAgIHN3aXRjaE1hcCgoY3VycmVudCkgPT4gY3VycmVudCAmJiAoY3VycmVudC5hY3RpdmF0ZWRSb3V0ZSBhcyBhbnkpW3BhdGhdKSxcbiAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGFjdGl2YXRlZCByb3V0ZSBwcm94eSBmb3IgdGhlIGdpdmVuIGNvbXBvbmVudCB0byB0aGUgbmV3IGluY29taW5nIHJvdXRlciBzdGF0ZVxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVBY3RpdmF0ZWRSb3V0ZVByb3h5KGNvbXBvbmVudDogYW55LCBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUpOiB2b2lkIHtcbiAgICBjb25zdCBwcm94eSA9IHRoaXMucHJveHlNYXAuZ2V0KGNvbXBvbmVudCk7XG4gICAgaWYgKCFwcm94eSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZmluZCBhY3RpdmF0ZWQgcm91dGUgcHJveHkgZm9yIHZpZXdgKTtcbiAgICB9XG5cbiAgICAocHJveHkgYXMgYW55KS5fZnV0dXJlU25hcHNob3QgPSAoYWN0aXZhdGVkUm91dGUgYXMgYW55KS5fZnV0dXJlU25hcHNob3Q7XG4gICAgKHByb3h5IGFzIGFueSkuX3JvdXRlclN0YXRlID0gKGFjdGl2YXRlZFJvdXRlIGFzIGFueSkuX3JvdXRlclN0YXRlO1xuICAgIHByb3h5LnNuYXBzaG90ID0gYWN0aXZhdGVkUm91dGUuc25hcHNob3Q7XG4gICAgcHJveHkub3V0bGV0ID0gYWN0aXZhdGVkUm91dGUub3V0bGV0O1xuICAgIHByb3h5LmNvbXBvbmVudCA9IGFjdGl2YXRlZFJvdXRlLmNvbXBvbmVudDtcblxuICAgIHRoaXMuY3VycmVudEFjdGl2YXRlZFJvdXRlJC5uZXh0KHsgY29tcG9uZW50LCBhY3RpdmF0ZWRSb3V0ZSB9KTtcbiAgfVxufVxuXG5jbGFzcyBPdXRsZXRJbmplY3RvciBpbXBsZW1lbnRzIEluamVjdG9yIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsIHByaXZhdGUgY2hpbGRDb250ZXh0czogQ2hpbGRyZW5PdXRsZXRDb250ZXh0cywgcHJpdmF0ZSBwYXJlbnQ6IEluamVjdG9yKSB7fVxuXG4gIGdldCh0b2tlbjogYW55LCBub3RGb3VuZFZhbHVlPzogYW55KTogYW55IHtcbiAgICBpZiAodG9rZW4gPT09IEFjdGl2YXRlZFJvdXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yb3V0ZTtcbiAgICB9XG5cbiAgICBpZiAodG9rZW4gPT09IENoaWxkcmVuT3V0bGV0Q29udGV4dHMpIHtcbiAgICAgIHJldHVybiB0aGlzLmNoaWxkQ29udGV4dHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucGFyZW50LmdldCh0b2tlbiwgbm90Rm91bmRWYWx1ZSk7XG4gIH1cbn1cblxuLy8gVE9ETzogRlctNDc4NSAtIFJlbW92ZSB0aGlzIG9uY2UgQW5ndWxhciAxNSBzdXBwb3J0IGlzIGRyb3BwZWRcbmNvbnN0IElOUFVUX0JJTkRFUiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxSb3V0ZWRDb21wb25lbnRJbnB1dEJpbmRlcj4oJycpO1xuXG4vKipcbiAqIEluamVjdGFibGUgdXNlZCBhcyBhIHRyZWUtc2hha2FibGUgcHJvdmlkZXIgZm9yIG9wdGluZyBpbiB0byBiaW5kaW5nIHJvdXRlciBkYXRhIHRvIGNvbXBvbmVudFxuICogaW5wdXRzLlxuICpcbiAqIFRoZSBSb3V0ZXJPdXRsZXQgcmVnaXN0ZXJzIGl0c2VsZiB3aXRoIHRoaXMgc2VydmljZSB3aGVuIGFuIGBBY3RpdmF0ZWRSb3V0ZWAgaXMgYXR0YWNoZWQgb3JcbiAqIGFjdGl2YXRlZC4gV2hlbiB0aGlzIGhhcHBlbnMsIHRoZSBzZXJ2aWNlIHN1YnNjcmliZXMgdG8gdGhlIGBBY3RpdmF0ZWRSb3V0ZWAgb2JzZXJ2YWJsZXMgKHBhcmFtcyxcbiAqIHF1ZXJ5UGFyYW1zLCBkYXRhKSBhbmQgc2V0cyB0aGUgaW5wdXRzIG9mIHRoZSBjb21wb25lbnQgdXNpbmcgYENvbXBvbmVudFJlZi5zZXRJbnB1dGAuXG4gKiBJbXBvcnRhbnRseSwgd2hlbiBhbiBpbnB1dCBkb2VzIG5vdCBoYXZlIGFuIGl0ZW0gaW4gdGhlIHJvdXRlIGRhdGEgd2l0aCBhIG1hdGNoaW5nIGtleSwgdGhpc1xuICogaW5wdXQgaXMgc2V0IHRvIGB1bmRlZmluZWRgLiBJZiBpdCB3ZXJlIG5vdCBkb25lIHRoaXMgd2F5LCB0aGUgcHJldmlvdXMgaW5mb3JtYXRpb24gd291bGQgYmVcbiAqIHJldGFpbmVkIGlmIHRoZSBkYXRhIGdvdCByZW1vdmVkIGZyb20gdGhlIHJvdXRlIChpLmUuIGlmIGEgcXVlcnkgcGFyYW1ldGVyIGlzIHJlbW92ZWQpLlxuICpcbiAqIFRoZSBgUm91dGVyT3V0bGV0YCBzaG91bGQgdW5yZWdpc3RlciBpdHNlbGYgd2hlbiBkZXN0cm95ZWQgdmlhIGB1bnN1YnNjcmliZUZyb21Sb3V0ZURhdGFgIHNvIHRoYXRcbiAqIHRoZSBzdWJzY3JpcHRpb25zIGFyZSBjbGVhbmVkIHVwLlxuICovXG5ASW5qZWN0YWJsZSgpXG5jbGFzcyBSb3V0ZWRDb21wb25lbnRJbnB1dEJpbmRlciB7XG4gIHByaXZhdGUgb3V0bGV0RGF0YVN1YnNjcmlwdGlvbnMgPSBuZXcgTWFwPElvblJvdXRlck91dGxldCwgU3Vic2NyaXB0aW9uPigpO1xuXG4gIGJpbmRBY3RpdmF0ZWRSb3V0ZVRvT3V0bGV0Q29tcG9uZW50KG91dGxldDogSW9uUm91dGVyT3V0bGV0KTogdm9pZCB7XG4gICAgdGhpcy51bnN1YnNjcmliZUZyb21Sb3V0ZURhdGEob3V0bGV0KTtcbiAgICB0aGlzLnN1YnNjcmliZVRvUm91dGVEYXRhKG91dGxldCk7XG4gIH1cblxuICB1bnN1YnNjcmliZUZyb21Sb3V0ZURhdGEob3V0bGV0OiBJb25Sb3V0ZXJPdXRsZXQpOiB2b2lkIHtcbiAgICB0aGlzLm91dGxldERhdGFTdWJzY3JpcHRpb25zLmdldChvdXRsZXQpPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMub3V0bGV0RGF0YVN1YnNjcmlwdGlvbnMuZGVsZXRlKG91dGxldCk7XG4gIH1cblxuICBwcml2YXRlIHN1YnNjcmliZVRvUm91dGVEYXRhKG91dGxldDogSW9uUm91dGVyT3V0bGV0KSB7XG4gICAgY29uc3QgeyBhY3RpdmF0ZWRSb3V0ZSB9ID0gb3V0bGV0O1xuICAgIGNvbnN0IGRhdGFTdWJzY3JpcHRpb24gPSBjb21iaW5lTGF0ZXN0KFthY3RpdmF0ZWRSb3V0ZS5xdWVyeVBhcmFtcywgYWN0aXZhdGVkUm91dGUucGFyYW1zLCBhY3RpdmF0ZWRSb3V0ZS5kYXRhXSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKFtxdWVyeVBhcmFtcywgcGFyYW1zLCBkYXRhXSwgaW5kZXgpID0+IHtcbiAgICAgICAgICBkYXRhID0geyAuLi5xdWVyeVBhcmFtcywgLi4ucGFyYW1zLCAuLi5kYXRhIH07XG4gICAgICAgICAgLy8gR2V0IHRoZSBmaXJzdCByZXN1bHQgZnJvbSB0aGUgZGF0YSBzdWJzY3JpcHRpb24gc3luY2hyb25vdXNseSBzbyBpdCdzIGF2YWlsYWJsZSB0b1xuICAgICAgICAgIC8vIHRoZSBjb21wb25lbnQgYXMgc29vbiBhcyBwb3NzaWJsZSAoYW5kIGRvZXNuJ3QgcmVxdWlyZSBhIHNlY29uZCBjaGFuZ2UgZGV0ZWN0aW9uKS5cbiAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBvZihkYXRhKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUHJvbWlzZS5yZXNvbHZlIGlzIHVzZWQgdG8gYXZvaWQgc3luY2hyb25vdXNseSB3cml0aW5nIHRoZSB3cm9uZyBkYXRhIHdoZW5cbiAgICAgICAgICAvLyB0d28gb2YgdGhlIE9ic2VydmFibGVzIGluIHRoZSBgY29tYmluZUxhdGVzdGAgc3RyZWFtIGVtaXQgb25lIGFmdGVyXG4gICAgICAgICAgLy8gYW5vdGhlci5cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGRhdGEpO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAvLyBPdXRsZXQgbWF5IGhhdmUgYmVlbiBkZWFjdGl2YXRlZCBvciBjaGFuZ2VkIG5hbWVzIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCBhIGRpZmZlcmVudFxuICAgICAgICAvLyByb3V0ZVxuICAgICAgICBpZiAoXG4gICAgICAgICAgIW91dGxldC5pc0FjdGl2YXRlZCB8fFxuICAgICAgICAgICFvdXRsZXQuYWN0aXZhdGVkQ29tcG9uZW50UmVmIHx8XG4gICAgICAgICAgb3V0bGV0LmFjdGl2YXRlZFJvdXRlICE9PSBhY3RpdmF0ZWRSb3V0ZSB8fFxuICAgICAgICAgIGFjdGl2YXRlZFJvdXRlLmNvbXBvbmVudCA9PT0gbnVsbFxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnVuc3Vic2NyaWJlRnJvbVJvdXRlRGF0YShvdXRsZXQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG1pcnJvciA9IHJlZmxlY3RDb21wb25lbnRUeXBlKGFjdGl2YXRlZFJvdXRlLmNvbXBvbmVudCk7XG4gICAgICAgIGlmICghbWlycm9yKSB7XG4gICAgICAgICAgdGhpcy51bnN1YnNjcmliZUZyb21Sb3V0ZURhdGEob3V0bGV0KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IHsgdGVtcGxhdGVOYW1lIH0gb2YgbWlycm9yLmlucHV0cykge1xuICAgICAgICAgIG91dGxldC5hY3RpdmF0ZWRDb21wb25lbnRSZWYuc2V0SW5wdXQodGVtcGxhdGVOYW1lLCBkYXRhW3RlbXBsYXRlTmFtZV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIHRoaXMub3V0bGV0RGF0YVN1YnNjcmlwdGlvbnMuc2V0KG91dGxldCwgZGF0YVN1YnNjcmlwdGlvbik7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHByb3ZpZGVDb21wb25lbnRJbnB1dEJpbmRpbmcgPSAoKTogUHJvdmlkZXIgPT4ge1xuICByZXR1cm4ge1xuICAgIHByb3ZpZGU6IElOUFVUX0JJTkRFUixcbiAgICB1c2VGYWN0b3J5OiBjb21wb25lbnRJbnB1dEJpbmRpbmdGYWN0b3J5LFxuICAgIGRlcHM6IFtSb3V0ZXJdLFxuICB9O1xufTtcblxuZnVuY3Rpb24gY29tcG9uZW50SW5wdXRCaW5kaW5nRmFjdG9yeShyb3V0ZXI/OiBSb3V0ZXIpIHtcbiAgLyoqXG4gICAqIFdlIGNhc3QgdGhlIHJvdXRlciB0byBhbnkgaGVyZSwgc2luY2UgdGhlIGNvbXBvbmVudElucHV0QmluZGluZ0VuYWJsZWRcbiAgICogcHJvcGVydHkgaXMgbm90IGF2YWlsYWJsZSB1bnRpbCBBbmd1bGFyIHYxNi5cbiAgICovXG4gIGlmICgocm91dGVyIGFzIGFueSk/LmNvbXBvbmVudElucHV0QmluZGluZ0VuYWJsZWQpIHtcbiAgICByZXR1cm4gbmV3IFJvdXRlZENvbXBvbmVudElucHV0QmluZGVyKCk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG4iXX0=
|