@wavemaker/app-ng-runtime 11.14.2-1.6423 → 11.14.2-2.6435

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 (35) hide show
  1. package/components/base/bundles/index.umd.js +6 -12
  2. package/components/base/esm2022/widgets/common/base/base.component.mjs +8 -14
  3. package/components/base/fesm2022/index.mjs +7 -13
  4. package/components/base/fesm2022/index.mjs.map +1 -1
  5. package/components/data/table/bundles/index.umd.js +5 -5
  6. package/components/data/table/esm2022/table.component.mjs +7 -7
  7. package/components/data/table/fesm2022/index.mjs +6 -6
  8. package/components/data/table/fesm2022/index.mjs.map +1 -1
  9. package/components/prefab/bundles/index.umd.js +0 -4
  10. package/components/prefab/esm2022/prefab.directive.mjs +1 -5
  11. package/components/prefab/fesm2022/index.mjs +0 -4
  12. package/components/prefab/fesm2022/index.mjs.map +1 -1
  13. package/core/bundles/index.umd.js +187 -330
  14. package/core/esm2022/public_api.mjs +2 -2
  15. package/core/esm2022/utils/watcher.mjs +191 -327
  16. package/core/fesm2022/index.mjs +194 -330
  17. package/core/fesm2022/index.mjs.map +1 -1
  18. package/core/public_api.d.ts +1 -1
  19. package/core/utils/watcher.d.ts +5 -26
  20. package/npm-shrinkwrap.json +2 -2
  21. package/package-lock.json +2 -2
  22. package/package.json +1 -1
  23. package/runtime/base/bundles/index.umd.js +11 -171
  24. package/runtime/base/components/app-component/app.component.d.ts +0 -4
  25. package/runtime/base/esm2022/components/app-component/app.component.mjs +9 -40
  26. package/runtime/base/esm2022/components/base-page.component.mjs +3 -35
  27. package/runtime/base/esm2022/components/base-partial.component.mjs +3 -37
  28. package/runtime/base/esm2022/components/base-prefab.component.mjs +3 -32
  29. package/runtime/base/esm2022/components/base-spa-page.component.mjs +3 -37
  30. package/runtime/base/fesm2022/index.mjs +12 -172
  31. package/runtime/base/fesm2022/index.mjs.map +1 -1
  32. package/runtime/dynamic/bundles/index.umd.js +4 -0
  33. package/runtime/dynamic/esm2022/app/app.config.mjs +6 -2
  34. package/runtime/dynamic/fesm2022/index.mjs +5 -1
  35. package/runtime/dynamic/fesm2022/index.mjs.map +1 -1
@@ -5,7 +5,7 @@ export * from './enums/enums';
5
5
  export * from './utils/event-notifier';
6
6
  export { ParseExprResult, $parseExpr, $parseEvent, registerFnByExpr, setPipeProvider, getFnByExpr, getFnForBindExpr, getFnForEventExpr } from './utils/expression-parser';
7
7
  export { EVENT_LIFE, isDefined, isObject, toBoolean, isIE, isAndroid, isAndroidTablet, isIphone, isIpod, isIpad, isIos, isSafari, isLargeTabletLandscape, isLargeTabletPortrait, isMobile, getAndroidVersion, isKitkatDevice, encodeUrl, encodeUrlParams, initCaps, spaceSeparate, replaceAt, periodSeparate, prettifyLabel, deHyphenate, prettifyLabels, isInsecureContentRequest, stringStartsWith, getEvaluatedExprValue, isImageFile, isAudioFile, isVideoFile, isValidImageUrl, isValidWebURL, getResourceURL, triggerFn, hasOffsetStr, getFormattedDate, getDateObj, addEventListenerOnElement, getClonedObject, getFiles, generateGUId, validateAccessRoles, getValidJSON, xmlToJson, findValueOf, extractType, isNumberType, isEmptyObject, scrollToElement, isElementInViewport, isPageable, replace, isDateTimeType, getValidDateObject, getNativeDateObject, getBlob, isEqualWithFields, loadStyleSheet, loadStyleSheets, loadScript, loadScripts, _WM_APP_PROJECT, setSessionStorageItem, getSessionStorageItem, noop, convertToBlob, AppConstants, openLink, fetchContent, toPromise, retryIfFails, getAbortableDefer, createCSSRule, getUrlParams, getMomentLocaleObject, getRouteNameFromLink, isAppleProduct, defer, executePromiseChain, isDataSourceEqual, validateDataSourceCtx, processFilterExpBindNode, extendProto, removeExtraSlashes, getDisplayDateTimeFormat, addForIdAttributes, adjustContainerPosition, adjustContainerRightEdges, setTranslation3dPosition, getWebkitTraslationMatrix, closePopover, detectChanges, triggerItemAction, getDatasourceFromExpr, extractCurrentItemExpr, findRootContainer, VALIDATOR, transformFileURI, appendScriptToHead, getAppSetting, setListClass, findParent, getNavClass, getSheetPositionClass } from './utils/utils';
8
- export { FIRST_TIME_WATCH, isFirstTimeChange, debounce, muteWatchers, unMuteWatchers, $watch, $unwatch, $unwatchAll, $unwatchAllByScope, setNgZone, setAppRef, isChangeFromWatch, resetChangeFromWatch, $invokeWatchers, $appDigest } from './utils/watcher';
8
+ export { FIRST_TIME_WATCH, isFirstTimeChange, debounce, muteWatchers, unMuteWatchers, $watch, $unwatch, setNgZone, setAppRef, isChangeFromWatch, resetChangeFromWatch, $invokeWatchers, $appDigest } from './utils/watcher';
9
9
  export * from './utils/id-generator';
10
10
  export * from './types/types';
11
11
  export { Viewport, ViewportEvent } from './services/viewport.service';
@@ -1,34 +1,13 @@
1
- export declare const FIRST_TIME_WATCH: Readonly<{}>;
2
- type ScopeType = 'Page' | 'Prefab' | 'Partial' | 'App';
3
- interface WatchConfig {
4
- arrayType?: boolean;
5
- isList?: boolean;
6
- }
1
+ export declare const FIRST_TIME_WATCH: {};
7
2
  export declare const isFirstTimeChange: (v: any) => boolean;
8
3
  export declare const debounce: (fn: Function, wait?: number) => (...args: any[]) => void;
9
4
  export declare const muteWatchers: () => void;
10
5
  export declare const unMuteWatchers: () => void;
11
- /**
12
- * Main watch function
13
- */
14
- export declare const $watch: (expr: string, $scope: any, $locals: any, listener: any, identifier?: string, doNotClone?: boolean, config?: WatchConfig, isMuted?: () => boolean) => () => void;
15
- /**
16
- * Unwatches a single identifier
17
- */
18
- export declare const $unwatch: (identifier: string) => boolean;
19
- /**
20
- * Unwatches all watchers for a specific widget ID
21
- */
22
- export declare const $unwatchAll: (widgetId: string) => number;
23
- /**
24
- * Unwatches all watchers for a specific scope (Page, Prefab, Partial, or App)
25
- * Now works directly with the main registry instead of separate scoped registries
26
- */
27
- export declare const $unwatchAllByScope: (scopeType: ScopeType, scopeName?: string) => number;
28
- export declare const setNgZone: (zone: any) => void;
6
+ export declare const $watch: (expr: any, $scope: any, $locals: any, listener: any, identifier?: string, doNotClone?: boolean, config?: any, isMuted?: () => boolean) => () => boolean;
7
+ export declare const $unwatch: (identifier: any) => boolean;
8
+ export declare const setNgZone: (zone: any) => any;
29
9
  export declare const setAppRef: (ref: any) => void;
30
10
  export declare const isChangeFromWatch: () => boolean;
31
- export declare const resetChangeFromWatch: () => void;
11
+ export declare const resetChangeFromWatch: () => boolean;
32
12
  export declare const $invokeWatchers: (force?: boolean, ignoreMuted?: boolean) => void;
33
13
  export declare const $appDigest: (force?: boolean) => void;
34
- export {};
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@wavemaker/app-ng-runtime",
3
- "version": "11.14.2-1.6423",
3
+ "version": "11.14.2-2.6435",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@wavemaker/app-ng-runtime",
9
- "version": "11.14.2-1.6423",
9
+ "version": "11.14.2-2.6435",
10
10
  "license": "MIT",
11
11
  "engines": {
12
12
  "node": ">=18.16.1",
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@wavemaker/app-ng-runtime",
3
- "version": "11.14.2-1.6423",
3
+ "version": "11.14.2-2.6435",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@wavemaker/app-ng-runtime",
9
- "version": "11.14.2-1.6423",
9
+ "version": "11.14.2-2.6435",
10
10
  "license": "MIT",
11
11
  "engines": {
12
12
  "node": ">=18.16.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wavemaker/app-ng-runtime",
3
- "version": "11.14.2-1.6423",
3
+ "version": "11.14.2-2.6435",
4
4
  "description": "All modules required for a WaveMaker application.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -890,41 +890,7 @@
890
890
  });
891
891
  }
892
892
  ngOnDestroy() {
893
- // MEMORY LEAK FIX: Unwatch all Partial-scoped watchers for THIS specific partial when partial is destroyed
894
- // Only unwatch watchers for this partial, not all partials (other partials may still be on the page)
895
- if (this.partialName) {
896
- i1.$unwatchAllByScope('Partial', this.partialName);
897
- }
898
- // MEMORY LEAK FIX: Complete Subjects to release subscriptions
899
- if (this.destroy$) {
900
- this.destroy$.complete();
901
- this.destroy$ = null;
902
- }
903
- if (this.viewInit$) {
904
- this.viewInit$.complete();
905
- this.viewInit$ = null;
906
- }
907
- // MEMORY LEAK FIX: Clear references to prevent memory leaks
908
- this.Widgets = null;
909
- this.Variables = null;
910
- this.Actions = null;
911
- this.App = null;
912
- this.containerWidget = null;
913
- this.i18nService = null;
914
- this.appLocale = null;
915
- this.partialDirective = null;
916
- this.pageDirective = null;
917
- this.Prefab = null;
918
- this.scriptLoaderService = null;
919
- this.Viewport = null;
920
- this.route = null;
921
- this.appManager = null;
922
- this.navigationService = null;
923
- this.router = null;
924
- this.pageParams = null;
925
- this.viewParent = null;
926
- // MEMORY LEAK FIX: Cleanup FragmentMonitor resources
927
- this.cleanupFragmentMonitor();
893
+ this.destroy$.complete();
928
894
  }
929
895
  ngOnAttach(refreshData) {
930
896
  this.unmute();
@@ -1370,41 +1336,9 @@
1370
1336
  }
1371
1337
  ngOnDestroy() {
1372
1338
  // MEMORY LEAK FIX: Unwatch all Page-scoped watchers for THIS specific page when page is destroyed
1373
- if (this.pageName) {
1374
- const removedCount = i1.$unwatchAllByScope('Page', this.pageName);
1375
- if (removedCount > 0) {
1376
- console.log(`🧹 Cleaned up ${removedCount} Page-scoped watcher(s) for page ${this.pageName}`);
1377
- }
1378
- }
1379
1339
  //this.captureApplicationThumbnail();
1380
1340
  this.savePageSnapShot();
1381
- // MEMORY LEAK FIX: Complete Subjects to release subscriptions
1382
- if (this.destroy$) {
1383
- this.destroy$.complete();
1384
- this.destroy$ = null;
1385
- }
1386
- if (this.viewInit$) {
1387
- this.viewInit$.complete();
1388
- this.viewInit$ = null;
1389
- }
1390
- // MEMORY LEAK FIX: Clear references to prevent memory leaks
1391
- this.Widgets = null;
1392
- this.Variables = null;
1393
- this.Actions = null;
1394
- this.App = null;
1395
- this.route = null;
1396
- this.appManager = null;
1397
- this.navigationService = null;
1398
- this.router = null;
1399
- this.pageParams = null;
1400
- this.i18nService = null;
1401
- this.appLocale = null;
1402
- this.pageDirective = null;
1403
- this.$page = null;
1404
- this.scriptLoaderService = null;
1405
- this.Viewport = null;
1406
- // MEMORY LEAK FIX: Cleanup FragmentMonitor resources
1407
- this.cleanupFragmentMonitor();
1341
+ this.destroy$.complete();
1408
1342
  }
