@angular/router 15.0.0 → 15.0.2

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.
Files changed (40) hide show
  1. package/esm2020/src/components/empty_outlet.mjs +3 -3
  2. package/esm2020/src/deprecated_load_children.mjs +3 -1
  3. package/esm2020/src/directives/router_link.mjs +3 -3
  4. package/esm2020/src/directives/router_link_active.mjs +3 -3
  5. package/esm2020/src/directives/router_outlet.mjs +5 -5
  6. package/esm2020/src/index.mjs +1 -1
  7. package/esm2020/src/models.mjs +1 -1
  8. package/esm2020/src/navigation_transition.mjs +380 -0
  9. package/esm2020/src/operators/activate_routes.mjs +1 -1
  10. package/esm2020/src/operators/apply_redirects.mjs +1 -1
  11. package/esm2020/src/operators/check_guards.mjs +1 -1
  12. package/esm2020/src/operators/recognize.mjs +1 -1
  13. package/esm2020/src/operators/resolve_data.mjs +1 -1
  14. package/esm2020/src/page_title_strategy.mjs +6 -6
  15. package/esm2020/src/private_export.mjs +1 -1
  16. package/esm2020/src/provide_router.mjs +11 -15
  17. package/esm2020/src/route_reuse_strategy.mjs +15 -1
  18. package/esm2020/src/router.mjs +76 -407
  19. package/esm2020/src/router_config_loader.mjs +3 -3
  20. package/esm2020/src/router_module.mjs +9 -7
  21. package/esm2020/src/router_outlet_context.mjs +3 -3
  22. package/esm2020/src/router_preloader.mjs +9 -9
  23. package/esm2020/src/router_scroller.mjs +20 -21
  24. package/esm2020/src/router_state.mjs +1 -1
  25. package/esm2020/src/url_handling_strategy.mjs +15 -1
  26. package/esm2020/src/url_tree.mjs +4 -4
  27. package/esm2020/src/version.mjs +1 -1
  28. package/esm2020/testing/src/router_testing_module.mjs +4 -4
  29. package/fesm2015/router.mjs +790 -732
  30. package/fesm2015/router.mjs.map +1 -1
  31. package/fesm2015/testing.mjs +5 -5
  32. package/fesm2015/upgrade.mjs +1 -1
  33. package/fesm2020/router.mjs +794 -735
  34. package/fesm2020/router.mjs.map +1 -1
  35. package/fesm2020/testing.mjs +5 -5
  36. package/fesm2020/upgrade.mjs +1 -1
  37. package/index.d.ts +24 -80
  38. package/package.json +4 -4
  39. package/testing/index.d.ts +1 -1
  40. package/upgrade/index.d.ts +1 -1