1409
1343
  captureApplicationThumbnail() {
1410
1344
  const root = this;
@@ -2027,36 +1961,7 @@
2027
1961
  });
2028
1962
  }
2029
1963
  ngOnDestroy() {
2030
- // MEMORY LEAK FIX: Unwatch all Prefab-scoped watchers for THIS specific prefab when prefab is destroyed
2031
- // Only unwatch watchers for this prefab, not all prefabs (other prefabs may still be on the page)
2032
- if (this.prefabName) {
2033
- i1.$unwatchAllByScope('Prefab', this.prefabName);
2034
- }
2035
- // MEMORY LEAK FIX: Complete Subjects to release subscriptions
2036
- if (this.destroy$) {
2037
- this.destroy$.complete();
2038
- this.destroy$ = null;
2039
- }
2040
- if (this.viewInit$) {
2041
- this.viewInit$.complete();
2042
- this.viewInit$ = null;
2043
- }
2044
- // MEMORY LEAK FIX: Clear references to prevent memory leaks
2045
- this.Widgets = null;
2046
- this.Variables = null;
2047
- this.Actions = null;
2048
- this.App = null;
2049
- this.containerWidget = null;
2050
- this.prefabMngr = null;
2051
- this.i18nService = null;
2052
- this.appLocale = null;
2053
- this.prefabContainerDirective = null;
2054
- this.scriptLoaderService = null;
2055
- this.pageDirective = null;
2056
- this.Viewport = null;
2057
- this.viewParent = null;
2058
- // MEMORY LEAK FIX: Cleanup FragmentMonitor resources
2059
- this.cleanupFragmentMonitor();
1964
+ this.destroy$.complete();
2060
1965
  }
2061
1966
  // user overrides this
2062
1967
  onPropertyChange() { }
@@ -2797,42 +2702,8 @@
2797
2702
  });
2798
2703
  }
2799
2704
  ngOnDestroy() {
2800
- // MEMORY LEAK FIX: Unwatch all Page-scoped watchers for THIS specific page when page is destroyed
2801
- if (this.pageName) {
2802
- i1.$unwatchAllByScope('Page', this.pageName);
2803
- // if (removedCount > 0) {
2804
- // console.log(`🧹 Cleaned up ${removedCount} Page-scoped watcher(s) for page ${this.pageName}`);
2805
- // }
2806
- }
2807
2705
  this.savePageSnapShot();
2808
- // MEMORY LEAK FIX: Complete Subjects to release subscriptions
2809
- if (this.destroy$) {
2810
- this.destroy$.complete();
2811
- this.destroy$ = null;
2812
- }
2813
- if (this.viewInit$) {
2814
- this.viewInit$.complete();
2815
- this.viewInit$ = null;
2816
- }
2817
- // MEMORY LEAK FIX: Clear references to prevent memory leaks
2818
- this.Widgets = null;
2819
- this.Variables = null;
2820
- this.Actions = null;
2821
- this.App = null;
2822
- this.route = null;
2823
- this.appManager = null;
2824
- this.navigationService = null;
2825
- this.router = null;
2826
- this.pageParams = null;
2827
- this.i18nService = null;
2828
- this.appLocale = null;
2829
- this.layoutDirective = null;
2830
- this.spaPageDirective = null;
2831
- this.$page = null;
2832
- this.scriptLoaderService = null;
2833
- this.Viewport = null;
2834
- // MEMORY LEAK FIX: Cleanup FragmentMonitor resources
2835
- this.cleanupFragmentMonitor();
2706
+ this.destroy$.complete();
2836
2707
  }
2837
2708
  onReady() { }
2838
2709
  onBeforePageReady() { }
@@ -4590,7 +4461,6 @@
4590
4461
  this.isApplicationType = false;
4591
4462
  this.enableSkipToMainContent = i1.getWmProjectProperties().enableSkipToMainContent === 'true' || i1.getWmProjectProperties().enableSkipToMainContent === true;
4592
4463
  this.retryCount = 0;
4593
- this.appManagerSubscriptions = []; // MEMORY LEAK FIX: Track appManager subscriptions
4594
4464
  this.appLocale = {};
4595
4465
  this.spinner = { show: false, messages: [], arialabel: '' };
4596
4466
  this.isOAuthDialogOpen = false;
@@ -4603,8 +4473,7 @@
4603
4473
  this.customIconsLoaderService.load();
4604
4474
  }
4605
4475
  // subscribe to OAuth changes
4606
- // MEMORY LEAK FIX: Store subscription reference for cleanup
4607
- this.oAuthProvidersSubscription = oAuthService.getOAuthProvidersAsObservable().subscribe((providers) => {
4476
+ oAuthService.getOAuthProvidersAsObservable().subscribe((providers) => {
4608
4477
  this.providersConfig = providers;
4609
4478
  if (providers.length) {
4610
4479
  this.showOAuthDialog();
@@ -4614,8 +4483,7 @@
4614
4483
  }
4615
4484
  });
4616
4485
  // Subscribe to the message source to show/hide app spinner
4617
- // MEMORY LEAK FIX: Store subscription reference for cleanup
4618
- this.spinnerMessageSubscription = this.spinnerService.getMessageSource().asObservable().subscribe((data) => {
4486
+ this.spinnerService.getMessageSource().asObservable().subscribe((data) => {
4619
4487
  // setTimeout is to avoid 'ExpressionChangedAfterItHasBeenCheckedError'
4620
4488
  setTimeout(() => {
4621
4489
  this.spinner.show = data.show;
@@ -4627,8 +4495,7 @@
4627
4495
  utils.setTheme('bs3');
4628
4496
  let spinnerId;
4629
4497
  let onPageRendered = i1.noop;
4630
- // MEMORY LEAK FIX: Store subscription reference for cleanup
4631
- this.routerEventsSubscription = this.router.events.subscribe(e => {
4498
+ this.router.events.subscribe(e => {
4632
4499
  if (e instanceof i1$1.NavigationStart) {
4633
4500
  let page = e.url.split('?')[0];
4634
4501
  page = page.substring(1);
@@ -4663,13 +4530,12 @@
4663
4530
  }, 1000);
4664
4531
  }
4665
4532
  });
4666
- // MEMORY LEAK FIX: Store subscription unsubscribe functions
4667
- this.appManagerSubscriptions.push(this.appManager.subscribe('pageReady', () => {
4533
+ this.appManager.subscribe('pageReady', () => {
4668
4534
  onPageRendered();
4669
- }));
4670
- this.appManagerSubscriptions.push(this.appManager.subscribe('pageAttach', () => {
4535
+ });
4536
+ this.appManager.subscribe('pageAttach', () => {
4671
4537
  onPageRendered();
4672
- }));
4538
+ });
4673
4539
  }
4674
4540
  showOAuthDialog() {
4675
4541
  if (!this.isOAuthDialogOpen) {
@@ -4744,35 +4610,9 @@
4744
4610
  i1.$invokeWatchers();
4745
4611
  }
4746
4612
  ngOnDestroy() {
4747
- // MEMORY LEAK FIX: Unwatch all App-scoped watchers when app is destroyed
4748
- i1.$unwatchAllByScope('App');
4749
- // MEMORY LEAK FIX: Unsubscribe from navigation end subscription
4750
4613
  if (this.navigationEndSubscription) {
4751
4614
  this.navigationEndSubscription.unsubscribe();
4752
- this.navigationEndSubscription = null;
4753
4615
  }
4754
- // MEMORY LEAK FIX: Unsubscribe from OAuth providers subscription
4755
- if (this.oAuthProvidersSubscription) {
4756
- this.oAuthProvidersSubscription.unsubscribe();
4757
- this.oAuthProvidersSubscription = null;
4758
- }
4759
- // MEMORY LEAK FIX: Unsubscribe from spinner message subscription
4760
- if (this.spinnerMessageSubscription) {
4761
- this.spinnerMessageSubscription.unsubscribe();
4762
- this.spinnerMessageSubscription = null;
4763
- }
4764
- // MEMORY LEAK FIX: Unsubscribe from router events subscription
4765
- if (this.routerEventsSubscription) {
4766
- this.routerEventsSubscription.unsubscribe();
4767
- this.routerEventsSubscription = null;
4768
- }
4769
- // MEMORY LEAK FIX: Unsubscribe from appManager subscriptions
4770
- this.appManagerSubscriptions.forEach(unsubscribe => {
4771
- if (unsubscribe) {
4772
- unsubscribe();
4773
- }
4774
- });
4775
- this.appManagerSubscriptions = [];
4776
4616
  }
4777
4617
  static { this.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0__namespace, type: AppComponent, deps: [{ token: PipeProvider }, { token: i0__namespace.ApplicationRef }, { token: i0__namespace.ElementRef }, { token: i2$2__namespace.OAuthService }, { token: i1__namespace.AbstractDialogService }, { token: i1__namespace.AbstractSpinnerService }, { token: i0__namespace.NgZone }, { token: i1$1__namespace.Router }, { token: i1__namespace.App }, { token: AppManagerService }, { token: i1__namespace.CustomIconsLoaderService }], target: i0__namespace.ɵɵFactoryTarget.Component }); }
4778
4618
  static { this.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AppComponent, isStandalone: true, selector: "app-root", viewQueries: [{ propertyName: "routerOutlet", first: true, predicate: i1$1.RouterOutlet, descendants: true }, { propertyName: "dynamicComponentContainerRef", first: true, predicate: ["dynamicComponent"], descendants: true, read: i0.ViewContainerRef }], ngImport: i0__namespace, template: "@if (startApp) {\n @if(enableSkipToMainContent) {\n <div id=\"app-focus-start\" tabindex=\"-1\"></div>\n <a href=\"javascript:void(0);\" class=\"skip\" (click)=\"skipToAppContent($event)\">{{appLocale.LABEL_SKIP_TO_MAIN_CONTENT || 'Skip to main content'}}</a>\n }\n <router-outlet></router-outlet>\n @if (isApplicationType) {\n <div wmContainer partialContainer content=\"Common\" hidden class=\"ng-hide\"></div>\n }\n <app-spinner name=\"globalspinner\" classname=\"global-spinner\" role=\"alert\" aria-live=\"assertive\" [attr.aria-label]=\"spinner.arialabel || 'Loading'\" [show]=\"spinner.show\" [spinnermessages]=\"spinner.messages\"></app-spinner>\n <div wmDialog name=\"oAuthLoginDialog\" title=\"Application is requesting you to sign in with\"\n close.event=\"closeOAuthDialog()\">\n <ng-template #dialogBody>\n <ul class=\"list-items\">\n @for (provider of providersConfig; track provider) {\n <li class=\"list-item\">\n <button class=\"btn\" (click)=\"provider.invoke()\">{{provider.name}}</button>\n </li>\n }\n </ul>\n </ng-template>\n </div>\n <div wmConfirmDialog name=\"_app-confirm-dialog\" title.bind=\"title\" message.bind=\"message\" oktext.bind=\"oktext\"\n canceltext.bind=\"canceltext\" closable=\"false\" iconclass.bind=\"iconclass\"\n escape.event=\"onEscape()\" ok.event=\"onOk()\" cancel.event=\"onCancel()\" close.event=\"onClose()\" opened.event=\"onOpen()\"></div>\n @if (!isApplicationType) {\n <div wmConfirmDialog name=\"PrefabConfirmDialog\" title.bind=\"title\" message.bind=\"text\" oktext.bind=\"okButtonText\"\n canceltext.bind=\"cancelButtonText\" closable=\"false\" iconclass.bind=\"iconclass\"\n escape.event=\"onEscape()\" ok.event=\"onOk()\" cancel.event=\"onCancel()\" close.event=\"onClose()\" opened.event=\"onOpen()\"></div>\n }\n @if (!isApplicationType) {\n <div wmAlertDialog name=\"PrefabAlertDialog\" title.bind=\"title\" message.bind=\"text\" oktext.bind=\"okButtonText\"\n canceltext.bind=\"cancelButtonText\" closable=\"false\" iconclass.bind=\"iconclass\"\n escape.event=\"onEscape()\" ok.event=\"onOk()\" cancel.event=\"onCancel()\" close.event=\"onClose()\" opened.event=\"onOpen()\"></div>\n }\n <div wmAppExt></div>\n <i id=\"wm-mobile-display\"></i>\n}\n<!--Dummy container to create the component dynamically-->\n<ng-container #dynamicComponent></ng-container>\n", dependencies: [{ kind: "ngmodule", type: i5.CommonModule }, { kind: "directive", type: i1$1.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: alertDialog.AlertDialogComponent, selector: "div[wmAlertDialog]" }, { kind: "component", type: confirmDialog.ConfirmDialogComponent, selector: "div[wmConfirmDialog]" }, { kind: "component", type: designDialog.DialogComponent, selector: "div[wmDialog]" }, { kind: "component", type: AppSpinnerComponent, selector: "app-spinner", inputs: ["show", "spinnermessages", "classname", "arialabel"] }, { kind: "directive", type: base.ContainerDirective, selector: "[wmContainer]" }, { kind: "directive", type: base.PartialParamHandlerDirective, selector: "[partialContainer]" }, { kind: "directive", type: base.PartialContainerDirective, selector: "[partialContainer]" }], encapsulation: i0__namespace.ViewEncapsulation.None }); }
@@ -24,10 +24,6 @@ export declare class AppComponent implements DoCheck, AfterViewInit, OnDestroy {
24
24
  enableSkipToMainContent: boolean;
25
25
  private retryCount;
26
26
  private navigationEndSubscription;
27
- private oAuthProvidersSubscription;
28
- private spinnerMessageSubscription;
29
- private routerEventsSubscription;
30
- private appManagerSubscriptions;
31
27
  appLocale: any;
32
28
  routerOutlet: RouterOutlet;
33
29
  dynamicComponentContainerRef: ViewContainerRef;
@@ -4,7 +4,7 @@ import { ConfirmDialogComponent } from '@wm/components/dialogs/confirm-dialog';
4
4
  import { ApplicationRef, Component, ElementRef, NgZone, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
5
5
  import { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router, RouterOutlet } from '@angular/router';
6
6
  import { setTheme } from 'ngx-bootstrap/utils';
7
- import { $invokeWatchers, $unwatchAllByScope, AbstractDialogService, AbstractSpinnerService, addClass, App, CustomIconsLoaderService, getWmProjectProperties, noop, removeClass, setAppRef, setNgZone, setPipeProvider } from '@wm/core';
7
+ import { $invokeWatchers, AbstractDialogService, AbstractSpinnerService, addClass, App, CustomIconsLoaderService, getWmProjectProperties, noop, removeClass, setAppRef, setNgZone, setPipeProvider } from '@wm/core';
8
8
  import { OAuthService } from '@wm/oAuth';
9
9
  import { AppManagerService } from '../../services/app.manager.service';
10
10
  import { PipeProvider } from '../../services/pipe-provider.service';
@@ -32,7 +32,6 @@ export class AppComponent {
32
32
  this.isApplicationType = false;
33
33
  this.enableSkipToMainContent = getWmProjectProperties().enableSkipToMainContent === 'true' || getWmProjectProperties().enableSkipToMainContent === true;
34
34
  this.retryCount = 0;
35
- this.appManagerSubscriptions = []; // MEMORY LEAK FIX: Track appManager subscriptions
36
35
  this.appLocale = {};
37
36
  this.spinner = { show: false, messages: [], arialabel: '' };
38
37
  this.isOAuthDialogOpen = false;
@@ -45,8 +44,7 @@ export class AppComponent {
45
44
  this.customIconsLoaderService.load();
46
45
  }
47
46
  // subscribe to OAuth changes
48
- // MEMORY LEAK FIX: Store subscription reference for cleanup
49
- this.oAuthProvidersSubscription = oAuthService.getOAuthProvidersAsObservable().subscribe((providers) => {
47
+ oAuthService.getOAuthProvidersAsObservable().subscribe((providers) => {
50
48
  this.providersConfig = providers;
51
49
  if (providers.length) {
52
50
  this.showOAuthDialog();
@@ -56,8 +54,7 @@ export class AppComponent {
56
54
  }
57
55
  });
58
56
  // Subscribe to the message source to show/hide app spinner
59
- // MEMORY LEAK FIX: Store subscription reference for cleanup
60
- this.spinnerMessageSubscription = this.spinnerService.getMessageSource().asObservable().subscribe((data) => {
57
+ this.spinnerService.getMessageSource().asObservable().subscribe((data) => {
61
58
  // setTimeout is to avoid 'ExpressionChangedAfterItHasBeenCheckedError'
62
59
  setTimeout(() => {
63
60
  this.spinner.show = data.show;
@@ -69,8 +66,7 @@ export class AppComponent {
69
66
  setTheme('bs3');
70
67
  let spinnerId;
71
68
  let onPageRendered = noop;
72
- // MEMORY LEAK FIX: Store subscription reference for cleanup
73
- this.routerEventsSubscription = this.router.events.subscribe(e => {
69
+ this.router.events.subscribe(e => {
74
70
  if (e instanceof NavigationStart) {
75
71
  let page = e.url.split('?')[0];
76
72
  page = page.substring(1);
@@ -105,13 +101,12 @@ export class AppComponent {
105
101
  }, 1000);
106
102
  }
107
103
  });
108
- // MEMORY LEAK FIX: Store subscription unsubscribe functions
109
- this.appManagerSubscriptions.push(this.appManager.subscribe('pageReady', () => {
104
+ this.appManager.subscribe('pageReady', () => {
110
105
  onPageRendered();
111
- }));
112
- this.appManagerSubscriptions.push(this.appManager.subscribe('pageAttach', () => {
106
+ });
107
+ this.appManager.subscribe('pageAttach', () => {
113
108
  onPageRendered();
114
- }));
109
+ });
115
110
  }
116
111
  showOAuthDialog() {
117
112
  if (!this.isOAuthDialogOpen) {
@@ -186,35 +181,9 @@ export class AppComponent {
186
181
  $invokeWatchers();
187
182
  }
188
183
  ngOnDestroy() {
189
- // MEMORY LEAK FIX: Unwatch all App-scoped watchers when app is destroyed
190
- $unwatchAllByScope('App');
191
- // MEMORY LEAK FIX: Unsubscribe from navigation end subscription
192
184
  if (this.navigationEndSubscription) {
193
185
  this.navigationEndSubscription.unsubscribe();
194
- this.navigationEndSubscription = null;
195
- }
196
- // MEMORY LEAK FIX: Unsubscribe from OAuth providers subscription
197
- if (this.oAuthProvidersSubscription) {
198
- this.oAuthProvidersSubscription.unsubscribe();
199
- this.oAuthProvidersSubscription = null;
200
- }
201
- // MEMORY LEAK FIX: Unsubscribe from spinner message subscription
202
- if (this.spinnerMessageSubscription) {
203
- this.spinnerMessageSubscription.unsubscribe();
204
- this.spinnerMessageSubscription = null;
205
186
  }
206
- // MEMORY LEAK FIX: Unsubscribe from router events subscription
207
- if (this.routerEventsSubscription) {
208
- this.routerEventsSubscription.unsubscribe();
209
- this.routerEventsSubscription = null;
210
- }
211
- // MEMORY LEAK FIX: Unsubscribe from appManager subscriptions
212
- this.appManagerSubscriptions.forEach(unsubscribe => {
213
- if (unsubscribe) {
214
- unsubscribe();
215
- }
216
- });
217
- this.appManagerSubscriptions = [];
218
187
  }
219
188
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppComponent, deps: [{ token: i1.PipeProvider }, { token: i0.ApplicationRef }, { token: i0.ElementRef }, { token: i2.OAuthService }, { token: i3.AbstractDialogService }, { token: i3.AbstractSpinnerService }, { token: i0.NgZone }, { token: i4.Router }, { token: i3.App }, { token: i5.AppManagerService }, { token: i3.CustomIconsLoaderService }], target: i0.ɵɵFactoryTarget.Component }); }
220
189
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AppComponent, isStandalone: true, selector: "app-root", viewQueries: [{ propertyName: "routerOutlet", first: true, predicate: RouterOutlet, descendants: true }, { propertyName: "dynamicComponentContainerRef", first: true, predicate: ["dynamicComponent"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@if (startApp) {\n @if(enableSkipToMainContent) {\n <div id=\"app-focus-start\" tabindex=\"-1\"></div>\n <a href=\"javascript:void(0);\" class=\"skip\" (click)=\"skipToAppContent($event)\">{{appLocale.LABEL_SKIP_TO_MAIN_CONTENT || 'Skip to main content'}}</a>\n }\n <router-outlet></router-outlet>\n @if (isApplicationType) {\n <div wmContainer partialContainer content=\"Common\" hidden class=\"ng-hide\"></div>\n }\n <app-spinner name=\"globalspinner\" classname=\"global-spinner\" role=\"alert\" aria-live=\"assertive\" [attr.aria-label]=\"spinner.arialabel || 'Loading'\" [show]=\"spinner.show\" [spinnermessages]=\"spinner.messages\"></app-spinner>\n <div wmDialog name=\"oAuthLoginDialog\" title=\"Application is requesting you to sign in with\"\n close.event=\"closeOAuthDialog()\">\n <ng-template #dialogBody>\n <ul class=\"list-items\">\n @for (provider of providersConfig; track provider) {\n <li class=\"list-item\">\n <button class=\"btn\" (click)=\"provider.invoke()\">{{provider.name}}</button>\n </li>\n }\n </ul>\n </ng-template>\n </div>\n <div wmConfirmDialog name=\"_app-confirm-dialog\" title.bind=\"title\" message.bind=\"message\" oktext.bind=\"oktext\"\n canceltext.bind=\"canceltext\" closable=\"false\" iconclass.bind=\"iconclass\"\n escape.event=\"onEscape()\" ok.event=\"onOk()\" cancel.event=\"onCancel()\" close.event=\"onClose()\" opened.event=\"onOpen()\"></div>\n @if (!isApplicationType) {\n <div wmConfirmDialog name=\"PrefabConfirmDialog\" title.bind=\"title\" message.bind=\"text\" oktext.bind=\"okButtonText\"\n canceltext.bind=\"cancelButtonText\" closable=\"false\" iconclass.bind=\"iconclass\"\n escape.event=\"onEscape()\" ok.event=\"onOk()\" cancel.event=\"onCancel()\" close.event=\"onClose()\" opened.event=\"onOpen()\"></div>\n }\n @if (!isApplicationType) {\n <div wmAlertDialog name=\"PrefabAlertDialog\" title.bind=\"title\" message.bind=\"text\" oktext.bind=\"okButtonText\"\n canceltext.bind=\"cancelButtonText\" closable=\"false\" iconclass.bind=\"iconclass\"\n escape.event=\"onEscape()\" ok.event=\"onOk()\" cancel.event=\"onCancel()\" close.event=\"onClose()\" opened.event=\"onOpen()\"></div>\n }\n <div wmAppExt></div>\n <i id=\"wm-mobile-display\"></i>\n}\n<!--Dummy container to create the component dynamically-->\n<ng-container #dynamicComponent></ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AlertDialogComponent, selector: "div[wmAlertDialog]" }, { kind: "component", type: ConfirmDialogComponent, selector: "div[wmConfirmDialog]" }, { kind: "component", type: DialogComponent, selector: "div[wmDialog]" }, { kind: "component", type: AppSpinnerComponent, selector: "app-spinner", inputs: ["show", "spinnermessages", "classname", "arialabel"] }, { kind: "directive", type: ContainerDirective, selector: "[wmContainer]" }, { kind: "directive", type: PartialParamHandlerDirective, selector: "[partialContainer]" }, { kind: "directive", type: PartialContainerDirective, selector: "[partialContainer]" }], encapsulation: i0.ViewEncapsulation.None }); }
@@ -229,4 +198,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
229
198
  type: ViewChild,
230
199
  args: ['dynamicComponent', { read: ViewContainerRef }]
231
200
  }] } });
232
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3J1bnRpbWUtYmFzZS9zcmMvY29tcG9uZW50cy9hcHAtY29tcG9uZW50L2FwcC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ydW50aW1lLWJhc2Uvc3JjL2NvbXBvbmVudHMvYXBwLWNvbXBvbmVudC9hcHAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBQ3pFLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFFSCxjQUFjLEVBQ2QsU0FBUyxFQUVULFVBQVUsRUFDVixNQUFNLEVBRU4sU0FBUyxFQUNULGdCQUFnQixFQUNoQixpQkFBaUIsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUVILGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsZUFBZSxFQUNmLGVBQWUsRUFDZixNQUFNLEVBQ04sWUFBWSxFQUNmLE1BQU0saUJBQWlCLENBQUM7QUFFekIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRTdDLE9BQU8sRUFDSCxlQUFlLEVBQ2Ysa0JBQWtCLEVBQ2xCLHFCQUFxQixFQUNyQixzQkFBc0IsRUFDdEIsUUFBUSxFQUNSLEdBQUcsRUFDSCx3QkFBd0IsRUFDeEIsc0JBQXNCLEVBQ3RCLElBQUksRUFDSixXQUFXLEVBQ1gsU0FBUyxFQUNULFNBQVMsRUFDVCxlQUFlLEVBQ2xCLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxXQUFXLENBQUM7QUFDdkMsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sb0NB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QUFZLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLHNCQUFzQixFQUFFLGVBQWUsRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSw0QkFBNEIsRUFBRyx5QkFBeUIsQ0FBQyxZQUM3TCxVQUFVLGlCQUVMLGlCQUFpQixDQUFDLElBQUk7OFdBY1osWUFBWTtzQkFBcEMsU0FBUzt1QkFBQyxZQUFZO2dCQUVvQyw0QkFBNEI7c0JBQXRGLFNBQVM7dUJBQUMsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbW1vbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7QWxlcnREaWFsb2dDb21wb25lbnR9IGZyb20gJ0B3bS9jb21wb25lbnRzL2RpYWxvZ3MvYWxlcnQtZGlhbG9nJztcbmltcG9ydCB7Q29uZmlybURpYWxvZ0NvbXBvbmVudH0gZnJvbSAnQHdtL2NvbXBvbmVudHMvZGlhbG9ncy9jb25maXJtLWRpYWxvZyc7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQXBwbGljYXRpb25SZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIERvQ2hlY2ssXG4gICAgRWxlbWVudFJlZixcbiAgICBOZ1pvbmUsXG4gICAgT25EZXN0cm95LFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3Q29udGFpbmVyUmVmLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBBY3RpdmF0ZWRSb3V0ZSxcbiAgICBOYXZpZ2F0aW9uQ2FuY2VsLFxuICAgIE5hdmlnYXRpb25FbmQsXG4gICAgTmF2aWdhdGlvbkVycm9yLFxuICAgIE5hdmlnYXRpb25TdGFydCxcbiAgICBSb3V0ZXIsXG4gICAgUm91dGVyT3V0bGV0XG59IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7c2V0VGhlbWV9IGZyb20gJ25neC1ib290c3RyYXAvdXRpbHMnO1xuXG5pbXBvcnQge1xuICAgICRpbnZva2VXYXRjaGVycyxcbiAgICAkdW53YXRjaEFsbEJ5U2NvcGUsXG4gICAgQWJzdHJhY3REaWFsb2dTZXJ2aWNlLFxuICAgIEFic3RyYWN0U3Bpbm5lclNlcnZpY2UsXG4gICAgYWRkQ2xhc3MsXG4gICAgQXBwLFxuICAgIEN1c3RvbUljb25zTG9hZGVyU2VydmljZSxcbiAgICBnZXRXbVByb2plY3RQcm9wZXJ0aWVzLFxuICAgIG5vb3AsXG4gICAgcmVtb3ZlQ2xhc3MsXG4gICAgc2V0QXBwUmVmLFxuICAgIHNldE5nWm9uZSxcbiAgICBzZXRQaXBlUHJvdmlkZXJcbn0gZnJvbSAnQHdtL2NvcmUnO1xuaW1wb3J0IHtPQXV0aFNlcnZpY2V9IGZyb20gJ0B3bS9vQXV0aCc7XG5pbXBvcnQge0FwcE1hbmFnZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hcHAubWFuYWdlci5zZXJ2aWNlJztcbmltcG9ydCB7UGlwZVByb3ZpZGVyfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9waXBlLXByb3ZpZGVyLnNlcnZpY2UnO1xuaW1wb3J0IHtBcHBTcGlubmVyQ29tcG9uZW50fSBmcm9tICcuLi9hcHAtc3Bpbm5lci5jb21wb25lbnQnO1xuaW1wb3J0IHtEaWFsb2dDb21wb25lbnR9IGZyb20gJ0B3bS9jb21wb25lbnRzL2RpYWxvZ3MvZGVzaWduLWRpYWxvZyc7XG5pbXBvcnQge0NvbnRhaW5lckRpcmVjdGl2ZSwgUGFydGlhbENvbnRhaW5lckRpcmVjdGl2ZSwgUGFydGlhbFBhcmFtSGFuZGxlckRpcmVjdGl2ZX0gZnJvbSAnQHdtL2NvbXBvbmVudHMvYmFzZSc7XG5pbXBvcnQge2ZpbHRlcn0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQge1N1YnNjcmlwdGlvbn0gZnJvbSBcInJ4anNcIjtcblxuaW50ZXJmYWNlIFNQSU5ORVIge1xuICAgIHNob3c6IGJvb2xlYW47XG4gICAgbWVzc2FnZXM6IEFycmF5PHN0cmluZz47XG4gICAgYXJpYWxhYmVsOiBzdHJpbmc7XG59XG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJvdXRlck91dGxldCwgQWxlcnREaWFsb2dDb21wb25lbnQsIENvbmZpcm1EaWFsb2dDb21wb25lbnQsIERpYWxvZ0NvbXBvbmVudCwgQXBwU3Bpbm5lckNvbXBvbmVudCwgQ29udGFpbmVyRGlyZWN0aXZlLCBQYXJ0aWFsUGFyYW1IYW5kbGVyRGlyZWN0aXZlICwgUGFydGlhbENvbnRhaW5lckRpcmVjdGl2ZV0sXG4gICAgc2VsZWN0b3I6ICdhcHAtcm9vdCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2FwcC5jb21wb25lbnQuaHRtbCcsXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBBcHBDb21wb25lbnQgaW1wbGVtZW50cyBEb0NoZWNrLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAgIHB1YmxpYyBzdGFydEFwcCA9IGZhbHNlO1xuICAgIHB1YmxpYyBpc0FwcGxpY2F0aW9uVHlwZSA9IGZhbHNlO1xuICAgIHB1YmxpYyBlbmFibGVTa2lwVG9NYWluQ29udGVudCA9IGdldFdtUHJvamVjdFByb3BlcnRpZXMoKS5lbmFibGVTa2lwVG9NYWluQ29udGVudCA9PT0gJ3RydWUnIHx8IGdldFdtUHJvamVjdFByb3BlcnRpZXMoKS5lbmFibGVTa2lwVG9NYWluQ29udGVudCA9PT0gdHJ1ZTtcbiAgICBwcml2YXRlIHJldHJ5Q291bnQgPSAwO1xuICAgIHByaXZhdGUgbmF2aWdhdGlvbkVuZFN1YnNjcmlwdGlvbiE6IFN1YnNjcmlwdGlvbjtcbiAgICBwcml2YXRlIG9BdXRoUHJvdmlkZXJzU3Vic2NyaXB0aW9uITogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgc3Bpbm5lck1lc3NhZ2VTdWJzY3JpcHRpb24hOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSByb3V0ZXJFdmVudHNTdWJzY3JpcHRpb24hOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBhcHBNYW5hZ2VyU3Vic2NyaXB0aW9uczogQXJyYXk8KCkgPT4gdm9pZD4gPSBbXTsgLy8gTUVNT1JZIExFQUsgRklYOiBUcmFjayBhcHBNYW5hZ2VyIHN1YnNjcmlwdGlvbnNcbiAgICBhcHBMb2NhbGU6IGFueSA9IHt9O1xuXG4gICAgQFZpZXdDaGlsZChSb3V0ZXJPdXRsZXQpIHJvdXRlck91dGxldDogUm91dGVyT3V0bGV0O1xuXG4gICAgQFZpZXdDaGlsZCgnZHluYW1pY0NvbXBvbmVudCcsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KSBkeW5hbWljQ29tcG9uZW50Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmO1xuXG4gICAgc3Bpbm5lcjogU1BJTk5FUiA9IHsgc2hvdzogZmFsc2UsIG1lc3NhZ2VzOiBbXSwgYXJpYWxhYmVsOiAnJyB9O1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBfcGlwZVByb3ZpZGVyOiBQaXBlUHJvdmlkZXIsXG4gICAgICAgIF9hcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgICAgICBwcml2YXRlIGVsUmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIG9BdXRoU2VydmljZTogT0F1dGhTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGRpYWxvZ1NlcnZpY2U6IEFic3RyYWN0RGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBzcGlubmVyU2VydmljZTogQWJzdHJhY3RTcGlubmVyU2VydmljZSxcbiAgICAgICAgbmdab25lOiBOZ1pvbmUsXG4gICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHB1YmxpYyBhcHA6IEFwcCxcbiAgICAgICAgcHJpdmF0ZSBhcHBNYW5hZ2VyOiBBcHBNYW5hZ2VyU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjdXN0b21JY29uc0xvYWRlclNlcnZpY2U6IEN1c3RvbUljb25zTG9hZGVyU2VydmljZVxuICAgICkge1xuICAgICAgICBzZXRQaXBlUHJvdmlkZXIoX3BpcGVQcm92aWRlcik7XG4gICAgICAgIHNldE5nWm9uZShuZ1pvbmUpO1xuICAgICAgICBzZXRBcHBSZWYoX2FwcFJlZik7XG5cbiAgICAgICAgdGhpcy5hcHBMb2NhbGUgPSBhcHAuYXBwTG9jYWxlO1xuICAgICAgICB0aGlzLmlzQXBwbGljYXRpb25UeXBlID0gZ2V0V21Qcm9qZWN0UHJvcGVydGllcygpLnR5cGUgPT09ICdBUFBMSUNBVElPTic7XG4gICAgICAgIGlmICh0aGlzLmlzQXBwbGljYXRpb25UeXBlKSB7XG4gICAgICAgICAgICB0aGlzLmN1c3RvbUljb25zTG9hZGVyU2VydmljZS5sb2FkKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzdWJzY3JpYmUgdG8gT0F1dGggY2hhbmdlc1xuICAgICAgICAvLyBNRU1PUlkgTEVBSyBGSVg6IFN0b3JlIHN1YnNjcmlwdGlvbiByZWZlcmVuY2UgZm9yIGNsZWFudXBcbiAgICAgICAgdGhpcy5vQXV0aFByb3ZpZGVyc1N1YnNjcmlwdGlvbiA9IG9BdXRoU2VydmljZS5nZXRPQXV0aFByb3ZpZGVyc0FzT2JzZXJ2YWJsZSgpLnN1YnNjcmliZSgocHJvdmlkZXJzOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHRoaXMucHJvdmlkZXJzQ29uZmlnID0gcHJvdmlkZXJzO1xuICAgICAgICAgICAgaWYgKHByb3ZpZGVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dPQXV0aERpYWxvZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlT0F1dGhEaWFsb2coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3Vic2NyaWJlIHRvIHRoZSBtZXNzYWdlIHNvdXJjZSB0byBzaG93L2hpZGUgYXBwIHNwaW5uZXJcbiAgICAgICAgLy8gTUVNT1JZIExFQUsgRklYOiBTdG9yZSBzdWJzY3JpcHRpb24gcmVmZXJlbmNlIGZvciBjbGVhbnVwXG4gICAgICAgIHRoaXMuc3Bpbm5lck1lc3NhZ2VTdWJzY3JpcHRpb24gPSB0aGlzLnNwaW5uZXJTZXJ2aWNlLmdldE1lc3NhZ2VTb3VyY2UoKS5hc09ic2VydmFibGUoKS5zdWJzY3JpYmUoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gc2V0VGltZW91dCBpcyB0byBhdm9pZCAnRXhwcmVzc2lvbkNoYW5nZWRBZnRlckl0SGFzQmVlbkNoZWNrZWRFcnJvcidcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci5zaG93ID0gZGF0YS5zaG93O1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci5tZXNzYWdlcyA9IGRhdGEubWVzc2FnZXM7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLmFyaWFsYWJlbCA9IGRhdGEubWVzc2FnZXMudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBzZXQgdGhlbWUgdG8gYnMzIG9uIG5neC1ib290c3RyYXAuIFRoaXMgYXZvaWRzIHJ1bnRpbWUgY2FsY3VsYXRpb24gdG8gZGV0ZXJtaW5lIGJzIHRoZW1lLiBUaHVzIHJlc29sdmVzIHBlcmZvcm1hbmNlLlxuICAgICAgICBzZXRUaGVtZSgnYnMzJyk7XG5cbiAgICAgICAgbGV0IHNwaW5uZXJJZDtcblxuICAgICAgICBsZXQgb25QYWdlUmVuZGVyZWQgPSBub29wO1xuXG4gICAgICAgIC8vIE1FTU9SWSBMRUFLIEZJWDogU3RvcmUgc3Vic2NyaXB0aW9uIHJlZmVyZW5jZSBmb3IgY2xlYW51cFxuICAgICAgICB0aGlzLnJvdXRlckV2ZW50c1N1YnNjcmlwdGlvbiA9IHRoaXMucm91dGVyLmV2ZW50cy5zdWJzY3JpYmUoZSA9PiB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25TdGFydCkge1xuICAgICAgICAgICAgICAgIGxldCBwYWdlID0gZS51cmwuc3BsaXQoJz8nKVswXTtcbiAgICAgICAgICAgICAgICBwYWdlID0gcGFnZS5zdWJzdHJpbmcoMSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXBhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHAuYWN0aXZlTGF5b3V0TmFtZSA9ICcnO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcC5sYXlvdXRQYWdlcyA9IFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5hcHAuYWN0aXZlTGF5b3V0TmFtZSAmJiB0aGlzLmFwcC5sYXlvdXRQYWdlcyAmJiB0aGlzLmFwcC5sYXlvdXRQYWdlcy5sZW5ndGggJiYgdGhpcy5hcHAubGF5b3V0UGFnZXMuaW5jbHVkZXMocGFnZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lcklkID0gdGhpcy5zcGlubmVyU2VydmljZS5zaG93KCcnLCAnd21Sb3V0ZXJPdXRsZXQnLCAnJywgJ3dtUm91dGVyT3V0bGV0Jyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lcklkID0gdGhpcy5zcGlubmVyU2VydmljZS5zaG93KCcnLCAnZ2xvYmFsU3Bpbm5lcicpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdhcHAtcGFnZS1vdXRsZXQnKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgICAgICBpZiAobm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhub2RlLCAncGFnZS1sb2FkLWluLXByb2dyZXNzJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgcGFnZUxvYWRTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIG9uUGFnZVJlbmRlcmVkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXJTZXJ2aWNlLmhpZGUoc3Bpbm5lcklkKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2FwcC1wYWdlLW91dGxldCcpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Mobm9kZSwgJ3BhZ2UtbG9hZC1pbi1wcm9ncmVzcycpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG9uUGFnZVJlbmRlcmVkID0gbm9vcDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHAuYWN0aXZlUGFnZUxvYWRUaW1lID0gRGF0ZS5ub3coKSAtIHBhZ2VMb2FkU3RhcnRUaW1lO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kIHx8IGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uQ2FuY2VsIHx8IGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgb25QYWdlUmVuZGVyZWQoKTtcbiAgICAgICAgICAgICAgICB9LCAxMDAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIE1FTU9SWSBMRUFLIEZJWDogU3RvcmUgc3Vic2NyaXB0aW9uIHVuc3Vic2NyaWJlIGZ1bmN0aW9uc1xuICAgICAgICB0aGlzLmFwcE1hbmFnZXJTdWJzY3JpcHRpb25zLnB1c2godGhpcy5hcHBNYW5hZ2VyLnN1YnNjcmliZSgncGFnZVJlYWR5JywgKCkgPT4ge1xuICAgICAgICAgICAgb25QYWdlUmVuZGVyZWQoKTtcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLmFwcE1hbmFnZXJTdWJzY3JpcHRpb25zLnB1c2godGhpcy5hcHBNYW5hZ2VyLnN1YnNjcmliZSgncGFnZUF0dGFjaCcsICgpID0+IHtcbiAgICAgICAgICAgIG9uUGFnZVJlbmRlcmVkKCk7XG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBwcm92aWRlcnNDb25maWc7XG4gICAgaXNPQXV0aERpYWxvZ09wZW4gPSBmYWxzZTtcblxuICAgIHNob3dPQXV0aERpYWxvZygpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzT0F1dGhEaWFsb2dPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLmlzT0F1dGhEaWFsb2dPcGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKCdvQXV0aExvZ2luRGlhbG9nJywgdGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbG9zZU9BdXRoRGlhbG9nKCkge1xuICAgICAgICBpZiAodGhpcy5pc09BdXRoRGlhbG9nT3Blbikge1xuICAgICAgICAgICAgdGhpcy5pc09BdXRoRGlhbG9nT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kaWFsb2dTZXJ2aWNlLmNsb3NlKCdvQXV0aExvZ2luRGlhbG9nJywgdGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXJ0KCkge1xuICAgICAgICAvL3RvIGZpeCB0aGUgaXNzdWUgdGhhdCBoYXBwZW5zIG9ubHkgaW4gdGhlIGRldmVsb3BtZW50IG1vZGVcbiAgICAgICAgLy9FeHByZXNzaW9uQ2hhbmdlZEFmdGVySXRIYXNCZWVuQ2hlY2tlZEVycm9yXG4gICAgICAgIC8vZml4OiBodHRwczovL2Jsb2cuYW5ndWxhci11bml2ZXJzaXR5LmlvL2FuZ3VsYXItZGVidWdnaW5nL1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBcHAgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFwcC5keW5hbWljQ29tcG9uZW50Q29udGFpbmVyUmVmID0gdGhpcy5keW5hbWljQ29tcG9uZW50Q29udGFpbmVyUmVmO1xuICAgICAgICAgICAgdGhpcy5vdmVycmlkZVJvdXRlck91dGxldCgpO1xuICAgICAgICB9LCAxMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvdmVycmlkZVJvdXRlck91dGxldCgpIHtcbiAgICAgICAgLy9vdmVycmlkZSB0aGUgYXR0YWNoL2RldGFjaCBtZXRob2RzXG4gICAgICAgIGNvbnN0IG9BdHRhY2ggPSB0aGlzLnJvdXRlck91dGxldC5hdHRhY2g7XG4gICAgICAgIGNvbnN0IG9EZXRhY2ggPSB0aGlzLnJvdXRlck91dGxldC5kZXRhY2g7XG4gICAgICAgIHRoaXMucm91dGVyT3V0bGV0LmF0dGFjaCA9IChjb21wb25lbnRSZWY6IGFueSwgYWN0aXZhdGVkUm91dGU6ICBBY3RpdmF0ZWRSb3V0ZSkgPT4ge1xuICAgICAgICAgICAgb0F0dGFjaC5jYWxsKHRoaXMucm91dGVyT3V0bGV0LCBjb21wb25lbnRSZWYsIGFjdGl2YXRlZFJvdXRlKTtcbiAgICAgICAgICAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5uZ09uQXR0YWNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucm91dGVyT3V0bGV0LmRldGFjaCA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYXBwLmFjdGl2ZVBhZ2UubmdPbkRldGFjaCgpO1xuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50UmVmID0gb0RldGFjaC5jYWxsKHRoaXMucm91dGVyT3V0bGV0KTtcbiAgICAgICAgICAgIHJldHVybiBjb21wb25lbnRSZWY7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc2tpcFRvQXBwQ29udGVudChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5yZXRyeUNvdW50ID0gMDtcbiAgICAgICAgdGhpcy50cnlGb2N1c0NvbnRlbnQoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRyeUZvY3VzQ29udGVudCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29udGVudEVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmFwcC1wYWdlLWNvbnRlbnQnKSBhcyBIVE1MRWxlbWVudDtcblxuICAgICAgICBpZiAoY29udGVudEVsKSB7XG4gICAgICAgICAgICBjb250ZW50RWwuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpOyAvLyBFbnN1cmUgaXQncyBmb2N1c2FibGVcbiAgICAgICAgICAgIGNvbnRlbnRFbC5mb2N1cyh7IHByZXZlbnRTY3JvbGw6IGZhbHNlIH0pO1xuICAgICAgICAgICAgY29udGVudEVsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucmV0cnlDb3VudCA8IDEwKSB7XG4gICAgICAgICAgICB0aGlzLnJldHJ5Q291bnQrKztcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50cnlGb2N1c0NvbnRlbnQoKSwgMTAwKTsgLy8gUmV0cnkgZXZlcnkgMTAwbXNcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnbGFuZycsIGdldFdtUHJvamVjdFByb3BlcnRpZXMoKS5kZWZhdWx0TGFuZ3VhZ2UpO1xuICAgICAgICB0aGlzLnN0YXJ0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlU2tpcFRvTWFpbkNvbnRlbnQpIHtcbiAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uRW5kU3Vic2NyaXB0aW9uID0gdGhpcy5yb3V0ZXIuZXZlbnRzXG4gICAgICAgICAgICAgICAgLnBpcGUoZmlsdGVyKChlKSA9PiBlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1mb2N1cy1zdGFydCcpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nRG9DaGVjaygpIHtcbiAgICAgICAgJGludm9rZVdhdGNoZXJzKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIC8vIE1FTU9SWSBMRUFLIEZJWDogVW53YXRjaCBhbGwgQXBwLXNjb3BlZCB3YXRjaGVycyB3aGVuIGFwcCBpcyBkZXN0cm95ZWRcbiAgICAgICAgJHVud2F0Y2hBbGxCeVNjb3BlKCdBcHAnKTtcbiAgICAgICAgXG4gICAgICAgIC8vIE1FTU9SWSBMRUFLIEZJWDogVW5zdWJzY3JpYmUgZnJvbSBuYXZpZ2F0aW9uIGVuZCBzdWJzY3JpcHRpb25cbiAgICAgICAgaWYgKHRoaXMubmF2aWdhdGlvbkVuZFN1YnNjcmlwdGlvbil7XG4gICAgICAgICAgICB0aGlzLm5hdmlnYXRpb25FbmRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgIHRoaXMubmF2aWdhdGlvbkVuZFN1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNRU1PUlkgTEVBSyBGSVg6IFVuc3Vic2NyaWJlIGZyb20gT0F1dGggcHJvdmlkZXJzIHN1YnNjcmlwdGlvblxuICAgICAgICBpZiAodGhpcy5vQXV0aFByb3ZpZGVyc1N1YnNjcmlwdGlvbikge1xuICAgICAgICAgICAgdGhpcy5vQXV0aFByb3ZpZGVyc1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgdGhpcy5vQXV0aFByb3ZpZGVyc1N1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNRU1PUlkgTEVBSyBGSVg6IFVuc3Vic2NyaWJlIGZyb20gc3Bpbm5lciBtZXNzYWdlIHN1YnNjcmlwdGlvblxuICAgICAgICBpZiAodGhpcy5zcGlubmVyTWVzc2FnZVN1YnNjcmlwdGlvbikge1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyTWVzc2FnZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyTWVzc2FnZVN1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNRU1PUlkgTEVBSyBGSVg6IFVuc3Vic2NyaWJlIGZyb20gcm91dGVyIGV2ZW50cyBzdWJzY3JpcHRpb25cbiAgICAgICAgaWYgKHRoaXMucm91dGVyRXZlbnRzU3Vic2NyaXB0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnJvdXRlckV2ZW50c1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgdGhpcy5yb3V0ZXJFdmVudHNTdWJzY3JpcHRpb24gPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTUVNT1JZIExFQUsgRklYOiBVbnN1YnNjcmliZSBmcm9tIGFwcE1hbmFnZXIgc3Vic2NyaXB0aW9uc1xuICAgICAgICB0aGlzLmFwcE1hbmFnZXJTdWJzY3JpcHRpb25zLmZvckVhY2godW5zdWJzY3JpYmUgPT4ge1xuICAgICAgICAgICAgaWYgKHVuc3Vic2NyaWJlKSB7XG4gICAgICAgICAgICAgICAgdW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXBwTWFuYWdlclN1YnNjcmlwdGlvbnMgPSBbXTtcbiAgICB9XG59XG4iLCJAaWYgKHN0YXJ0QXBwKSB7XG4gICAgQGlmKGVuYWJsZVNraXBUb01haW5Db250ZW50KSB7XG4gICAgICAgIDxkaXYgaWQ9XCJhcHAtZm9jdXMtc3RhcnRcIiB0YWJpbmRleD1cIi0xXCI+PC9kaXY+XG4gICAgICAgIDxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMCk7XCIgY2xhc3M9XCJza2lwXCIgKGNsaWNrKT1cInNraXBUb0FwcENvbnRlbnQoJGV2ZW50KVwiPnt7YXBwTG9jYWxlLkxBQkVMX1NLSVBfVE9fTUFJTl9DT05URU5UIHx8ICdTa2lwIHRvIG1haW4gY29udGVudCd9fTwvYT5cbiAgICB9XG4gICAgPHJvdXRlci1vdXRsZXQ+PC9yb3V0ZXItb3V0bGV0PlxuICBAaWYgKGlzQXBwbGljYXRpb25UeXBlKSB7XG4gICAgPGRpdiB3bUNvbnRhaW5lciBwYXJ0aWFsQ29udGFpbmVyIGNvbnRlbnQ9XCJDb21tb25cIiBoaWRkZW4gY2xhc3M9XCJuZy1oaWRlXCI+PC9kaXY+XG4gIH1cbiAgPGFwcC1zcGlubmVyIG5hbWU9XCJnbG9iYWxzcGlubmVyXCIgY2xhc3NuYW1lPVwiZ2xvYmFsLXNwaW5uZXJcIiByb2xlPVwiYWxlcnRcIiBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIiBbYXR0ci5hcmlhLWxhYmVsXT1cInNwaW5uZXIuYXJpYWxhYmVsIHx8ICdMb2FkaW5nJ1wiIFtzaG93XT1cInNwaW5uZXIuc2hvd1wiIFtzcGlubmVybWVzc2FnZXNdPVwic3Bpbm5lci5tZXNzYWdlc1wiPjwvYXBwLXNwaW5uZXI+XG4gIDxkaXYgd21EaWFsb2cgbmFtZT1cIm9BdXRoTG9naW5EaWFsb2dcIiB0aXRsZT1cIkFwcGxpY2F0aW9uIGlzIHJlcXVlc3RpbmcgeW91IHRvIHNpZ24gaW4gd2l0aFwiXG4gICAgY2xvc2UuZXZlbnQ9XCJjbG9zZU9BdXRoRGlhbG9nKClcIj5cbiAgICA8bmctdGVtcGxhdGUgI2RpYWxvZ0JvZHk+XG4gICAgICA8dWwgY2xhc3M9XCJsaXN0LWl0ZW1zXCI+XG4gICAgICAgIEBmb3IgKHByb3ZpZGVyIG9mIHByb3ZpZGVyc0NvbmZpZzsgdHJhY2sgcHJvdmlkZXIpIHtcbiAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWl0ZW1cIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG5cIiAoY2xpY2spPVwicHJvdmlkZXIuaW52b2tlKClcIj57e3Byb3ZpZGVyLm5hbWV9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIH1cbiAgICAgIDwvdWw+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG4gIDxkaXYgd21Db25maXJtRGlhbG9nIG5hbWU9XCJfYXBwLWNvbmZpcm0tZGlhbG9nXCIgdGl0bGUuYmluZD1cInRpdGxlXCIgbWVzc2FnZS5iaW5kPVwibWVzc2FnZVwiIG9rdGV4dC5iaW5kPVwib2t0ZXh0XCJcbiAgICBjYW5jZWx0ZXh0LmJpbmQ9XCJjYW5jZWx0ZXh0XCIgY2xvc2FibGU9XCJmYWxzZVwiIGljb25jbGFzcy5iaW5kPVwiaWNvbmNsYXNzXCJcbiAgZXNjYXBlLmV2ZW50PVwib25Fc2NhcGUoKVwiIG9rLmV2ZW50PVwib25PaygpXCIgY2FuY2VsLmV2ZW50PVwib25DYW5jZWwoKVwiIGNsb3NlLmV2ZW50PVwib25DbG9zZSgpXCIgb3BlbmVkLmV2ZW50PVwib25PcGVuKClcIj48L2Rpdj5cbiAgQGlmICghaXNBcHBsaWNhdGlvblR5cGUpIHtcbiAgICA8ZGl2ICB3bUNvbmZpcm1EaWFsb2cgbmFtZT1cIlByZWZhYkNvbmZpcm1EaWFsb2dcIiB0aXRsZS5iaW5kPVwidGl0bGVcIiBtZXNzYWdlLmJpbmQ9XCJ0ZXh0XCIgb2t0ZXh0LmJpbmQ9XCJva0J1dHRvblRleHRcIlxuICAgICAgY2FuY2VsdGV4dC5iaW5kPVwiY2FuY2VsQnV0dG9uVGV4dFwiIGNsb3NhYmxlPVwiZmFsc2VcIiBpY29uY2xhc3MuYmluZD1cImljb25jbGFzc1wiXG4gICAgZXNjYXBlLmV2ZW50PVwib25Fc2NhcGUoKVwiIG9rLmV2ZW50PVwib25PaygpXCIgY2FuY2VsLmV2ZW50PVwib25DYW5jZWwoKVwiIGNsb3NlLmV2ZW50PVwib25DbG9zZSgpXCIgb3BlbmVkLmV2ZW50PVwib25PcGVuKClcIj48L2Rpdj5cbiAgfVxuICBAaWYgKCFpc0FwcGxpY2F0aW9uVHlwZSkge1xuICAgIDxkaXYgIHdtQWxlcnREaWFsb2cgbmFtZT1cIlByZWZhYkFsZXJ0RGlhbG9nXCIgdGl0bGUuYmluZD1cInRpdGxlXCIgbWVzc2FnZS5iaW5kPVwidGV4dFwiIG9rdGV4dC5iaW5kPVwib2tCdXR0b25UZXh0XCJcbiAgICAgIGNhbmNlbHRleHQuYmluZD1cImNhbmNlbEJ1dHRvblRleHRcIiBjbG9zYWJsZT1cImZhbHNlXCIgaWNvbmNsYXNzLmJpbmQ9XCJpY29uY2xhc3NcIlxuICAgIGVzY2FwZS5ldmVudD1cIm9uRXNjYXBlKClcIiBvay5ldmVudD1cIm9uT2soKVwiIGNhbmNlbC5ldmVudD1cIm9uQ2FuY2VsKClcIiBjbG9zZS5ldmVudD1cIm9uQ2xvc2UoKVwiIG9wZW5lZC5ldmVudD1cIm9uT3BlbigpXCI+PC9kaXY+XG4gIH1cbiAgPGRpdiB3bUFwcEV4dD48L2Rpdj5cbiAgPGkgaWQ9XCJ3bS1tb2JpbGUtZGlzcGxheVwiPjwvaT5cbn1cbjwhLS1EdW1teSBjb250YWluZXIgdG8gY3JlYXRlIHRoZSBjb21wb25lbnQgZHluYW1pY2FsbHktLT5cbjxuZy1jb250YWluZXIgI2R5bmFtaWNDb21wb25lbnQ+PC9uZy1jb250YWluZXI+XG4iXX0=
201
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3J1bnRpbWUtYmFzZS9zcmMvY29tcG9uZW50cy9hcHAtY29tcG9uZW50L2FwcC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ydW50aW1lLWJhc2Uvc3JjL2NvbXBvbmVudHMvYXBwLWNvbXBvbmVudC9hcHAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBQ3pFLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFFSCxjQUFjLEVBQ2QsU0FBUyxFQUVULFVBQVUsRUFDVixNQUFNLEVBRU4sU0FBUyxFQUNULGdCQUFnQixFQUNoQixpQkFBaUIsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUVILGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsZUFBZSxFQUNmLGVBQWUsRUFDZixNQUFNLEVBQ04sWUFBWSxFQUNmLE1BQU0saUJBQWlCLENBQUM7QUFFekIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRTdDLE9BQU8sRUFDSCxlQUFlLEVBQ2YscUJBQXFCLEVBQ3JCLHNCQUFzQixFQUN0QixRQUFRLEVBQ1IsR0FBRyxFQUNILHdCQUF3QixFQUN4QixzQkFBc0IsRUFDdEIsSUFBSSxFQUNKLFdBQVcsRUFDWCxTQUFTLEVBQ1QsU0FBUyxFQUNULGVBQWUsRUFDbEIsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUN2QyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUNy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QUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsNEJBQTRCLEVBQUcseUJBQXlCLENBQUMsWUFDN0wsVUFBVSxpQkFFTCxpQkFBaUIsQ0FBQyxJQUFJOzhXQVVaLFlBQVk7c0JBQXBDLFNBQVM7dUJBQUMsWUFBWTtnQkFFb0MsNEJBQTRCO3NCQUF0RixTQUFTO3VCQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb21tb25Nb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge0FsZXJ0RGlhbG9nQ29tcG9uZW50fSBmcm9tICdAd20vY29tcG9uZW50cy9kaWFsb2dzL2FsZXJ0LWRpYWxvZyc7XG5pbXBvcnQge0NvbmZpcm1EaWFsb2dDb21wb25lbnR9IGZyb20gJ0B3bS9jb21wb25lbnRzL2RpYWxvZ3MvY29uZmlybS1kaWFsb2cnO1xuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIEFwcGxpY2F0aW9uUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBEb0NoZWNrLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgTmdab25lLFxuICAgIE9uRGVzdHJveSxcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NvbnRhaW5lclJlZixcbiAgICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gICAgQWN0aXZhdGVkUm91dGUsXG4gICAgTmF2aWdhdGlvbkNhbmNlbCxcbiAgICBOYXZpZ2F0aW9uRW5kLFxuICAgIE5hdmlnYXRpb25FcnJvcixcbiAgICBOYXZpZ2F0aW9uU3RhcnQsXG4gICAgUm91dGVyLFxuICAgIFJvdXRlck91dGxldFxufSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG5pbXBvcnQge3NldFRoZW1lfSBmcm9tICduZ3gtYm9vdHN0cmFwL3V0aWxzJztcblxuaW1wb3J0IHtcbiAgICAkaW52b2tlV2F0Y2hlcnMsXG4gICAgQWJzdHJhY3REaWFsb2dTZXJ2aWNlLFxuICAgIEFic3RyYWN0U3Bpbm5lclNlcnZpY2UsXG4gICAgYWRkQ2xhc3MsXG4gICAgQXBwLFxuICAgIEN1c3RvbUljb25zTG9hZGVyU2VydmljZSxcbiAgICBnZXRXbVByb2plY3RQcm9wZXJ0aWVzLFxuICAgIG5vb3AsXG4gICAgcmVtb3ZlQ2xhc3MsXG4gICAgc2V0QXBwUmVmLFxuICAgIHNldE5nWm9uZSxcbiAgICBzZXRQaXBlUHJvdmlkZXJcbn0gZnJvbSAnQHdtL2NvcmUnO1xuaW1wb3J0IHtPQXV0aFNlcnZpY2V9IGZyb20gJ0B3bS9vQXV0aCc7XG5pbXBvcnQge0FwcE1hbmFnZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hcHAubWFuYWdlci5zZXJ2aWNlJztcbmltcG9ydCB7UGlwZVByb3ZpZGVyfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9waXBlLXByb3ZpZGVyLnNlcnZpY2UnO1xuaW1wb3J0IHtBcHBTcGlubmVyQ29tcG9uZW50fSBmcm9tICcuLi9hcHAtc3Bpbm5lci5jb21wb25lbnQnO1xuaW1wb3J0IHtEaWFsb2dDb21wb25lbnR9IGZyb20gJ0B3bS9jb21wb25lbnRzL2RpYWxvZ3MvZGVzaWduLWRpYWxvZyc7XG5pbXBvcnQge0NvbnRhaW5lckRpcmVjdGl2ZSwgUGFydGlhbENvbnRhaW5lckRpcmVjdGl2ZSwgUGFydGlhbFBhcmFtSGFuZGxlckRpcmVjdGl2ZX0gZnJvbSAnQHdtL2NvbXBvbmVudHMvYmFzZSc7XG5pbXBvcnQge2ZpbHRlcn0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQge1N1YnNjcmlwdGlvbn0gZnJvbSBcInJ4anNcIjtcblxuaW50ZXJmYWNlIFNQSU5ORVIge1xuICAgIHNob3c6IGJvb2xlYW47XG4gICAgbWVzc2FnZXM6IEFycmF5PHN0cmluZz47XG4gICAgYXJpYWxhYmVsOiBzdHJpbmc7XG59XG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJvdXRlck91dGxldCwgQWxlcnREaWFsb2dDb21wb25lbnQsIENvbmZpcm1EaWFsb2dDb21wb25lbnQsIERpYWxvZ0NvbXBvbmVudCwgQXBwU3Bpbm5lckNvbXBvbmVudCwgQ29udGFpbmVyRGlyZWN0aXZlLCBQYXJ0aWFsUGFyYW1IYW5kbGVyRGlyZWN0aXZlICwgUGFydGlhbENvbnRhaW5lckRpcmVjdGl2ZV0sXG4gICAgc2VsZWN0b3I6ICdhcHAtcm9vdCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2FwcC5jb21wb25lbnQuaHRtbCcsXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBBcHBDb21wb25lbnQgaW1wbGVtZW50cyBEb0NoZWNrLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAgIHB1YmxpYyBzdGFydEFwcCA9IGZhbHNlO1xuICAgIHB1YmxpYyBpc0FwcGxpY2F0aW9uVHlwZSA9IGZhbHNlO1xuICAgIHB1YmxpYyBlbmFibGVTa2lwVG9NYWluQ29udGVudCA9IGdldFdtUHJvamVjdFByb3BlcnRpZXMoKS5lbmFibGVTa2lwVG9NYWluQ29udGVudCA9PT0gJ3RydWUnIHx8IGdldFdtUHJvamVjdFByb3BlcnRpZXMoKS5lbmFibGVTa2lwVG9NYWluQ29udGVudCA9PT0gdHJ1ZTtcbiAgICBwcml2YXRlIHJldHJ5Q291bnQgPSAwO1xuICAgIHByaXZhdGUgbmF2aWdhdGlvbkVuZFN1YnNjcmlwdGlvbiE6IFN1YnNjcmlwdGlvbjtcbiAgICBhcHBMb2NhbGU6IGFueSA9IHt9O1xuXG4gICAgQFZpZXdDaGlsZChSb3V0ZXJPdXRsZXQpIHJvdXRlck91dGxldDogUm91dGVyT3V0bGV0O1xuXG4gICAgQFZpZXdDaGlsZCgnZHluYW1pY0NvbXBvbmVudCcsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KSBkeW5hbWljQ29tcG9uZW50Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmO1xuXG4gICAgc3Bpbm5lcjogU1BJTk5FUiA9IHsgc2hvdzogZmFsc2UsIG1lc3NhZ2VzOiBbXSwgYXJpYWxhYmVsOiAnJyB9O1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBfcGlwZVByb3ZpZGVyOiBQaXBlUHJvdmlkZXIsXG4gICAgICAgIF9hcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgICAgICBwcml2YXRlIGVsUmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIG9BdXRoU2VydmljZTogT0F1dGhTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGRpYWxvZ1NlcnZpY2U6IEFic3RyYWN0RGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBzcGlubmVyU2VydmljZTogQWJzdHJhY3RTcGlubmVyU2VydmljZSxcbiAgICAgICAgbmdab25lOiBOZ1pvbmUsXG4gICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHB1YmxpYyBhcHA6IEFwcCxcbiAgICAgICAgcHJpdmF0ZSBhcHBNYW5hZ2VyOiBBcHBNYW5hZ2VyU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjdXN0b21JY29uc0xvYWRlclNlcnZpY2U6IEN1c3RvbUljb25zTG9hZGVyU2VydmljZVxuICAgICkge1xuICAgICAgICBzZXRQaXBlUHJvdmlkZXIoX3BpcGVQcm92aWRlcik7XG4gICAgICAgIHNldE5nWm9uZShuZ1pvbmUpO1xuICAgICAgICBzZXRBcHBSZWYoX2FwcFJlZik7XG5cbiAgICAgICAgdGhpcy5hcHBMb2NhbGUgPSBhcHAuYXBwTG9jYWxlO1xuICAgICAgICB0aGlzLmlzQXBwbGljYXRpb25UeXBlID0gZ2V0V21Qcm9qZWN0UHJvcGVydGllcygpLnR5cGUgPT09ICdBUFBMSUNBVElPTic7XG4gICAgICAgIGlmICh0aGlzLmlzQXBwbGljYXRpb25UeXBlKSB7XG4gICAgICAgICAgICB0aGlzLmN1c3RvbUljb25zTG9hZGVyU2VydmljZS5sb2FkKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzdWJzY3JpYmUgdG8gT0F1dGggY2hhbmdlc1xuICAgICAgICBvQXV0aFNlcnZpY2UuZ2V0T0F1dGhQcm92aWRlcnNBc09ic2VydmFibGUoKS5zdWJzY3JpYmUoKHByb3ZpZGVyczogYW55KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVyc0NvbmZpZyA9IHByb3ZpZGVycztcbiAgICAgICAgICAgIGlmIChwcm92aWRlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93T0F1dGhEaWFsb2coKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZU9BdXRoRGlhbG9nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFN1YnNjcmliZSB0byB0aGUgbWVzc2FnZSBzb3VyY2UgdG8gc2hvdy9oaWRlIGFwcCBzcGlubmVyXG4gICAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2UuZ2V0TWVzc2FnZVNvdXJjZSgpLmFzT2JzZXJ2YWJsZSgpLnN1YnNjcmliZSgoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyBzZXRUaW1lb3V0IGlzIHRvIGF2b2lkICdFeHByZXNzaW9uQ2hhbmdlZEFmdGVySXRIYXNCZWVuQ2hlY2tlZEVycm9yJ1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnNob3cgPSBkYXRhLnNob3c7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLm1lc3NhZ2VzID0gZGF0YS5tZXNzYWdlcztcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIuYXJpYWxhYmVsID0gZGF0YS5tZXNzYWdlcy50b1N0cmluZygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIHNldCB0aGVtZSB0byBiczMgb24gbmd4LWJvb3RzdHJhcC4gVGhpcyBhdm9pZHMgcnVudGltZSBjYWxjdWxhdGlvbiB0byBkZXRlcm1pbmUgYnMgdGhlbWUuIFRodXMgcmVzb2x2ZXMgcGVyZm9ybWFuY2UuXG4gICAgICAgIHNldFRoZW1lKCdiczMnKTtcblxuICAgICAgICBsZXQgc3Bpbm5lcklkO1xuXG4gICAgICAgIGxldCBvblBhZ2VSZW5kZXJlZCA9IG5vb3A7XG5cbiAgICAgICAgdGhpcy5yb3V0ZXIuZXZlbnRzLnN1YnNjcmliZShlID0+IHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgTmF2aWdhdGlvblN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgbGV0IHBhZ2UgPSBlLnVybC5zcGxpdCgnPycpWzBdO1xuICAgICAgICAgICAgICAgIHBhZ2UgPSBwYWdlLnN1YnN0cmluZygxKTtcblxuICAgICAgICAgICAgICAgIGlmICghcGFnZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcC5hY3RpdmVMYXlvdXROYW1lID0gJyc7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwLmxheW91dFBhZ2VzID0gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmFwcC5hY3RpdmVMYXlvdXROYW1lICYmIHRoaXMuYXBwLmxheW91dFBhZ2VzICYmIHRoaXMuYXBwLmxheW91dFBhZ2VzLmxlbmd0aCAmJiB0aGlzLmFwcC5sYXlvdXRQYWdlcy5pbmNsdWRlcyhwYWdlKSkge1xuICAgICAgICAgICAgICAgICAgICBzcGlubmVySWQgPSB0aGlzLnNwaW5uZXJTZXJ2aWNlLnNob3coJycsICd3bVJvdXRlck91dGxldCcsICcnLCAnd21Sb3V0ZXJPdXRsZXQnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzcGlubmVySWQgPSB0aGlzLnNwaW5uZXJTZXJ2aWNlLnNob3coJycsICdnbG9iYWxTcGlubmVyJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2FwcC1wYWdlLW91dGxldCcpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKG5vZGUsICdwYWdlLWxvYWQtaW4tcHJvZ3Jlc3MnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwYWdlTG9hZFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgb25QYWdlUmVuZGVyZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2UuaGlkZShzcGlubmVySWQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYXBwLXBhZ2Utb3V0bGV0JykgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhub2RlLCAncGFnZS1sb2FkLWluLXByb2dyZXNzJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb25QYWdlUmVuZGVyZWQgPSBub29wO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcC5hY3RpdmVQYWdlTG9hZFRpbWUgPSBEYXRlLm5vdygpIC0gcGFnZUxvYWRTdGFydFRpbWU7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQgfHwgZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25DYW5jZWwgfHwgZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25FcnJvcikge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvblBhZ2VSZW5kZXJlZCgpO1xuICAgICAgICAgICAgICAgIH0sIDEwMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hcHBNYW5hZ2VyLnN1YnNjcmliZSgncGFnZVJlYWR5JywgKCkgPT4ge1xuICAgICAgICAgICAgb25QYWdlUmVuZGVyZWQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXBwTWFuYWdlci5zdWJzY3JpYmUoJ3BhZ2VBdHRhY2gnLCAoKSA9PiB7XG4gICAgICAgICAgICBvblBhZ2VSZW5kZXJlZCgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm92aWRlcnNDb25maWc7XG4gICAgaXNPQXV0aERpYWxvZ09wZW4gPSBmYWxzZTtcblxuICAgIHNob3dPQXV0aERpYWxvZygpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzT0F1dGhEaWFsb2dPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLmlzT0F1dGhEaWFsb2dPcGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKCdvQXV0aExvZ2luRGlhbG9nJywgdGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbG9zZU9BdXRoRGlhbG9nKCkge1xuICAgICAgICBpZiAodGhpcy5pc09BdXRoRGlhbG9nT3Blbikge1xuICAgICAgICAgICAgdGhpcy5pc09BdXRoRGlhbG9nT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kaWFsb2dTZXJ2aWNlLmNsb3NlKCdvQXV0aExvZ2luRGlhbG9nJywgdGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXJ0KCkge1xuICAgICAgICAvL3RvIGZpeCB0aGUgaXNzdWUgdGhhdCBoYXBwZW5zIG9ubHkgaW4gdGhlIGRldmVsb3BtZW50IG1vZGVcbiAgICAgICAgLy9FeHByZXNzaW9uQ2hhbmdlZEFmdGVySXRIYXNCZWVuQ2hlY2tlZEVycm9yXG4gICAgICAgIC8vZml4OiBodHRwczovL2Jsb2cuYW5ndWxhci11bml2ZXJzaXR5LmlvL2FuZ3VsYXItZGVidWdnaW5nL1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBcHAgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFwcC5keW5hbWljQ29tcG9uZW50Q29udGFpbmVyUmVmID0gdGhpcy5keW5hbWljQ29tcG9uZW50Q29udGFpbmVyUmVmO1xuICAgICAgICAgICAgdGhpcy5vdmVycmlkZVJvdXRlck91dGxldCgpO1xuICAgICAgICB9LCAxMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvdmVycmlkZVJvdXRlck91dGxldCgpIHtcbiAgICAgICAgLy9vdmVycmlkZSB0aGUgYXR0YWNoL2RldGFjaCBtZXRob2RzXG4gICAgICAgIGNvbnN0IG9BdHRhY2ggPSB0aGlzLnJvdXRlck91dGxldC5hdHRhY2g7XG4gICAgICAgIGNvbnN0IG9EZXRhY2ggPSB0aGlzLnJvdXRlck91dGxldC5kZXRhY2g7XG4gICAgICAgIHRoaXMucm91dGVyT3V0bGV0LmF0dGFjaCA9IChjb21wb25lbnRSZWY6IGFueSwgYWN0aXZhdGVkUm91dGU6ICBBY3RpdmF0ZWRSb3V0ZSkgPT4ge1xuICAgICAgICAgICAgb0F0dGFjaC5jYWxsKHRoaXMucm91dGVyT3V0bGV0LCBjb21wb25lbnRSZWYsIGFjdGl2YXRlZFJvdXRlKTtcbiAgICAgICAgICAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5uZ09uQXR0YWNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucm91dGVyT3V0bGV0LmRldGFjaCA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYXBwLmFjdGl2ZVBhZ2UubmdPbkRldGFjaCgpO1xuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50UmVmID0gb0RldGFjaC5jYWxsKHRoaXMucm91dGVyT3V0bGV0KTtcbiAgICAgICAgICAgIHJldHVybiBjb21wb25lbnRSZWY7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc2tpcFRvQXBwQ29udGVudChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5yZXRyeUNvdW50ID0gMDtcbiAgICAgICAgdGhpcy50cnlGb2N1c0NvbnRlbnQoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRyeUZvY3VzQ29udGVudCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29udGVudEVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmFwcC1wYWdlLWNvbnRlbnQnKSBhcyBIVE1MRWxlbWVudDtcblxuICAgICAgICBpZiAoY29udGVudEVsKSB7XG4gICAgICAgICAgICBjb250ZW50RWwuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpOyAvLyBFbnN1cmUgaXQncyBmb2N1c2FibGVcbiAgICAgICAgICAgIGNvbnRlbnRFbC5mb2N1cyh7IHByZXZlbnRTY3JvbGw6IGZhbHNlIH0pO1xuICAgICAgICAgICAgY29udGVudEVsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucmV0cnlDb3VudCA8IDEwKSB7XG4gICAgICAgICAgICB0aGlzLnJldHJ5Q291bnQrKztcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50cnlGb2N1c0NvbnRlbnQoKSwgMTAwKTsgLy8gUmV0cnkgZXZlcnkgMTAwbXNcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnbGFuZycsIGdldFdtUHJvamVjdFByb3BlcnRpZXMoKS5kZWZhdWx0TGFuZ3VhZ2UpO1xuICAgICAgICB0aGlzLnN0YXJ0KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlU2tpcFRvTWFpbkNvbnRlbnQpIHtcbiAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uRW5kU3Vic2NyaXB0aW9uID0gdGhpcy5yb3V0ZXIuZXZlbnRzXG4gICAgICAgICAgICAgICAgLnBpcGUoZmlsdGVyKChlKSA9PiBlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcC1mb2N1cy1zdGFydCcpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nRG9DaGVjaygpIHtcbiAgICAgICAgJGludm9rZVdhdGNoZXJzKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIGlmICh0aGlzLm5hdmlnYXRpb25FbmRTdWJzY3JpcHRpb24pe1xuICAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uRW5kU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJAaWYgKHN0YXJ0QXBwKSB7XG4gICAgQGlmKGVuYWJsZVNraXBUb01haW5Db250ZW50KSB7XG4gICAgICAgIDxkaXYgaWQ9XCJhcHAtZm9jdXMtc3RhcnRcIiB0YWJpbmRleD1cIi0xXCI+PC9kaXY+XG4gICAgICAgIDxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMCk7XCIgY2xhc3M9XCJza2lwXCIgKGNsaWNrKT1cInNraXBUb0FwcENvbnRlbnQoJGV2ZW50KVwiPnt7YXBwTG9jYWxlLkxBQkVMX1NLSVBfVE9fTUFJTl9DT05URU5UIHx8ICdTa2lwIHRvIG1haW4gY29udGVudCd9fTwvYT5cbiAgICB9XG4gICAgPHJvdXRlci1vdXRsZXQ+PC9yb3V0ZXItb3V0bGV0PlxuICBAaWYgKGlzQXBwbGljYXRpb25UeXBlKSB7XG4gICAgPGRpdiB3bUNvbnRhaW5lciBwYXJ0aWFsQ29udGFpbmVyIGNvbnRlbnQ9XCJDb21tb25cIiBoaWRkZW4gY2xhc3M9XCJuZy1oaWRlXCI+PC9kaXY+XG4gIH1cbiAgPGFwcC1zcGlubmVyIG5hbWU9XCJnbG9iYWxzcGlubmVyXCIgY2xhc3NuYW1lPVwiZ2xvYmFsLXNwaW5uZXJcIiByb2xlPVwiYWxlcnRcIiBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIiBbYXR0ci5hcmlhLWxhYmVsXT1cInNwaW5uZXIuYXJpYWxhYmVsIHx8ICdMb2FkaW5nJ1wiIFtzaG93XT1cInNwaW5uZXIuc2hvd1wiIFtzcGlubmVybWVzc2FnZXNdPVwic3Bpbm5lci5tZXNzYWdlc1wiPjwvYXBwLXNwaW5uZXI+XG4gIDxkaXYgd21EaWFsb2cgbmFtZT1cIm9BdXRoTG9naW5EaWFsb2dcIiB0aXRsZT1cIkFwcGxpY2F0aW9uIGlzIHJlcXVlc3RpbmcgeW91IHRvIHNpZ24gaW4gd2l0aFwiXG4gICAgY2xvc2UuZXZlbnQ9XCJjbG9zZU9BdXRoRGlhbG9nKClcIj5cbiAgICA8bmctdGVtcGxhdGUgI2RpYWxvZ0JvZHk+XG4gICAgICA8dWwgY2xhc3M9XCJsaXN0LWl0ZW1zXCI+XG4gICAgICAgIEBmb3IgKHByb3ZpZGVyIG9mIHByb3ZpZGVyc0NvbmZpZzsgdHJhY2sgcHJvdmlkZXIpIHtcbiAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWl0ZW1cIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG5cIiAoY2xpY2spPVwicHJvdmlkZXIuaW52b2tlKClcIj57e3Byb3ZpZGVyLm5hbWV9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIH1cbiAgICAgIDwvdWw+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG4gIDxkaXYgd21Db25maXJtRGlhbG9nIG5hbWU9XCJfYXBwLWNvbmZpcm0tZGlhbG9nXCIgdGl0bGUuYmluZD1cInRpdGxlXCIgbWVzc2FnZS5iaW5kPVwibWVzc2FnZVwiIG9rdGV4dC5iaW5kPVwib2t0ZXh0XCJcbiAgICBjYW5jZWx0ZXh0LmJpbmQ9XCJjYW5jZWx0ZXh0XCIgY2xvc2FibGU9XCJmYWxzZVwiIGljb25jbGFzcy5iaW5kPVwiaWNvbmNsYXNzXCJcbiAgZXNjYXBlLmV2ZW50PVwib25Fc2NhcGUoKVwiIG9rLmV2ZW50PVwib25PaygpXCIgY2FuY2VsLmV2ZW50PVwib25DYW5jZWwoKVwiIGNsb3NlLmV2ZW50PVwib25DbG9zZSgpXCIgb3BlbmVkLmV2ZW50PVwib25PcGVuKClcIj48L2Rpdj5cbiAgQGlmICghaXNBcHBsaWNhdGlvblR5cGUpIHtcbiAgICA8ZGl2ICB3bUNvbmZpcm1EaWFsb2cgbmFtZT1cIlByZWZhYkNvbmZpcm1EaWFsb2dcIiB0aXRsZS5iaW5kPVwidGl0bGVcIiBtZXNzYWdlLmJpbmQ9XCJ0ZXh0XCIgb2t0ZXh0LmJpbmQ9XCJva0J1dHRvblRleHRcIlxuICAgICAgY2FuY2VsdGV4dC5iaW5kPVwiY2FuY2VsQnV0dG9uVGV4dFwiIGNsb3NhYmxlPVwiZmFsc2VcIiBpY29uY2xhc3MuYmluZD1cImljb25jbGFzc1wiXG4gICAgZXNjYXBlLmV2ZW50PVwib25Fc2NhcGUoKVwiIG9rLmV2ZW50PVwib25PaygpXCIgY2FuY2VsLmV2ZW50PVwib25DYW5jZWwoKVwiIGNsb3NlLmV2ZW50PVwib25DbG9zZSgpXCIgb3BlbmVkLmV2ZW50PVwib25PcGVuKClcIj48L2Rpdj5cbiAgfVxuICBAaWYgKCFpc0FwcGxpY2F0aW9uVHlwZSkge1xuICAgIDxkaXYgIHdtQWxlcnREaWFsb2cgbmFtZT1cIlByZWZhYkFsZXJ0RGlhbG9nXCIgdGl0bGUuYmluZD1cInRpdGxlXCIgbWVzc2FnZS5iaW5kPVwidGV4dFwiIG9rdGV4dC5iaW5kPVwib2tCdXR0b25UZXh0XCJcbiAgICAgIGNhbmNlbHRleHQuYmluZD1cImNhbmNlbEJ1dHRvblRleHRcIiBjbG9zYWJsZT1cImZhbHNlXCIgaWNvbmNsYXNzLmJpbmQ9XCJpY29uY2xhc3NcIlxuICAgIGVzY2FwZS5ldmVudD1cIm9uRXNjYXBlKClcIiBvay5ldmVudD1cIm9uT2soKVwiIGNhbmNlbC5ldmVudD1cIm9uQ2FuY2VsKClcIiBjbG9zZS5ldmVudD1cIm9uQ2xvc2UoKVwiIG9wZW5lZC5ldmVudD1cIm9uT3BlbigpXCI+PC9kaXY+XG4gIH1cbiAgPGRpdiB3bUFwcEV4dD48L2Rpdj5cbiAgPGkgaWQ9XCJ3bS1tb2JpbGUtZGlzcGxheVwiPjwvaT5cbn1cbjwhLS1EdW1teSBjb250YWluZXIgdG8gY3JlYXRlIHRoZSBjb21wb25lbnQgZHluYW1pY2FsbHktLT5cbjxuZy1jb250YWluZXIgI2R5bmFtaWNDb21wb25lbnQ+PC9uZy1jb250YWluZXI+XG4iXX0=