@@ -0,0 +1,380 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ import { EnvironmentInjector, inject, Injectable } from '@angular/core';
9
+ import { BehaviorSubject, combineLatest, EMPTY, of, Subject } from 'rxjs';
10
+ import { catchError, defaultIfEmpty, filter, finalize, map, switchMap, take, tap } from 'rxjs/operators';
11
+ import { createRouterState } from './create_router_state';
12
+ import { GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RoutesRecognized } from './events';
13
+ import { isNavigationCancelingError, isRedirectingNavigationCancelingError, redirectingNavigationError } from './navigation_canceling_error';
14
+ import { activateRoutes } from './operators/activate_routes';
15
+ import { applyRedirects } from './operators/apply_redirects';
16
+ import { checkGuards } from './operators/check_guards';
17
+ import { recognize } from './operators/recognize';
18
+ import { resolveData } from './operators/resolve_data';
19
+ import { switchTap } from './operators/switch_tap';
20
+ import { RouterConfigLoader } from './router_config_loader';
21
+ import { ChildrenOutletContexts } from './router_outlet_context';
22
+ import { createEmptyState } from './router_state';
23
+ import { isUrlTree, UrlSerializer } from './url_tree';
24
+ import { getAllRouteGuards } from './utils/preactivation';
25
+ import * as i0 from "@angular/core";
26
+ const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
27
+ export class NavigationTransitions {
28
+ constructor() {
29
+ this.currentNavigation = null;
30
+ this.lastSuccessfulNavigation = null;
31
+ this.events = new Subject();
32
+ this.configLoader = inject(RouterConfigLoader);
33
+ this.environmentInjector = inject(EnvironmentInjector);
34
+ this.urlSerializer = inject(UrlSerializer);
35
+ this.rootContexts = inject(ChildrenOutletContexts);
36
+ this.navigationId = 0;
37
+ const onLoadStart = (r) => this.events.next(new RouteConfigLoadStart(r));
38
+ const onLoadEnd = (r) => this.events.next(new RouteConfigLoadEnd(r));
39
+ this.configLoader.onLoadEndListener = onLoadEnd;
40
+ this.configLoader.onLoadStartListener = onLoadStart;
41
+ }
42
+ get hasRequestedNavigation() {
43
+ return this.navigationId !== 0;
44
+ }
45
+ complete() {
46
+ this.transitions?.complete();
47
+ }
48
+ handleNavigationRequest(request) {
49
+ const id = ++this.navigationId;
50
+ this.transitions?.next({ ...this.transitions.value, ...request, id });
51
+ }
52
+ setupNavigations(router) {
53
+ this.transitions = new BehaviorSubject({
54
+ id: 0,
55
+ targetPageId: 0,
56
+ currentUrlTree: router.currentUrlTree,
57
+ currentRawUrl: router.currentUrlTree,
58
+ extractedUrl: router.urlHandlingStrategy.extract(router.currentUrlTree),
59
+ urlAfterRedirects: router.urlHandlingStrategy.extract(router.currentUrlTree),
60
+ rawUrl: router.currentUrlTree,
61
+ extras: {},
62
+ resolve: null,
63
+ reject: null,
64
+ promise: Promise.resolve(true),
65
+ source: 'imperative',
66
+ restoredState: null,
67
+ currentSnapshot: router.routerState.snapshot,
68
+ targetSnapshot: null,
69
+ currentRouterState: router.routerState,
70
+ targetRouterState: null,
71
+ guards: { canActivateChecks: [], canDeactivateChecks: [] },
72
+ guardsResult: null,
73
+ });
74
+ return this.transitions.pipe(filter(t => t.id !== 0),
75
+ // Extract URL
76
+ map(t => ({ ...t, extractedUrl: router.urlHandlingStrategy.extract(t.rawUrl) })),
77
+ // Using switchMap so we cancel executing navigations when a new one comes in
78
+ switchMap(overallTransitionState => {
79
+ let completed = false;
80
+ let errored = false;
81
+ return of(overallTransitionState)
82
+ .pipe(
83
+ // Store the Navigation object
84
+ tap(t => {
85
+ this.currentNavigation = {
86
+ id: t.id,
87
+ initialUrl: t.rawUrl,
88
+ extractedUrl: t.extractedUrl,
89
+ trigger: t.source,
90
+ extras: t.extras,
91
+ previousNavigation: !this.lastSuccessfulNavigation ? null : {
92
+ ...this.lastSuccessfulNavigation,
93
+ previousNavigation: null,
94
+ },
95
+ };
96
+ }), switchMap(t => {
97
+ const browserUrlTree = router.browserUrlTree.toString();
98
+ const urlTransition = !router.navigated ||
99
+ t.extractedUrl.toString() !== browserUrlTree ||
100
+ // Navigations which succeed or ones which fail and are cleaned up
101
+ // correctly should result in `browserUrlTree` and `currentUrlTree`
102
+ // matching. If this is not the case, assume something went wrong and
103
+ // try processing the URL again.
104
+ browserUrlTree !== router.currentUrlTree.toString();
105
+ const processCurrentUrl = (router.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
106
+ router.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
107
+ if (processCurrentUrl) {
108
+ // If the source of the navigation is from a browser event, the URL is
109
+ // already updated. We already need to sync the internal state.
110
+ if (isBrowserTriggeredNavigation(t.source)) {
111
+ router.browserUrlTree = t.extractedUrl;
112
+ }
113
+ return of(t).pipe(
114
+ // Fire NavigationStart event
115
+ switchMap(t => {
116
+ const transition = this.transitions?.getValue();
117
+ this.events.next(new NavigationStart(t.id, this.urlSerializer.serialize(t.extractedUrl), t.source, t.restoredState));
118
+ if (transition !== this.transitions?.getValue()) {
119
+ return EMPTY;
120
+ }
121
+ // This delay is required to match old behavior that forced
122
+ // navigation to always be async
123
+ return Promise.resolve(t);
124
+ }),
125
+ // ApplyRedirects
126
+ applyRedirects(this.environmentInjector, this.configLoader, this.urlSerializer, router.config),
127
+ // Update the currentNavigation
128
+ // `urlAfterRedirects` is guaranteed to be set after this point
129
+ tap(t => {
130
+ this.currentNavigation = {
131
+ ...this.currentNavigation,
132
+ finalUrl: t.urlAfterRedirects
133
+ };
134
+ overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
135
+ }),
136
+ // Recognize
137
+ recognize(this.environmentInjector, router.rootComponentType, router.config, this.urlSerializer, router.paramsInheritanceStrategy),
138
+ // Update URL if in `eager` update mode
139
+ tap(t => {
140
+ overallTransitionState.targetSnapshot = t.targetSnapshot;
141
+ if (router.urlUpdateStrategy === 'eager') {
142
+ if (!t.extras.skipLocationChange) {
143
+ const rawUrl = router.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
144
+ router.setBrowserUrl(rawUrl, t);
145
+ }
146
+ router.browserUrlTree = t.urlAfterRedirects;
147
+ }
148
+ // Fire RoutesRecognized
149
+ const routesRecognized = new RoutesRecognized(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
150
+ this.events.next(routesRecognized);
151
+ }));
152
+ }
153
+ else {
154
+ const processPreviousUrl = urlTransition && router.rawUrlTree &&
155
+ router.urlHandlingStrategy.shouldProcessUrl(router.rawUrlTree);
156
+ /* When the current URL shouldn't be processed, but the previous one
157
+ * was, we handle this "error condition" by navigating to the
158
+ * previously successful URL, but leaving the URL intact.*/
159
+ if (processPreviousUrl) {
160
+ const { id, extractedUrl, source, restoredState, extras } = t;
161
+ const navStart = new NavigationStart(id, this.urlSerializer.serialize(extractedUrl), source, restoredState);
162
+ this.events.next(navStart);
163
+ const targetSnapshot = createEmptyState(extractedUrl, router.rootComponentType)
164
+ .snapshot;
165
+ overallTransitionState = {
166
+ ...t,
167
+ targetSnapshot,
168
+ urlAfterRedirects: extractedUrl,
169
+ extras: { ...extras, skipLocationChange: false, replaceUrl: false },
170
+ };
171
+ return of(overallTransitionState);
172
+ }
173
+ else {
174
+ /* When neither the current or previous URL can be processed, do
175
+ * nothing other than update router's internal reference to the
176
+ * current "settled" URL. This way the next navigation will be coming
177
+ * from the current URL in the browser.
178
+ */
179
+ router.rawUrlTree = t.rawUrl;
180
+ t.resolve(null);
181
+ return EMPTY;
182
+ }
183
+ }
184
+ }),
185
+ // --- GUARDS ---
186
+ tap(t => {
187
+ const guardsStart = new GuardsCheckStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
188
+ this.events.next(guardsStart);
189
+ }), map(t => {
190
+ overallTransitionState = {
191
+ ...t,
192
+ guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts)
193
+ };
194
+ return overallTransitionState;
195
+ }), checkGuards(this.environmentInjector, (evt) => this.events.next(evt)), tap(t => {
196
+ overallTransitionState.guardsResult = t.guardsResult;
197
+ if (isUrlTree(t.guardsResult)) {
198
+ throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
199
+ }
200
+ const guardsEnd = new GuardsCheckEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
201
+ this.events.next(guardsEnd);
202
+ }), filter(t => {
203
+ if (!t.guardsResult) {
204
+ router.restoreHistory(t);
205
+ this.cancelNavigationTransition(t, '', 3 /* NavigationCancellationCode.GuardRejected */, router);
206
+ return false;
207
+ }
208
+ return true;
209
+ }),
210
+ // --- RESOLVE ---
211
+ switchTap(t => {
212
+ if (t.guards.canActivateChecks.length) {
213
+ return of(t).pipe(tap(t => {
214
+ const resolveStart = new ResolveStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
215
+ this.events.next(resolveStart);
216
+ }), switchMap(t => {
217
+ let dataResolved = false;
218
+ return of(t).pipe(resolveData(router.paramsInheritanceStrategy, this.environmentInjector), tap({
219
+ next: () => dataResolved = true,
220
+ complete: () => {
221
+ if (!dataResolved) {
222
+ router.restoreHistory(t);
223
+ this.cancelNavigationTransition(t, NG_DEV_MODE ?
224
+ `At least one route resolver didn't emit any value.` :
225
+ '', 2 /* NavigationCancellationCode.NoDataFromResolver */, router);
226
+ }
227
+ }
228
+ }));
229
+ }), tap(t => {
230
+ const resolveEnd = new ResolveEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
231
+ this.events.next(resolveEnd);
232
+ }));
233
+ }
234
+ return undefined;
235
+ }),
236
+ // --- LOAD COMPONENTS ---
237
+ switchTap((t) => {
238
+ const loadComponents = (route) => {
239
+ const loaders = [];
240
+ if (route.routeConfig?.loadComponent &&
241
+ !route.routeConfig._loadedComponent) {
242
+ loaders.push(this.configLoader.loadComponent(route.routeConfig)
243
+ .pipe(tap(loadedComponent => {
244
+ route.component = loadedComponent;
245
+ }), map(() => void 0)));
246
+ }
247
+ for (const child of route.children) {
248
+ loaders.push(...loadComponents(child));
249
+ }
250
+ return loaders;
251
+ };
252
+ return combineLatest(loadComponents(t.targetSnapshot.root))
253
+ .pipe(defaultIfEmpty(), take(1));
254
+ }), switchTap(() => router.afterPreactivation()), map((t) => {
255
+ const targetRouterState = createRouterState(router.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
256
+ overallTransitionState = { ...t, targetRouterState };
257
+ return (overallTransitionState);
258
+ }),
259
+ /* Once here, we are about to activate synchronously. The assumption is
260
+ this will succeed, and user code may read from the Router service.
261
+ Therefore before activation, we need to update router properties storing
262
+ the current URL and the RouterState, as well as updated the browser URL.
263
+ All this should happen *before* activating. */
264
+ tap((t) => {
265
+ router.currentUrlTree = t.urlAfterRedirects;
266
+ router.rawUrlTree =
267
+ router.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
268
+ router.routerState =
269
+ t.targetRouterState;
270
+ if (router.urlUpdateStrategy === 'deferred') {
271
+ if (!t.extras.skipLocationChange) {
272
+ router.setBrowserUrl(router.rawUrlTree, t);
273
+ }
274
+ router.browserUrlTree = t.urlAfterRedirects;
275
+ }
276
+ }), activateRoutes(this.rootContexts, router.routeReuseStrategy, (evt) => this.events.next(evt)), tap({
277
+ next: (t) => {
278
+ completed = true;
279
+ this.lastSuccessfulNavigation = this.currentNavigation;
280
+ router.navigated = true;
281
+ this.events.next(new NavigationEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(router.currentUrlTree)));
282
+ router.titleStrategy?.updateTitle(t.targetRouterState.snapshot);
283
+ t.resolve(true);
284
+ },
285
+ complete: () => {
286
+ completed = true;
287
+ }
288
+ }), finalize(() => {
289
+ /* When the navigation stream finishes either through error or success,
290
+ * we set the `completed` or `errored` flag. However, there are some
291
+ * situations where we could get here without either of those being set.
292
+ * For instance, a redirect during NavigationStart. Therefore, this is a
293
+ * catch-all to make sure the NavigationCancel event is fired when a
294
+ * navigation gets cancelled but not caught by other means. */
295
+ if (!completed && !errored) {
296
+ const cancelationReason = NG_DEV_MODE ?
297
+ `Navigation ID ${overallTransitionState
298
+ .id} is not equal to the current navigation id ${this.navigationId}` :
299
+ '';
300
+ this.cancelNavigationTransition(overallTransitionState, cancelationReason, 1 /* NavigationCancellationCode.SupersededByNewNavigation */, router);
301
+ }
302
+ // Only clear current navigation if it is still set to the one that
303
+ // finalized.
304
+ if (this.currentNavigation?.id === overallTransitionState.id) {
305
+ this.currentNavigation = null;
306
+ }
307
+ }), catchError((e) => {
308
+ errored = true;
309
+ /* This error type is issued during Redirect, and is handled as a
310
+ * cancellation rather than an error. */
311
+ if (isNavigationCancelingError(e)) {
312
+ if (!isRedirectingNavigationCancelingError(e)) {
313
+ // Set property only if we're not redirecting. If we landed on a page
314
+ // and redirect to `/` route, the new navigation is going to see the
315
+ // `/` isn't a change from the default currentUrlTree and won't
316
+ // navigate. This is only applicable with initial navigation, so
317
+ // setting `navigated` only when not redirecting resolves this
318
+ // scenario.
319
+ router.navigated = true;
320
+ router.restoreHistory(overallTransitionState, true);
321
+ }
322
+ const navCancel = new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e.message, e.cancellationCode);
323
+ this.events.next(navCancel);
324
+ // When redirecting, we need to delay resolving the navigation
325
+ // promise and push it to the redirect navigation
326
+ if (!isRedirectingNavigationCancelingError(e)) {
327
+ overallTransitionState.resolve(false);
328
+ }
329
+ else {
330
+ const mergedTree = router.urlHandlingStrategy.merge(e.url, router.rawUrlTree);
331
+ const extras = {
332
+ skipLocationChange: overallTransitionState.extras.skipLocationChange,
333
+ // The URL is already updated at this point if we have 'eager' URL
334
+ // updates or if the navigation was triggered by the browser (back
335
+ // button, URL bar, etc). We want to replace that item in history
336
+ // if the navigation is rejected.
337
+ replaceUrl: router.urlUpdateStrategy === 'eager' ||
338
+ isBrowserTriggeredNavigation(overallTransitionState.source)
339
+ };
340
+ router.scheduleNavigation(mergedTree, 'imperative', null, extras, {
341
+ resolve: overallTransitionState.resolve,
342
+ reject: overallTransitionState.reject,
343
+ promise: overallTransitionState.promise
344
+ });
345
+ }
346
+ /* All other errors should reset to the router's internal URL reference
347
+ * to the pre-error state. */
348
+ }
349
+ else {
350
+ router.restoreHistory(overallTransitionState, true);
351
+ const navError = new NavigationError(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined);
352
+ this.events.next(navError);
353
+ try {
354
+ overallTransitionState.resolve(router.errorHandler(e));
355
+ }
356
+ catch (ee) {
357
+ overallTransitionState.reject(ee);
358
+ }
359
+ }
360
+ return EMPTY;
361
+ }));
362
+ // TODO(jasonaden): remove cast once g3 is on updated TypeScript
363
+ }));
364
+ }
365
+ cancelNavigationTransition(t, reason, code, router) {
366
+ const navCancel = new NavigationCancel(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, code);
367
+ this.events.next(navCancel);
368
+ t.resolve(false);
369
+ }
370
+ }
371
+ NavigationTransitions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
372
+ NavigationTransitions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NavigationTransitions, providedIn: 'root' });
373
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.2", ngImport: i0, type: NavigationTransitions, decorators: [{
374
+ type: Injectable,
375
+ args: [{ providedIn: 'root' }]
376
+ }], ctorParameters: function () { return []; } });
377
+ export function isBrowserTriggeredNavigation(source) {
378
+ return source !== 'imperative';
379
+ }
380
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2aWdhdGlvbl90cmFuc2l0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9uYXZpZ2F0aW9uX3RyYW5zaXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQU8sTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDcEYsT0FBTyxFQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUV2RyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQVEsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUE4QixhQUFhLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBcUIsVUFBVSxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxvQkFBb0IsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUV6USxPQUFPLEVBQUMsMEJBQTBCLEVBQUUscUNBQXFDLEVBQUUsMEJBQTBCLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUMzSSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFDM0QsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDaEQsT0FBTyxFQUFDLFdBQVcsRUFBQyxN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QUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtFbnZpcm9ubWVudEluamVjdG9yLCBpbmplY3QsIEluamVjdGFibGUsIFR5cGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIEVNUFRZLCBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2NhdGNoRXJyb3IsIGRlZmF1bHRJZkVtcHR5LCBmaWx0ZXIsIGZpbmFsaXplLCBtYXAsIHN3aXRjaE1hcCwgdGFrZSwgdGFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7Y3JlYXRlUm91dGVyU3RhdGV9IGZyb20gJy4vY3JlYXRlX3JvdXRlcl9zdGF0ZSc7XG5pbXBvcnQge0V2ZW50LCBHdWFyZHNDaGVja0VuZCwgR3VhcmRzQ2hlY2tTdGFydCwgTmF2aWdhdGlvbkNhbmNlbCwgTmF2aWdhdGlvbkNhbmNlbGxhdGlvbkNvZGUsIE5hdmlnYXRpb25FbmQsIE5hdmlnYXRpb25FcnJvciwgTmF2aWdhdGlvblN0YXJ0LCBOYXZpZ2F0aW9uVHJpZ2dlciwgUmVzb2x2ZUVuZCwgUmVzb2x2ZVN0YXJ0LCBSb3V0ZUNvbmZpZ0xvYWRFbmQsIFJvdXRlQ29uZmlnTG9hZFN0YXJ0LCBSb3V0ZXNSZWNvZ25pemVkfSBmcm9tICcuL2V2ZW50cyc7XG5pbXBvcnQge05hdmlnYXRpb25CZWhhdmlvck9wdGlvbnMsIFF1ZXJ5UGFyYW1zSGFuZGxpbmcsIFJvdXRlLCBSb3V0ZXN9IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7aXNOYXZpZ2F0aW9uQ2FuY2VsaW5nRXJyb3IsIGlzUmVkaXJlY3RpbmdOYXZpZ2F0aW9uQ2FuY2VsaW5nRXJyb3IsIHJlZGlyZWN0aW5nTmF2aWdhdGlvbkVycm9yfSBmcm9tICcuL25hdmlnYXRpb25fY2FuY2VsaW5nX2Vycm9yJztcbmltcG9ydCB7YWN0aXZhdGVSb3V0ZXN9IGZyb20gJy4vb3BlcmF0b3JzL2FjdGl2YXRlX3JvdXRlcyc7XG5pbXBvcnQge2FwcGx5UmVkaXJlY3RzfSBmcm9tICcuL29wZXJhdG9ycy9hcHBseV9yZWRpcmVjdHMnO1xuaW1wb3J0IHtjaGVja0d1YXJkc30gZnJvbSAnLi9vcGVyYXRvcnMvY2hlY2tfZ3VhcmRzJztcbmltcG9ydCB7cmVjb2duaXplfSBmcm9tICcuL29wZXJhdG9ycy9yZWNvZ25pemUnO1xuaW1wb3J0IHtyZXNvbHZlRGF0YX0gZnJvbSAnLi9vcGVyYXRvcnMvcmVzb2x2ZV9kYXRhJztcbmltcG9ydCB7c3dpdGNoVGFwfSBmcm9tICcuL29wZXJhdG9ycy9zd2l0Y2hfdGFwJztcbmltcG9ydCB7VGl0bGVTdHJhdGVneX0gZnJvbSAnLi9wYWdlX3RpdGxlX3N0cmF0ZWd5JztcbmltcG9ydCB7Um91dGVSZXVzZVN0cmF0ZWd5fSBmcm9tICcuL3JvdXRlX3JldXNlX3N0cmF0ZWd5JztcbmltcG9ydCB7RXJyb3JIYW5kbGVyfSBmcm9tICcuL3JvdXRlcl9jb25maWcnO1xuaW1wb3J0IHtSb3V0ZXJDb25maWdMb2FkZXJ9IGZyb20gJy4vcm91dGVyX2NvbmZpZ19sb2FkZXInO1xuaW1wb3J0IHtDaGlsZHJlbk91dGxldENvbnRleHRzfSBmcm9tICcuL3JvdXRlcl9vdXRsZXRfY29udGV4dCc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlLCBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBjcmVhdGVFbXB0eVN0YXRlLCBSb3V0ZXJTdGF0ZSwgUm91dGVyU3RhdGVTbmFwc2hvdH0gZnJvbSAnLi9yb3V0ZXJfc3RhdGUnO1xuaW1wb3J0IHtQYXJhbXN9IGZyb20gJy4vc2hhcmVkJztcbmltcG9ydCB7VXJsSGFuZGxpbmdTdHJhdGVneX0gZnJvbSAnLi91cmxfaGFuZGxpbmdfc3RyYXRlZ3knO1xuaW1wb3J0IHtpc1VybFRyZWUsIFVybFNlcmlhbGl6ZXIsIFVybFRyZWV9IGZyb20gJy4vdXJsX3RyZWUnO1xuaW1wb3J0IHtDaGVja3MsIGdldEFsbFJvdXRlR3VhcmRzfSBmcm9tICcuL3V0aWxzL3ByZWFjdGl2YXRpb24nO1xuXG5cbmNvbnN0IE5HX0RFVl9NT0RFID0gdHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgISFuZ0Rldk1vZGU7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogT3B0aW9ucyB0aGF0IG1vZGlmeSB0aGUgYFJvdXRlcmAgVVJMLlxuICogU3VwcGx5IGFuIG9iamVjdCBjb250YWluaW5nIGFueSBvZiB0aGVzZSBwcm9wZXJ0aWVzIHRvIGEgYFJvdXRlcmAgbmF2aWdhdGlvbiBmdW5jdGlvbiB0b1xuICogY29udHJvbCBob3cgdGhlIHRhcmdldCBVUkwgc2hvdWxkIGJlIGNvbnN0cnVjdGVkLlxuICpcbiAqIEBzZWUgW1JvdXRlci5uYXZpZ2F0ZSgpIG1ldGhvZF0oYXBpL3JvdXRlci9Sb3V0ZXIjbmF2aWdhdGUpXG4gKiBAc2VlIFtSb3V0ZXIuY3JlYXRlVXJsVHJlZSgpIG1ldGhvZF0oYXBpL3JvdXRlci9Sb3V0ZXIjY3JlYXRldXJsdHJlZSlcbiAqIEBzZWUgW1JvdXRpbmcgYW5kIE5hdmlnYXRpb24gZ3VpZGVdKGd1aWRlL3JvdXRlcilcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVXJsQ3JlYXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwZWNpZmllcyBhIHJvb3QgVVJJIHRvIHVzZSBmb3IgcmVsYXRpdmUgbmF2aWdhdGlvbi5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIGNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgcm91dGUgY29uZmlndXJhdGlvbiB3aGVyZSB0aGUgcGFyZW50IHJvdXRlXG4gICAqIGhhcyB0d28gY2hpbGRyZW4uXG4gICAqXG4gICAqIGBgYFxuICAgKiBbe1xuICAgKiAgIHBhdGg6ICdwYXJlbnQnLFxuICAgKiAgIGNvbXBvbmVudDogUGFyZW50Q29tcG9uZW50LFxuICAgKiAgIGNoaWxkcmVuOiBbe1xuICAgKiAgICAgcGF0aDogJ2xpc3QnLFxuICAgKiAgICAgY29tcG9uZW50OiBMaXN0Q29tcG9uZW50XG4gICAqICAgfSx7XG4gICAqICAgICBwYXRoOiAnY2hpbGQnLFxuICAgKiAgICAgY29tcG9uZW50OiBDaGlsZENvbXBvbmVudFxuICAgKiAgIH1dXG4gICAqIH1dXG4gICAqIGBgYFxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGBnbygpYCBmdW5jdGlvbiBuYXZpZ2F0ZXMgdG8gdGhlIGBsaXN0YCByb3V0ZSBieVxuICAgKiBpbnRlcnByZXRpbmcgdGhlIGRlc3RpbmF0aW9uIFVSSSBhcyByZWxhdGl2ZSB0byB0aGUgYWN0aXZhdGVkIGBjaGlsZGAgIHJvdXRlXG4gICAqXG4gICAqIGBgYFxuICAgKiAgQENvbXBvbmVudCh7Li4ufSlcbiAgICogIGNsYXNzIENoaWxkQ29tcG9uZW50IHtcbiAgICogICAgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZXI6IFJvdXRlciwgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUpIHt9XG4gICAqXG4gICAqICAgIGdvKCkge1xuICAgKiAgICAgIHJvdXRlci5uYXZpZ2F0ZShbJy4uL2xpc3QnXSwgeyByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlIH0pO1xuICAgKiAgICB9XG4gICAqICB9XG4gICAqIGBgYFxuICAgKlxuICAgKiBBIHZhbHVlIG9mIGBudWxsYCBvciBgdW5kZWZpbmVkYCBpbmRpY2F0ZXMgdGhhdCB0aGUgbmF2aWdhdGlvbiBjb21tYW5kcyBzaG91bGQgYmUgYXBwbGllZFxuICAgKiByZWxhdGl2ZSB0byB0aGUgcm9vdC5cbiAgICovXG4gIHJlbGF0aXZlVG8/OiBBY3RpdmF0ZWRSb3V0ZXxudWxsO1xuXG4gIC8qKlxuICAgKiBTZXRzIHF1ZXJ5IHBhcmFtZXRlcnMgdG8gdGhlIFVSTC5cbiAgICpcbiAgICogYGBgXG4gICAqIC8vIE5hdmlnYXRlIHRvIC9yZXN1bHRzP3BhZ2U9MVxuICAgKiByb3V0ZXIubmF2aWdhdGUoWycvcmVzdWx0cyddLCB7IHF1ZXJ5UGFyYW1zOiB7IHBhZ2U6IDEgfSB9KTtcbiAgICogYGBgXG4gICAqL1xuICBxdWVyeVBhcmFtcz86IFBhcmFtc3xudWxsO1xuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBoYXNoIGZyYWdtZW50IGZvciB0aGUgVVJMLlxuICAgKlxuICAgKiBgYGBcbiAgICogLy8gTmF2aWdhdGUgdG8gL3Jlc3VsdHMjdG9wXG4gICAqIHJvdXRlci5uYXZpZ2F0ZShbJy9yZXN1bHRzJ10sIHsgZnJhZ21lbnQ6ICd0b3AnIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGZyYWdtZW50Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBIb3cgdG8gaGFuZGxlIHF1ZXJ5IHBhcmFtZXRlcnMgaW4gdGhlIHJvdXRlciBsaW5rIGZvciB0aGUgbmV4dCBuYXZpZ2F0aW9uLlxuICAgKiBPbmUgb2Y6XG4gICAqICogYHByZXNlcnZlYCA6IFByZXNlcnZlIGN1cnJlbnQgcGFyYW1ldGVycy5cbiAgICogKiBgbWVyZ2VgIDogTWVyZ2UgbmV3IHdpdGggY3VycmVudCBwYXJhbWV0ZXJzLlxuICAgKlxuICAgKiBUaGUgXCJwcmVzZXJ2ZVwiIG9wdGlvbiBkaXNjYXJkcyBhbnkgbmV3IHF1ZXJ5IHBhcmFtczpcbiAgICogYGBgXG4gICAqIC8vIGZyb20gL3ZpZXcxP3BhZ2U9MSB0by92aWV3Mj9wYWdlPTFcbiAgICogcm91dGVyLm5hdmlnYXRlKFsnL3ZpZXcyJ10sIHsgcXVlcnlQYXJhbXM6IHsgcGFnZTogMiB9LCAgcXVlcnlQYXJhbXNIYW5kbGluZzogXCJwcmVzZXJ2ZVwiXG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICogVGhlIFwibWVyZ2VcIiBvcHRpb24gYXBwZW5kcyBuZXcgcXVlcnkgcGFyYW1zIHRvIHRoZSBwYXJhbXMgZnJvbSB0aGUgY3VycmVudCBVUkw6XG4gICAqIGBgYFxuICAgKiAvLyBmcm9tIC92aWV3MT9wYWdlPTEgdG8vdmlldzI/cGFnZT0xJm90aGVyS2V5PTJcbiAgICogcm91dGVyLm5hdmlnYXRlKFsnL3ZpZXcyJ10sIHsgcXVlcnlQYXJhbXM6IHsgb3RoZXJLZXk6IDIgfSwgIHF1ZXJ5UGFyYW1zSGFuZGxpbmc6IFwibWVyZ2VcIlxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqIEluIGNhc2Ugb2YgYSBrZXkgY29sbGlzaW9uIGJldHdlZW4gY3VycmVudCBwYXJhbWV0ZXJzIGFuZCB0aG9zZSBpbiB0aGUgYHF1ZXJ5UGFyYW1zYCBvYmplY3QsXG4gICAqIHRoZSBuZXcgdmFsdWUgaXMgdXNlZC5cbiAgICpcbiAgICovXG4gIHF1ZXJ5UGFyYW1zSGFuZGxpbmc/OiBRdWVyeVBhcmFtc0hhbmRsaW5nfG51bGw7XG5cbiAgLyoqXG4gICAqIFdoZW4gdHJ1ZSwgcHJlc2VydmVzIHRoZSBVUkwgZnJhZ21lbnQgZm9yIHRoZSBuZXh0IG5hdmlnYXRpb25cbiAgICpcbiAgICogYGBgXG4gICAqIC8vIFByZXNlcnZlIGZyYWdtZW50IGZyb20gL3Jlc3VsdHMjdG9wIHRvIC92aWV3I3RvcFxuICAgKiByb3V0ZXIubmF2aWdhdGUoWycvdmlldyddLCB7IHByZXNlcnZlRnJhZ21lbnQ6IHRydWUgfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgcHJlc2VydmVGcmFnbWVudD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogT3B0aW9ucyB0aGF0IG1vZGlmeSB0aGUgYFJvdXRlcmAgbmF2aWdhdGlvbiBzdHJhdGVneS5cbiAqIFN1cHBseSBhbiBvYmplY3QgY29udGFpbmluZyBhbnkgb2YgdGhlc2UgcHJvcGVydGllcyB0byBhIGBSb3V0ZXJgIG5hdmlnYXRpb24gZnVuY3Rpb24gdG9cbiAqIGNvbnRyb2wgaG93IHRoZSB0YXJnZXQgVVJMIHNob3VsZCBiZSBjb25zdHJ1Y3RlZCBvciBpbnRlcnByZXRlZC5cbiAqXG4gKiBAc2VlIFtSb3V0ZXIubmF2aWdhdGUoKSBtZXRob2RdKGFwaS9yb3V0ZXIvUm91dGVyI25hdmlnYXRlKVxuICogQHNlZSBbUm91dGVyLm5hdmlnYXRlQnlVcmwoKSBtZXRob2RdKGFwaS9yb3V0ZXIvUm91dGVyI25hdmlnYXRlYnl1cmwpXG4gKiBAc2VlIFtSb3V0ZXIuY3JlYXRlVXJsVHJlZSgpIG1ldGhvZF0oYXBpL3JvdXRlci9Sb3V0ZXIjY3JlYXRldXJsdHJlZSlcbiAqIEBzZWUgW1JvdXRpbmcgYW5kIE5hdmlnYXRpb24gZ3VpZGVdKGd1aWRlL3JvdXRlcilcbiAqIEBzZWUgVXJsQ3JlYXRpb25PcHRpb25zXG4gKiBAc2VlIE5hdmlnYXRpb25CZWhhdmlvck9wdGlvbnNcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGlvbkV4dHJhcyBleHRlbmRzIFVybENyZWF0aW9uT3B0aW9ucywgTmF2aWdhdGlvbkJlaGF2aW9yT3B0aW9ucyB7fVxuXG5leHBvcnQgdHlwZSBSZXN0b3JlZFN0YXRlID0ge1xuICBbazogc3RyaW5nXTogYW55LFxuICAvLyBUT0RPKCMyNzYwNyk6IFJlbW92ZSBgbmF2aWdhdGlvbklkYCBhbmQgYMm1cm91dGVyUGFnZUlkYCBhbmQgbW92ZSB0byBgbmdgIG9yIGDJtWAgbmFtZXNwYWNlLlxuICBuYXZpZ2F0aW9uSWQ6IG51bWJlcixcbiAgLy8gVGhlIGDJtWAgcHJlZml4IGlzIHRoZXJlIHRvIHJlZHVjZSB0aGUgY2hhbmNlIG9mIGNvbGxpZGluZyB3aXRoIGFueSBleGlzdGluZyB1c2VyIHByb3BlcnRpZXMgb25cbiAgLy8gdGhlIGhpc3Rvcnkgc3RhdGUuXG4gIMm1cm91dGVyUGFnZUlkPzogbnVtYmVyLFxufTtcblxuLyoqXG4gKiBJbmZvcm1hdGlvbiBhYm91dCBhIG5hdmlnYXRpb24gb3BlcmF0aW9uLlxuICogUmV0cmlldmUgdGhlIG1vc3QgcmVjZW50IG5hdmlnYXRpb24gb2JqZWN0IHdpdGggdGhlXG4gKiBbUm91dGVyLmdldEN1cnJlbnROYXZpZ2F0aW9uKCkgbWV0aG9kXShhcGkvcm91dGVyL1JvdXRlciNnZXRjdXJyZW50bmF2aWdhdGlvbikgLlxuICpcbiAqICogKmlkKiA6IFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgY3VycmVudCBuYXZpZ2F0aW9uLlxuICogKiAqaW5pdGlhbFVybCogOiBUaGUgdGFyZ2V0IFVSTCBwYXNzZWQgaW50byB0aGUgYFJvdXRlciNuYXZpZ2F0ZUJ5VXJsKClgIGNhbGwgYmVmb3JlIG5hdmlnYXRpb24uXG4gKiBUaGlzIGlzIHRoZSB2YWx1ZSBiZWZvcmUgdGhlIHJvdXRlciBoYXMgcGFyc2VkIG9yIGFwcGxpZWQgcmVkaXJlY3RzIHRvIGl0LlxuICogKiAqZXh0cmFjdGVkVXJsKiA6IFRoZSBpbml0aWFsIHRhcmdldCBVUkwgYWZ0ZXIgYmVpbmcgcGFyc2VkIHdpdGggYFVybFNlcmlhbGl6ZXIuZXh0cmFjdCgpYC5cbiAqICogKmZpbmFsVXJsKiA6IFRoZSBleHRyYWN0ZWQgVVJMIGFmdGVyIHJlZGlyZWN0cyBoYXZlIGJlZW4gYXBwbGllZC5cbiAqIFRoaXMgVVJMIG1heSBub3QgYmUgYXZhaWxhYmxlIGltbWVkaWF0ZWx5LCB0aGVyZWZvcmUgdGhpcyBwcm9wZXJ0eSBjYW4gYmUgYHVuZGVmaW5lZGAuXG4gKiBJdCBpcyBndWFyYW50ZWVkIHRvIGJlIHNldCBhZnRlciB0aGUgYFJvdXRlc1JlY29nbml6ZWRgIGV2ZW50IGZpcmVzLlxuICogKiAqdHJpZ2dlciogOiBJZGVudGlmaWVzIGhvdyB0aGlzIG5hdmlnYXRpb24gd2FzIHRyaWdnZXJlZC5cbiAqIC0tICdpbXBlcmF0aXZlJy0tVHJpZ2dlcmVkIGJ5IGByb3V0ZXIubmF2aWdhdGVCeVVybGAgb3IgYHJvdXRlci5uYXZpZ2F0ZWAuXG4gKiAtLSAncG9wc3RhdGUnLS1UcmlnZ2VyZWQgYnkgYSBwb3BzdGF0ZSBldmVudC5cbiAqIC0tICdoYXNoY2hhbmdlJy0tVHJpZ2dlcmVkIGJ5IGEgaGFzaGNoYW5nZSBldmVudC5cbiAqICogKmV4dHJhcyogOiBBIGBOYXZpZ2F0aW9uRXh0cmFzYCBvcHRpb25zIG9iamVjdCB0aGF0IGNvbnRyb2xsZWQgdGhlIHN0cmF0ZWd5IHVzZWQgZm9yIHRoaXNcbiAqIG5hdmlnYXRpb24uXG4gKiAqICpwcmV2aW91c05hdmlnYXRpb24qIDogVGhlIHByZXZpb3VzbHkgc3VjY2Vzc2Z1bCBgTmF2aWdhdGlvbmAgb2JqZWN0LiBPbmx5IG9uZSBwcmV2aW91c1xuICogbmF2aWdhdGlvbiBpcyBhdmFpbGFibGUsIHRoZXJlZm9yZSB0aGlzIHByZXZpb3VzIGBOYXZpZ2F0aW9uYCBvYmplY3QgaGFzIGEgYG51bGxgIHZhbHVlIGZvciBpdHNcbiAqIG93biBgcHJldmlvdXNOYXZpZ2F0aW9uYC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGN1cnJlbnQgbmF2aWdhdGlvbi5cbiAgICovXG4gIGlkOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgdGFyZ2V0IFVSTCBwYXNzZWQgaW50byB0aGUgYFJvdXRlciNuYXZpZ2F0ZUJ5VXJsKClgIGNhbGwgYmVmb3JlIG5hdmlnYXRpb24uIFRoaXMgaXNcbiAgICogdGhlIHZhbHVlIGJlZm9yZSB0aGUgcm91dGVyIGhhcyBwYXJzZWQgb3IgYXBwbGllZCByZWRpcmVjdHMgdG8gaXQuXG4gICAqL1xuICBpbml0aWFsVXJsOiBVcmxUcmVlO1xuICAvKipcbiAgICogVGhlIGluaXRpYWwgdGFyZ2V0IFVSTCBhZnRlciBiZWluZyBwYXJzZWQgd2l0aCBgVXJsSGFuZGxpbmdTdHJhdGVneS5leHRyYWN0KClgLlxuICAgKi9cbiAgZXh0cmFjdGVkVXJsOiBVcmxUcmVlO1xuICAvKipcbiAgICogVGhlIGV4dHJhY3RlZCBVUkwgYWZ0ZXIgcmVkaXJlY3RzIGhhdmUgYmVlbiBhcHBsaWVkLlxuICAgKiBUaGlzIFVSTCBtYXkgbm90IGJlIGF2YWlsYWJsZSBpbW1lZGlhdGVseSwgdGhlcmVmb3JlIHRoaXMgcHJvcGVydHkgY2FuIGJlIGB1bmRlZmluZWRgLlxuICAgKiBJdCBpcyBndWFyYW50ZWVkIHRvIGJlIHNldCBhZnRlciB0aGUgYFJvdXRlc1JlY29nbml6ZWRgIGV2ZW50IGZpcmVzLlxuICAgKi9cbiAgZmluYWxVcmw/OiBVcmxUcmVlO1xuICAvKipcbiAgICogSWRlbnRpZmllcyBob3cgdGhpcyBuYXZpZ2F0aW9uIHdhcyB0cmlnZ2VyZWQuXG4gICAqXG4gICAqICogJ2ltcGVyYXRpdmUnLS1UcmlnZ2VyZWQgYnkgYHJvdXRlci5uYXZpZ2F0ZUJ5VXJsYCBvciBgcm91dGVyLm5hdmlnYXRlYC5cbiAgICogKiAncG9wc3RhdGUnLS1UcmlnZ2VyZWQgYnkgYSBwb3BzdGF0ZSBldmVudC5cbiAgICogKiAnaGFzaGNoYW5nZSctLVRyaWdnZXJlZCBieSBhIGhhc2hjaGFuZ2UgZXZlbnQuXG4gICAqL1xuICB0cmlnZ2VyOiAnaW1wZXJhdGl2ZSd8J3BvcHN0YXRlJ3wnaGFzaGNoYW5nZSc7XG4gIC8qKlxuICAgKiBPcHRpb25zIHRoYXQgY29udHJvbGxlZCB0aGUgc3RyYXRlZ3kgdXNlZCBmb3IgdGhpcyBuYXZpZ2F0aW9uLlxuICAgKiBTZWUgYE5hdmlnYXRpb25FeHRyYXNgLlxuICAgKi9cbiAgZXh0cmFzOiBOYXZpZ2F0aW9uRXh0cmFzO1xuICAvKipcbiAgICogVGhlIHByZXZpb3VzbHkgc3VjY2Vzc2Z1bCBgTmF2aWdhdGlvbmAgb2JqZWN0LiBPbmx5IG9uZSBwcmV2aW91cyBuYXZpZ2F0aW9uXG4gICAqIGlzIGF2YWlsYWJsZSwgdGhlcmVmb3JlIHRoaXMgcHJldmlvdXMgYE5hdmlnYXRpb25gIG9iamVjdCBoYXMgYSBgbnVsbGAgdmFsdWVcbiAgICogZm9yIGl0cyBvd24gYHByZXZpb3VzTmF2aWdhdGlvbmAuXG4gICAqL1xuICBwcmV2aW91c05hdmlnYXRpb246IE5hdmlnYXRpb258bnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOYXZpZ2F0aW9uVHJhbnNpdGlvbiB7XG4gIGlkOiBudW1iZXI7XG4gIHRhcmdldFBhZ2VJZDogbnVtYmVyO1xuICBjdXJyZW50VXJsVHJlZTogVXJsVHJlZTtcbiAgZXh0cmFjdGVkVXJsOiBVcmxUcmVlO1xuICBjdXJyZW50UmF3VXJsOiBVcmxUcmVlO1xuICB1cmxBZnRlclJlZGlyZWN0cz86IFVybFRyZWU7XG4gIHJhd1VybDogVXJsVHJlZTtcbiAgZXh0cmFzOiBOYXZpZ2F0aW9uRXh0cmFzO1xuICByZXNvbHZlOiBhbnk7XG4gIHJlamVjdDogYW55O1xuICBwcm9taXNlOiBQcm9taXNlPGJvb2xlYW4+O1xuICBzb3VyY2U6IE5hdmlnYXRpb25UcmlnZ2VyO1xuICByZXN0b3JlZFN0YXRlOiBSZXN0b3JlZFN0YXRlfG51bGw7XG4gIGN1cnJlbnRTbmFwc2hvdDogUm91dGVyU3RhdGVTbmFwc2hvdDtcbiAgdGFyZ2V0U25hcHNob3Q6IFJvdXRlclN0YXRlU25hcHNob3R8bnVsbDtcbiAgY3VycmVudFJvdXRlclN0YXRlOiBSb3V0ZXJTdGF0ZTtcbiAgdGFyZ2V0Um91dGVyU3RhdGU6IFJvdXRlclN0YXRlfG51bGw7XG4gIGd1YXJkczogQ2hlY2tzO1xuICBndWFyZHNSZXN1bHQ6IGJvb2xlYW58VXJsVHJlZXxudWxsO1xufVxuXG4vKipcbiAqIFRoZSBpbnRlcmZhY2UgZnJvbSB0aGUgUm91dGVyIG5lZWRlZCBieSB0aGUgdHJhbnNpdGlvbnMuIFVzZWQgdG8gYXZvaWQgYSBjaXJjdWxhciBkZXBlbmRlbmN5IG9uXG4gKiBSb3V0ZXIuIFRoaXMgaW50ZXJmYWNlIHNob3VsZCBiZSB3aGl0dGxlZCBkb3duIHdpdGggZnV0dXJlIHJlZmFjdG9ycy4gRm9yIGV4YW1wbGUsIHdlIGRvIG5vdCBuZWVkXG4gKiB0byBnZXQgYFVybFNlcmlhbGl6ZXJgIGZyb20gdGhlIFJvdXRlci4gV2UgY2FuIGluc3RlYWQgaW5qZWN0IGl0IGluIGBOYXZpZ2F0aW9uVHJhbnNpdGlvbnNgXG4gKiBkaXJlY3RseS5cbiAqL1xuaW50ZXJmYWNlIEludGVybmFsUm91dGVySW50ZXJmYWNlIHtcbiAgYnJvd3NlclVybFRyZWU6IFVybFRyZWU7XG4gIGN1cnJlbnRVcmxUcmVlOiBVcmxUcmVlO1xuICByYXdVcmxUcmVlOiBVcmxUcmVlO1xuICByZWFkb25seSByb3V0ZXJTdGF0ZTogUm91dGVyU3RhdGU7XG4gIGVycm9ySGFuZGxlcjogRXJyb3JIYW5kbGVyO1xuICB0aXRsZVN0cmF0ZWd5PzogVGl0bGVTdHJhdGVneTtcbiAgbmF2aWdhdGVkOiBib29sZWFuO1xuICBhZnRlclByZWFjdGl2YXRpb246ICgpID0+IE9ic2VydmFibGU8dm9pZD47XG4gIHVybEhhbmRsaW5nU3RyYXRlZ3k6IFVybEhhbmRsaW5nU3RyYXRlZ3k7XG4gIHJvdXRlUmV1c2VTdHJhdGVneTogUm91dGVSZXVzZVN0cmF0ZWd5O1xuICBvblNhbWVVcmxOYXZpZ2F0aW9uOiAncmVsb2FkJ3wnaWdub3JlJztcbiAgcGFyYW1zSW5oZXJpdGFuY2VTdHJhdGVneTogJ2VtcHR5T25seSd8J2Fsd2F5cyc7XG4gIHVybFVwZGF0ZVN0cmF0ZWd5OiAnZGVmZXJyZWQnfCdlYWdlcic7XG4gIHNlcmlhbGl6ZVVybCh1cmw6IFVybFRyZWUpOiBzdHJpbmc7XG4gIGNvbmZpZzogUm91dGVzO1xuICByb290Q29tcG9uZW50VHlwZTogVHlwZTxhbnk+fG51bGw7XG4gIHNldEJyb3dzZXJVcmwodXJsOiBVcmxUcmVlLCB0OiBOYXZpZ2F0aW9uVHJhbnNpdGlvbik6IHZvaWQ7XG4gIHJlc3RvcmVIaXN0b3J5KHQ6IE5hdmlnYXRpb25UcmFuc2l0aW9uLCByZXN0b3JpbmdGcm9tQ2F1Z2h0RXJyb3I/OiBib29sZWFuKTogdm9pZDtcbiAgc2NoZWR1bGVOYXZpZ2F0aW9uKFxuICAgICAgcmF3VXJsOiBVcmxUcmVlLCBzb3VyY2U6IE5hdmlnYXRpb25UcmlnZ2VyLCByZXN0b3JlZFN0YXRlOiBSZXN0b3JlZFN0YXRlfG51bGwsXG4gICAgICBleHRyYXM6IE5hdmlnYXRpb25FeHRyYXMsXG4gICAgICBwcmlvclByb21pc2U/OiB7cmVzb2x2ZTogYW55LCByZWplY3Q6IGFueSwgcHJvbWlzZTogUHJvbWlzZTxib29sZWFuPn0pOiBQcm9taXNlPGJvb2xlYW4+O1xufVxuXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcbmV4cG9ydCBjbGFzcyBOYXZpZ2F0aW9uVHJhbnNpdGlvbnMge1xuICBjdXJyZW50TmF2aWdhdGlvbjogTmF2aWdhdGlvbnxudWxsID0gbnVsbDtcbiAgbGFzdFN1Y2Nlc3NmdWxOYXZpZ2F0aW9uOiBOYXZpZ2F0aW9ufG51bGwgPSBudWxsO1xuICByZWFkb25seSBldmVudHMgPSBuZXcgU3ViamVjdDxFdmVudD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWdMb2FkZXIgPSBpbmplY3QoUm91dGVyQ29uZmlnTG9hZGVyKTtcbiAgcHJpdmF0ZSByZWFkb25seSBlbnZpcm9ubWVudEluamVjdG9yID0gaW5qZWN0KEVudmlyb25tZW50SW5qZWN0b3IpO1xuICBwcml2YXRlIHJlYWRvbmx5IHVybFNlcmlhbGl6ZXIgPSBpbmplY3QoVXJsU2VyaWFsaXplcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vdENvbnRleHRzID0gaW5qZWN0KENoaWxkcmVuT3V0bGV0Q29udGV4dHMpO1xuICBuYXZpZ2F0aW9uSWQgPSAwO1xuICBnZXQgaGFzUmVxdWVzdGVkTmF2aWdhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5uYXZpZ2F0aW9uSWQgIT09IDA7XG4gIH1cbiAgcHJpdmF0ZSB0cmFuc2l0aW9ucz86IEJlaGF2aW9yU3ViamVjdDxOYXZpZ2F0aW9uVHJhbnNpdGlvbj47XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgY29uc3Qgb25Mb2FkU3RhcnQgPSAocjogUm91dGUpID0+IHRoaXMuZXZlbnRzLm5leHQobmV3IFJvdXRlQ29uZmlnTG9hZFN0YXJ0KHIpKTtcbiAgICBjb25zdCBvbkxvYWRFbmQgPSAocjogUm91dGUpID0+IHRoaXMuZXZlbnRzLm5leHQobmV3IFJvdXRlQ29uZmlnTG9hZEVuZChyKSk7XG4gICAgdGhpcy5jb25maWdMb2FkZXIub25Mb2FkRW5kTGlzdGVuZXIgPSBvbkxvYWRFbmQ7XG4gICAgdGhpcy5jb25maWdMb2FkZXIub25Mb2FkU3RhcnRMaXN0ZW5lciA9IG9uTG9hZFN0YXJ0O1xuICB9XG5cbiAgY29tcGxldGUoKSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucz8uY29tcGxldGUoKTtcbiAgfVxuXG4gIGhhbmRsZU5hdmlnYXRpb25SZXF1ZXN0KFxuICAgICAgcmVxdWVzdDogUGljazxcbiAgICAgICAgICBOYXZpZ2F0aW9uVHJhbnNpdGlvbixcbiAgICAgICAgICAndGFyZ2V0UGFnZUlkJ3wnc291cmNlJ3wncmVzdG9yZWRTdGF0ZSd8J2N1cnJlbnRVcmxUcmVlJ3wnY3VycmVudFJhd1VybCd8J3Jhd1VybCd8XG4gICAgICAgICAgJ2V4dHJhcyd8J3Jlc29sdmUnfCdyZWplY3QnfCdwcm9taXNlJ3wnY3VycmVudFNuYXBzaG90J3wnY3VycmVudFJvdXRlclN0YXRlJz4pIHtcbiAgICBjb25zdCBpZCA9ICsrdGhpcy5uYXZpZ2F0aW9uSWQ7XG4gICAgdGhpcy50cmFuc2l0aW9ucz8ubmV4dCh7Li4udGhpcy50cmFuc2l0aW9ucy52YWx1ZSwgLi4ucmVxdWVzdCwgaWR9KTtcbiAgfVxuXG4gIHNldHVwTmF2aWdhdGlvbnMocm91dGVyOiBJbnRlcm5hbFJvdXRlckludGVyZmFjZSk6IE9ic2VydmFibGU8TmF2aWdhdGlvblRyYW5zaXRpb24+IHtcbiAgICB0aGlzLnRyYW5zaXRpb25zID0gbmV3IEJlaGF2aW9yU3ViamVjdDxOYXZpZ2F0aW9uVHJhbnNpdGlvbj4oe1xuICAgICAgaWQ6IDAsXG4gICAgICB0YXJnZXRQYWdlSWQ6IDAsXG4gICAgICBjdXJyZW50VXJsVHJlZTogcm91dGVyLmN1cnJlbnRVcmxUcmVlLFxuICAgICAgY3VycmVudFJhd1VybDogcm91dGVyLmN1cnJlbnRVcmxUcmVlLFxuICAgICAgZXh0cmFjdGVkVXJsOiByb3V0ZXIudXJsSGFuZGxpbmdTdHJhdGVneS5leHRyYWN0KHJvdXRlci5jdXJyZW50VXJsVHJlZSksXG4gICAgICB1cmxBZnRlclJlZGlyZWN0czogcm91dGVyLnVybEhhbmRsaW5nU3RyYXRlZ3kuZXh0cmFjdChyb3V0ZXIuY3VycmVudFVybFRyZWUpLFxuICAgICAgcmF3VXJsOiByb3V0ZXIuY3VycmVudFVybFRyZWUsXG4gICAgICBleHRyYXM6IHt9LFxuICAgICAgcmVzb2x2ZTogbnVsbCxcbiAgICAgIHJlamVjdDogbnVsbCxcbiAgICAgIHByb21pc2U6IFByb21pc2UucmVzb2x2ZSh0cnVlKSxcbiAgICAgIHNvdXJjZTogJ2ltcGVyYXRpdmUnLFxuICAgICAgcmVzdG9yZWRTdGF0ZTogbnVsbCxcbiAgICAgIGN1cnJlbnRTbmFwc2hvdDogcm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LFxuICAgICAgdGFyZ2V0U25hcHNob3Q6IG51bGwsXG4gICAgICBjdXJyZW50Um91dGVyU3RhdGU6IHJvdXRlci5yb3V0ZXJTdGF0ZSxcbiAgICAgIHRhcmdldFJvdXRlclN0YXRlOiBudWxsLFxuICAgICAgZ3VhcmRzOiB7Y2FuQWN0aXZhdGVDaGVja3M6IFtdLCBjYW5EZWFjdGl2YXRlQ2hlY2tzOiBbXX0sXG4gICAgICBndWFyZHNSZXN1bHQ6IG51bGwsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvbnMucGlwZShcbiAgICAgICAgICAgICAgIGZpbHRlcih0ID0+IHQuaWQgIT09IDApLFxuXG4gICAgICAgICAgICAgICAvLyBFeHRyYWN0IFVSTFxuICAgICAgICAgICAgICAgbWFwKHQgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgKHsuLi50LCBleHRyYWN0ZWRVcmw6IHJvdXRlci51cmxIYW5kbGluZ1N0cmF0ZWd5LmV4dHJhY3QodC5yYXdVcmwpfSBhc1xuICAgICAgICAgICAgICAgICAgICAgICAgTmF2aWdhdGlvblRyYW5zaXRpb24pKSxcblxuICAgICAgICAgICAgICAgLy8gVXNpbmcgc3dpdGNoTWFwIHNvIHdlIGNhbmNlbCBleGVjdXRpbmcgbmF2aWdhdGlvbnMgd2hlbiBhIG5ldyBvbmUgY29tZXMgaW5cbiAgICAgICAgICAgICAgIHN3aXRjaE1hcChvdmVyYWxsVHJhbnNpdGlvblN0YXRlID0+IHtcbiAgICAgICAgICAgICAgICAgbGV0IGNvbXBsZXRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICBsZXQgZXJyb3JlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICByZXR1cm4gb2Yob3ZlcmFsbFRyYW5zaXRpb25TdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSBOYXZpZ2F0aW9uIG9iamVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgIHRhcCh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE5hdmlnYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiB0LmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsVXJsOiB0LnJhd1VybCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFjdGVkVXJsOiB0LmV4dHJhY3RlZFVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcjogdC5zb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhczogdC5leHRyYXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzTmF2aWdhdGlvbjogIXRoaXMubGFzdFN1Y2Nlc3NmdWxOYXZpZ2F0aW9uID8gbnVsbCA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi50aGlzLmxhc3RTdWNjZXNzZnVsTmF2aWdhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c05hdmlnYXRpb246IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJyb3dzZXJVcmxUcmVlID0gcm91dGVyLmJyb3dzZXJVcmxUcmVlLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cmxUcmFuc2l0aW9uID0gIXJvdXRlci5uYXZpZ2F0ZWQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmV4dHJhY3RlZFVybC50b1N0cmluZygpICE9PSBicm93c2VyVXJsVHJlZSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5hdmlnYXRpb25zIHdoaWNoIHN1Y2NlZWQgb3Igb25lcyB3aGljaCBmYWlsIGFuZCBhcmUgY2xlYW5lZCB1cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvcnJlY3RseSBzaG91bGQgcmVzdWx0IGluIGBicm93c2VyVXJsVHJlZWAgYW5kIGBjdXJyZW50VXJsVHJlZWBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXRjaGluZy4gSWYgdGhpcyBpcyBub3QgdGhlIGNhc2UsIGFzc3VtZSBzb21ldGhpbmcgd2VudCB3cm9uZyBhbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cnkgcHJvY2Vzc2luZyB0aGUgVVJMIGFnYWluLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyb3dzZXJVcmxUcmVlICE9PSByb3V0ZXIuY3VycmVudFVybFRyZWUudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb2Nlc3NDdXJyZW50VXJsID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocm91dGVyLm9uU2FtZVVybE5hdmlnYXRpb24gPT09ICdyZWxvYWQnID8gdHJ1ZSA6IHVybFRyYW5zaXRpb24pICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLnVybEhhbmRsaW5nU3RyYXRlZ3kuc2hvdWxkUHJvY2Vzc1VybCh0LnJhd1VybCk7XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NDdXJyZW50VXJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBzb3VyY2Ugb2YgdGhlIG5hdmlnYXRpb24gaXMgZnJvbSBhIGJyb3dzZXIgZXZlbnQsIHRoZSBVUkwgaXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxyZWFkeSB1cGRhdGVkLiBXZSBhbHJlYWR5IG5lZWQgdG8gc3luYyB0aGUgaW50ZXJuYWwgc3RhdGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Jyb3dzZXJUcmlnZ2VyZWROYXZpZ2F0aW9uKHQuc291cmNlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlci5icm93c2VyVXJsVHJlZSA9IHQuZXh0cmFjdGVkVXJsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZih0KS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmlyZSBOYXZpZ2F0aW9uU3RhcnQgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHRoaXMudHJhbnNpdGlvbnM/LmdldFZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQobmV3IE5hdmlnYXRpb25TdGFydChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuaWQsIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC5leHRyYWN0ZWRVcmwpLCB0LnNvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQucmVzdG9yZWRTdGF0ZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNpdGlvbiAhPT0gdGhpcy50cmFuc2l0aW9ucz8uZ2V0VmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgZGVsYXkgaXMgcmVxdWlyZWQgdG8gbWF0Y2ggb2xkIGJlaGF2aW9yIHRoYXQgZm9yY2VkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gdG8gYWx3YXlzIGJlIGFzeW5jXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXBwbHlSZWRpcmVjdHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5UmVkaXJlY3RzKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW52aXJvbm1lbnRJbmplY3RvciwgdGhpcy5jb25maWdMb2FkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLCByb3V0ZXIuY29uZmlnKSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBjdXJyZW50TmF2aWdhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYHVybEFmdGVyUmVkaXJlY3RzYCBpcyBndWFyYW50ZWVkIHRvIGJlIHNldCBhZnRlciB0aGlzIHBvaW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXAodCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE5hdmlnYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udGhpcy5jdXJyZW50TmF2aWdhdGlvbiEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxVcmw6IHQudXJsQWZ0ZXJSZWRpcmVjdHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS51cmxBZnRlclJlZGlyZWN0cyA9IHQudXJsQWZ0ZXJSZWRpcmVjdHM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVjb2duaXplXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvZ25pemUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbnZpcm9ubWVudEluamVjdG9yLCByb3V0ZXIucm9vdENvbXBvbmVudFR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLmNvbmZpZywgdGhpcy51cmxTZXJpYWxpemVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlci5wYXJhbXNJbmhlcml0YW5jZVN0cmF0ZWd5KSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIFVSTCBpZiBpbiBgZWFnZXJgIHVwZGF0ZSBtb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXAodCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUudGFyZ2V0U25hcHNob3QgPSB0LnRhcmdldFNuYXBzaG90O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocm91dGVyLnVybFVwZGF0ZVN0cmF0ZWd5ID09PSAnZWFnZXInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0LmV4dHJhcy5za2lwTG9jYXRpb25DaGFuZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhd1VybCA9IHJvdXRlci51cmxIYW5kbGluZ1N0cmF0ZWd5Lm1lcmdlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQudXJsQWZ0ZXJSZWRpcmVjdHMhLCB0LnJhd1VybCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIuc2V0QnJvd3NlclVybChyYXdVcmwsIHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIuYnJvd3NlclVybFRyZWUgPSB0LnVybEFmdGVyUmVkaXJlY3RzITtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpcmUgUm91dGVzUmVjb2duaXplZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByb3V0ZXNSZWNvZ25pemVkID0gbmV3IFJvdXRlc1JlY29nbml6ZWQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmlkLCB0aGlzLnVybFNlcmlhbGl6ZXIuc2VyaWFsaXplKHQuZXh0cmFjdGVkVXJsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC51cmxBZnRlclJlZGlyZWN0cyEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC50YXJnZXRTbmFwc2hvdCEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KHJvdXRlc1JlY29nbml6ZWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvY2Vzc1ByZXZpb3VzVXJsID0gdXJsVHJhbnNpdGlvbiAmJiByb3V0ZXIucmF3VXJsVHJlZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLnVybEhhbmRsaW5nU3RyYXRlZ3kuc2hvdWxkUHJvY2Vzc1VybChyb3V0ZXIucmF3VXJsVHJlZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdoZW4gdGhlIGN1cnJlbnQgVVJMIHNob3VsZG4ndCBiZSBwcm9jZXNzZWQsIGJ1dCB0aGUgcHJldmlvdXMgb25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHdhcywgd2UgaGFuZGxlIHRoaXMgXCJlcnJvciBjb25kaXRpb25cIiBieSBuYXZpZ2F0aW5nIHRvIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBwcmV2aW91c2x5IHN1Y2Nlc3NmdWwgVVJMLCBidXQgbGVhdmluZyB0aGUgVVJMIGludGFjdC4qL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc1ByZXZpb3VzVXJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qge2lkLCBleHRyYWN0ZWRVcmwsIHNvdXJjZSwgcmVzdG9yZWRTdGF0ZSwgZXh0cmFzfSA9IHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF2U3RhcnQgPSBuZXcgTmF2aWdhdGlvblN0YXJ0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCwgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZShleHRyYWN0ZWRVcmwpLCBzb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RvcmVkU3RhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQobmF2U3RhcnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldFNuYXBzaG90ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRW1wdHlTdGF0ZShleHRyYWN0ZWRVcmwsIHJvdXRlci5yb290Q29tcG9uZW50VHlwZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zbmFwc2hvdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0U25hcHNob3QsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmxBZnRlclJlZGlyZWN0czogZXh0cmFjdGVkVXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFzOiB7Li4uZXh0cmFzLCBza2lwTG9jYXRpb25DaGFuZ2U6IGZhbHNlLCByZXBsYWNlVXJsOiBmYWxzZX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2Yob3ZlcmFsbFRyYW5zaXRpb25TdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogV2hlbiBuZWl0aGVyIHRoZSBjdXJyZW50IG9yIHByZXZpb3VzIFVSTCBjYW4gYmUgcHJvY2Vzc2VkLCBkb1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIG5vdGhpbmcgb3RoZXIgdGhhbiB1cGRhdGUgcm91dGVyJ3MgaW50ZXJuYWwgcmVmZXJlbmNlIHRvIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGN1cnJlbnQgXCJzZXR0bGVkXCIgVVJMLiBUaGlzIHdheSB0aGUgbmV4dCBuYXZpZ2F0aW9uIHdpbGwgYmUgY29taW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZnJvbSB0aGUgY3VycmVudCBVUkwgaW4gdGhlIGJyb3dzZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLnJhd1VybFRyZWUgPSB0LnJhd1VybDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgfSksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAvLyAtLS0gR1VBUkRTIC0tLVxuICAgICAgICAgICAgICAgICAgICAgICAgIHRhcCh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGd1YXJkc1N0YXJ0ID0gbmV3IEd1YXJkc0NoZWNrU3RhcnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5pZCwgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LnVybEFmdGVyUmVkaXJlY3RzISksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC50YXJnZXRTbmFwc2hvdCEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMubmV4dChndWFyZHNTdGFydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgfSksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBtYXAodCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBndWFyZHM6IGdldEFsbFJvdXRlR3VhcmRzKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC50YXJnZXRTbmFwc2hvdCEsIHQuY3VycmVudFNuYXBzaG90LCB0aGlzLnJvb3RDb250ZXh0cylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrR3VhcmRzKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVudmlyb25tZW50SW5qZWN0b3IsIChldnQ6IEV2ZW50KSA9PiB0aGlzLmV2ZW50cy5uZXh0KGV2dCkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHRhcCh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUuZ3VhcmRzUmVzdWx0ID0gdC5ndWFyZHNSZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNVcmxUcmVlKHQuZ3VhcmRzUmVzdWx0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyByZWRpcmVjdGluZ05hdmlnYXRpb25FcnJvcih0aGlzLnVybFNlcmlhbGl6ZXIsIHQuZ3VhcmRzUmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3VhcmRzRW5kID0gbmV3IEd1YXJkc0NoZWNrRW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuaWQsIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC5leHRyYWN0ZWRVcmwpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC51cmxBZnRlclJlZGlyZWN0cyEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQudGFyZ2V0U25hcHNob3QhLCAhIXQuZ3VhcmRzUmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQoZ3VhcmRzRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcblxuICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcih0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdC5ndWFyZHNSZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLnJlc3RvcmVIaXN0b3J5KHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbE5hdmlnYXRpb25UcmFuc2l0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCwgJycsIE5hdmlnYXRpb25DYW5jZWxsYXRpb25Db2RlLkd1YXJkUmVqZWN0ZWQsIHJvdXRlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgLy8gLS0tIFJFU09MVkUgLS0tXG4gICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoVGFwKHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQuZ3VhcmRzLmNhbkFjdGl2YXRlQ2hlY2tzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YodCkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcCh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZVN0YXJ0ID0gbmV3IFJlc29sdmVTdGFydChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuaWQsIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC5leHRyYWN0ZWRVcmwpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LnVybEFmdGVyUmVkaXJlY3RzISksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnRhcmdldFNuYXBzaG90ISk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQocmVzb2x2ZVN0YXJ0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoTWFwKHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGF0YVJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZih0KS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZURhdGEoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLnBhcmFtc0luaGVyaXRhbmNlU3RyYXRlZ3ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbnZpcm9ubWVudEluamVjdG9yKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6ICgpID0+IGRhdGFSZXNvbHZlZCA9IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhUmVzb2x2ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlci5yZXN0b3JlSGlzdG9yeSh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsTmF2aWdhdGlvblRyYW5zaXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOR19ERVZfTU9ERSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBBdCBsZWFzdCBvbmUgcm91dGUgcmVzb2x2ZXIgZGlkbid0IGVtaXQgYW55IHZhbHVlLmAgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXZpZ2F0aW9uQ2FuY2VsbGF0aW9uQ29kZS5Ob0RhdGFGcm9tUmVzb2x2ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXAodCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVFbmQgPSBuZXcgUmVzb2x2ZUVuZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuaWQsIHRoaXMudXJsU2VyaWFsaXplci5zZXJpYWxpemUodC5leHRyYWN0ZWRVcmwpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LnVybEFmdGVyUmVkaXJlY3RzISksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnRhcmdldFNuYXBzaG90ISk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQocmVzb2x2ZUVuZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgLy8gLS0tIExPQUQgQ09NUE9ORU5UUyAtLS1cbiAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hUYXAoKHQ6IE5hdmlnYXRpb25UcmFuc2l0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2FkQ29tcG9uZW50cyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogQXJyYXk8T2JzZXJ2YWJsZTx2b2lkPj4gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9hZGVyczogQXJyYXk8T2JzZXJ2YWJsZTx2b2lkPj4gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyb3V0ZS5yb3V0ZUNvbmZpZz8ubG9hZENvbXBvbmVudCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFyb3V0ZS5yb3V0ZUNvbmZpZy5fbG9hZGVkQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlcnMucHVzaCh0aGlzLmNvbmZpZ0xvYWRlci5sb2FkQ29tcG9uZW50KHJvdXRlLnJvdXRlQ29uZmlnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXAobG9hZGVkQ29tcG9uZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZS5jb21wb25lbnQgPSBsb2FkZWRDb21wb25lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKCkgPT4gdm9pZCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHJvdXRlLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlcnMucHVzaCguLi5sb2FkQ29tcG9uZW50cyhjaGlsZCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRlcnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KGxvYWRDb21wb25lbnRzKHQudGFyZ2V0U25hcHNob3QhLnJvb3QpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5waXBlKGRlZmF1bHRJZkVtcHR5KCksIHRha2UoMSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoVGFwKCgpID0+IHJvdXRlci5hZnRlclByZWFjdGl2YXRpb24oKSksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKHQ6IE5hdmlnYXRpb25UcmFuc2l0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXRSb3V0ZXJTdGF0ZSA9IGNyZWF0ZVJvdXRlclN0YXRlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlci5yb3V0ZVJldXNlU3RyYXRlZ3ksIHQudGFyZ2V0U25hcHNob3QhLCB0LmN1cnJlbnRSb3V0ZXJTdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlID0gey4uLnQsIHRhcmdldFJvdXRlclN0YXRlfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAob3ZlcmFsbFRyYW5zaXRpb25TdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgfSksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAvKiBPbmNlIGhlcmUsIHdlIGFyZSBhYm91dCB0byBhY3RpdmF0ZSBzeW5jaHJvbm91c2x5LiBUaGUgYXNzdW1wdGlvbiBpc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgd2lsbCBzdWNjZWVkLCBhbmQgdXNlciBjb2RlIG1heSByZWFkIGZyb20gdGhlIFJvdXRlciBzZXJ2aWNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZXJlZm9yZSBiZWZvcmUgYWN0aXZhdGlvbiwgd2UgbmVlZCB0byB1cGRhdGUgcm91dGVyIHByb3BlcnRpZXMgc3RvcmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBjdXJyZW50IFVSTCBhbmQgdGhlIFJvdXRlclN0YXRlLCBhcyB3ZWxsIGFzIHVwZGF0ZWQgdGhlIGJyb3dzZXIgVVJMLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsbCB0aGlzIHNob3VsZCBoYXBwZW4gKmJlZm9yZSogYWN0aXZhdGluZy4gKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICB0YXAoKHQ6IE5hdmlnYXRpb25UcmFuc2l0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIuY3VycmVudFVybFRyZWUgPSB0LnVybEFmdGVyUmVkaXJlY3RzITtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlci5yYXdVcmxUcmVlID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIudXJsSGFuZGxpbmdTdHJhdGVneS5tZXJnZSh0LnVybEFmdGVyUmVkaXJlY3RzISwgdC5yYXdVcmwpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAocm91dGVyIGFzIHtyb3V0ZXJTdGF0ZTogUm91dGVyU3RhdGV9KS5yb3V0ZXJTdGF0ZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC50YXJnZXRSb3V0ZXJTdGF0ZSE7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyb3V0ZXIudXJsVXBkYXRlU3RyYXRlZ3kgPT09ICdkZWZlcnJlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0LmV4dHJhcy5za2lwTG9jYXRpb25DaGFuZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIuc2V0QnJvd3NlclVybChyb3V0ZXIucmF3VXJsVHJlZSwgdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLmJyb3dzZXJVcmxUcmVlID0gdC51cmxBZnRlclJlZGlyZWN0cyE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgfSksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmF0ZVJvdXRlcyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yb290Q29udGV4dHMsIHJvdXRlci5yb3V0ZVJldXNlU3RyYXRlZ3ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChldnQ6IEV2ZW50KSA9PiB0aGlzLmV2ZW50cy5uZXh0KGV2dCkpLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgdGFwKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6ICh0OiBOYXZpZ2F0aW9uVHJhbnNpdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxhc3RTdWNjZXNzZnVsTmF2aWdhdGlvbiA9IHRoaXMuY3VycmVudE5hdmlnYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlci5uYXZpZ2F0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cy5uZXh0KG5ldyBOYXZpZ2F0aW9uRW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5pZCwgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZSh0LmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVybFNlcmlhbGl6ZXIuc2VyaWFsaXplKHJvdXRlci5jdXJyZW50VXJsVHJlZSkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLnRpdGxlU3RyYXRlZ3k/LnVwZGF0ZVRpdGxlKHQudGFyZ2V0Um91dGVyU3RhdGUhLnNuYXBzaG90KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5yZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogV2hlbiB0aGUgbmF2aWdhdGlvbiBzdHJlYW0gZmluaXNoZXMgZWl0aGVyIHRocm91Z2ggZXJyb3Igb3Igc3VjY2VzcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHdlIHNldCB0aGUgYGNvbXBsZXRlZGAgb3IgYGVycm9yZWRgIGZsYWcuIEhvd2V2ZXIsIHRoZXJlIGFyZSBzb21lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzaXR1YXRpb25zIHdoZXJlIHdlIGNvdWxkIGdldCBoZXJlIHdpdGhvdXQgZWl0aGVyIG9mIHRob3NlIGJlaW5nIHNldC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIEZvciBpbnN0YW5jZSwgYSByZWRpcmVjdCBkdXJpbmcgTmF2aWdhdGlvblN0YXJ0LiBUaGVyZWZvcmUsIHRoaXMgaXMgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICogY2F0Y2gtYWxsIHRvIG1ha2Ugc3VyZSB0aGUgTmF2aWdhdGlvbkNhbmNlbCBldmVudCBpcyBmaXJlZCB3aGVuIGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIG5hdmlnYXRpb24gZ2V0cyBjYW5jZWxsZWQgYnV0IG5vdCBjYXVnaHQgYnkgb3RoZXIgbWVhbnMuICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbXBsZXRlZCAmJiAhZXJyb3JlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5jZWxhdGlvblJlYXNvbiA9IE5HX0RFVl9NT0RFID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOYXZpZ2F0aW9uIElEICR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaWR9IGlzIG5vdCBlcXVhbCB0byB0aGUgY3VycmVudCBuYXZpZ2F0aW9uIGlkICR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uSWR9YCA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW5jZWxOYXZpZ2F0aW9uVHJhbnNpdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUsIGNhbmNlbGF0aW9uUmVhc29uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF2aWdhdGlvbkNhbmNlbGxhdGlvbkNvZGUuU3VwZXJzZWRlZEJ5TmV3TmF2aWdhdGlvbiwgcm91dGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgY2xlYXIgY3VycmVudCBuYXZpZ2F0aW9uIGlmIGl0IGlzIHN0aWxsIHNldCB0byB0aGUgb25lIHRoYXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmFsaXplZC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnROYXZpZ2F0aW9uPy5pZCA9PT0gb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnROYXZpZ2F0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaEVycm9yKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgZXJyb3IgdHlwZSBpcyBpc3N1ZWQgZHVyaW5nIFJlZGlyZWN0LCBhbmQgaXMgaGFuZGxlZCBhcyBhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBjYW5jZWxsYXRpb24gcmF0aGVyIHRoYW4gYW4gZXJyb3IuICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYXZpZ2F0aW9uQ2FuY2VsaW5nRXJyb3IoZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1JlZGlyZWN0aW5nTmF2aWdhdGlvbkNhbmNlbGluZ0Vycm9yKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IHByb3BlcnR5IG9ubHkgaWYgd2UncmUgbm90IHJlZGlyZWN0aW5nLiBJZiB3ZSBsYW5kZWQgb24gYSBwYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHJlZGlyZWN0IHRvIGAvYCByb3V0ZSwgdGhlIG5ldyBuYXZpZ2F0aW9uIGlzIGdvaW5nIHRvIHNlZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBgL2AgaXNuJ3QgYSBjaGFuZ2UgZnJvbSB0aGUgZGVmYXVsdCBjdXJyZW50VXJsVHJlZSBhbmQgd29uJ3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuYXZpZ2F0ZS4gVGhpcyBpcyBvbmx5IGFwcGxpY2FibGUgd2l0aCBpbml0aWFsIG5hdmlnYXRpb24sIHNvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2V0dGluZyBgbmF2aWdhdGVkYCBvbmx5IHdoZW4gbm90IHJlZGlyZWN0aW5nIHJlc29sdmVzIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzY2VuYXJpby5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIubmF2aWdhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIucmVzdG9yZUhpc3Rvcnkob3ZlcmFsbFRyYW5zaXRpb25TdGF0ZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF2Q2FuY2VsID0gbmV3IE5hdmlnYXRpb25DYW5jZWwoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZShvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLm1lc3NhZ2UsIGUuY2FuY2VsbGF0aW9uQ29kZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQobmF2Q2FuY2VsKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHJlZGlyZWN0aW5nLCB3ZSBuZWVkIHRvIGRlbGF5IHJlc29sdmluZyB0aGUgbmF2aWdhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwcm9taXNlIGFuZCBwdXNoIGl0IHRvIHRoZSByZWRpcmVjdCBuYXZpZ2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNSZWRpcmVjdGluZ05hdmlnYXRpb25DYW5jZWxpbmdFcnJvcihlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVyZ2VkVHJlZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlci51cmxIYW5kbGluZ1N0cmF0ZWd5Lm1lcmdlKGUudXJsLCByb3V0ZXIucmF3VXJsVHJlZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0cmFzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcExvY2F0aW9uQ2hhbmdlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUuZXh0cmFzLnNraXBMb2NhdGlvbkNoYW5nZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBVUkwgaXMgYWxyZWFkeSB1cGRhdGVkIGF0IHRoaXMgcG9pbnQgaWYgd2UgaGF2ZSAnZWFnZXInIFVSTFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlcyBvciBpZiB0aGUgbmF2aWdhdGlvbiB3YXMgdHJpZ2dlcmVkIGJ5IHRoZSBicm93c2VyIChiYWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBidXR0b24sIFVSTCBiYXIsIGV0YykuIFdlIHdhbnQgdG8gcmVwbGFjZSB0aGF0IGl0ZW0gaW4gaGlzdG9yeVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIG5hdmlnYXRpb24gaXMgcmVqZWN0ZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlVXJsOiByb3V0ZXIudXJsVXBkYXRlU3RyYXRlZ3kgPT09ICdlYWdlcicgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0Jyb3dzZXJUcmlnZ2VyZWROYXZpZ2F0aW9uKG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUuc291cmNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXIuc2NoZWR1bGVOYXZpZ2F0aW9uKG1lcmdlZFRyZWUsICdpbXBlcmF0aXZlJywgbnVsbCwgZXh0cmFzLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlOiBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLnJlc29sdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3Q6IG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUucmVqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZTogb3ZlcmFsbFRyYW5zaXRpb25TdGF0ZS5wcm9taXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBBbGwgb3RoZXIgZXJyb3JzIHNob3VsZCByZXNldCB0byB0aGUgcm91dGVyJ3MgaW50ZXJuYWwgVVJMIHJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB0byB0aGUgcHJlLWVycm9yIHN0YXRlLiAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVyLnJlc3RvcmVIaXN0b3J5KG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXZFcnJvciA9IG5ldyBOYXZpZ2F0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cmxTZXJpYWxpemVyLnNlcmlhbGl6ZShvdmVyYWxsVHJhbnNpdGlvblN0YXRlLmV4dHJhY3RlZFVybCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLCBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLnRhcmdldFNuYXBzaG90ID8/IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLm5leHQobmF2RXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxUcmFuc2l0aW9uU3RhdGUucmVzb2x2ZShyb3V0ZXIuZXJyb3JIYW5kbGVyKGUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyYWxsVHJhbnNpdGlvblN0YXRlLnJlamVjdChlZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgIC8vIFRPRE8oamFzb25hZGVuKTogcmVtb3ZlIGNhc3Qgb25jZSBnMyBpcyBvbiB1cGRhdGVkIFR5cGVTY3JpcHRcbiAgICAgICAgICAgICAgIH0pKSBhcyBhbnkgYXMgT2JzZXJ2YWJsZTxOYXZpZ2F0aW9uVHJhbnNpdGlvbj47XG4gIH1cblxuICBwcml2YXRlIGNhbmNlbE5hdmlnYXRpb25UcmFuc2l0aW9uKFxuICAgICAgdDogTmF2aWdhdGlvblRyYW5zaXRpb24sIHJlYXNvbjogc3RyaW5nLCBjb2RlOiBOYXZpZ2F0aW9uQ2FuY2VsbGF0aW9uQ29kZSxcbiAgICAgIHJvdXRlcjogSW50ZXJuYWxSb3V0ZXJJbnRlcmZhY2UpIHtcbiAgICBjb25zdCBuYXZDYW5jZWwgPVxuICAgICAgICBuZXcgTmF2aWdhdGlvbkNhbmNlbCh0LmlkLCB0aGlzLnVybFNlcmlhbGl6ZXIuc2VyaWFsaXplKHQuZXh0cmFjdGVkVXJsKSwgcmVhc29uLCBjb2RlKTtcbiAgICB0aGlzLmV2ZW50cy5uZXh0KG5hdkNhbmNlbCk7XG4gICAgdC5yZXNvbHZlKGZhbHNlKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNCcm93c2VyVHJpZ2dlcmVkTmF2aWdhdGlvbihzb3VyY2U6ICdpbXBlcmF0aXZlJ3wncG9wc3RhdGUnfCdoYXNoY2hhbmdlJykge1xuICByZXR1cm4gc291cmNlICE9PSAnaW1wZXJhdGl2ZSc7XG59XG4iXX0=