UNPKG

@netgrif/components-core

Version:

Netgrif Application engine frontend core Angular library

422 lines 55.7 kB
import { Breakpoints } from '@angular/cdk/layout'; import { Component, EventEmitter, Input, Output } from '@angular/core'; import { filter, take } from 'rxjs/operators'; import { NAE_ROUTING_CONFIGURATION_PATH } from '../../routing/routing-builder/routing-builder.service'; import { PathService } from '../service/path.service'; import { LEFT_DRAWER_DEFAULT_WIDTH, RIGHT_DRAWER_DEFAULT_MIN_WIDTH, RIGHT_DRAWER_DEFAULT_WIDTH, RIGHT_DRAWER_MAX_WIDTH, } from '../model/navigation-configs'; import { GroupNavigationConstants } from "../model/group-navigation-constants"; import { extractFieldValueFromData } from "../utility/navigation-item-task-utility-methods"; import { LoadingEmitter } from "../../utility/loading-emitter"; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "@angular/cdk/layout"; import * as i3 from "../../translate/language.service"; import * as i4 from "@ngx-translate/core"; import * as i5 from "../../user/services/user.service"; import * as i6 from "../../logger/services/logger.service"; import * as i7 from "../../configuration/configuration.service"; import * as i8 from "../service/path.service"; import * as i9 from "../../resources/engine-endpoint/case-resource.service"; import * as i10 from "../../impersonation/services/impersonation-user-select.service"; import * as i11 from "../../impersonation/services/impersonation.service"; import * as i12 from "./service/double-drawer-navigation.service"; export class AbstractNavigationDoubleDrawerComponent { _router; _activatedRoute; _breakpoint; _languageService; _translateService; _userService; _log; _config; _pathService; _caseResourceService; _impersonationUserSelect; _impersonation; _navigationService; portalLeftMenu; portalRightMenu; imageRouterLink = '/'; imageAlt = 'Logo'; image; profileRouterLink = '/profile'; includeUser = true; includeLanguage = true; includeMoreMenu = true; includeImpersonation = true; allClosable = true; folderIcon = 'folder'; openedFolderIcon = 'folder_open'; filterIcon = 'filter_alt'; foldersCategoryName = 'toolbar.menu.folders'; viewsCategoryName = 'toolbar.menu.views'; loggedOut = new EventEmitter(true); // on logout stateChanged = new EventEmitter(); // on menu state change itemClicked = new EventEmitter(); // on item click resized = new EventEmitter(true); // on menu resize itemLoaded = new EventEmitter(true); // on item loaded hideMoreMenu; _breakpointSubscription; _currentNodeSubscription; _currentPathSubscription; _loggedUserSubscription; /** * Currently display Path * Siblings of the node are on the left, children are on the right */ _currentPath; _pathResolverLoading$; _configLeftMenu = { mode: 'side', opened: true, disableClose: false, width: LEFT_DRAWER_DEFAULT_WIDTH, }; _configRightMenu = { mode: 'side', opened: true, disableClose: false, width: RIGHT_DRAWER_DEFAULT_WIDTH, }; configUrl; constructor(_router, _activatedRoute, _breakpoint, _languageService, _translateService, _userService, _log, _config, _pathService, _caseResourceService, _impersonationUserSelect, _impersonation, _navigationService) { this._router = _router; this._activatedRoute = _activatedRoute; this._breakpoint = _breakpoint; this._languageService = _languageService; this._translateService = _translateService; this._userService = _userService; this._log = _log; this._config = _config; this._pathService = _pathService; this._caseResourceService = _caseResourceService; this._impersonationUserSelect = _impersonationUserSelect; this._impersonation = _impersonation; this._navigationService = _navigationService; let configUrl = this._config.getServicesConfiguration()?.doubleDrawer?.url; if (configUrl !== undefined && !configUrl.startsWith('/')) { configUrl = '/' + configUrl; } this.configUrl = configUrl; this.hideMoreMenu = true; this._navigationService.itemClicked$.subscribe((itemClickEvent) => { this.itemClicked.emit(itemClickEvent); }); this._navigationService.itemLoaded$.subscribe((itemLoadedEvent) => { this.itemLoaded.emit(itemLoadedEvent); }); this._pathResolverLoading$ = new LoadingEmitter(); } ngOnInit() { this._breakpointSubscription = this._breakpoint.observe([Breakpoints.HandsetLandscape]).subscribe(() => { if (this._breakpoint.isMatched('(max-width: 959.99px)')) { this.resolveLayout(false); } else { this.resolveLayout(true); } }); this._userService.user$.pipe(filter(u => !!u && u.id !== ''), take(1)).subscribe(() => { this.resolveInitialValueOfPath(); this._currentPathSubscription = this._pathService.activePath$.subscribe(path => { if (path !== this.currentPath && !this._pathResolverLoading$.isActive) { this.currentPath = path; } else if (!this._pathResolverLoading$.isActive) { this.openAvailableView(); } }); if (this.canApplyAutoSelect()) { this.rightItems$.pipe(filter(rightItems => rightItems.length > 0), take(1)).subscribe(() => { this.openAvailableView(); }); } const viewConfigurationPath = this._activatedRoute.snapshot.data[NAE_ROUTING_CONFIGURATION_PATH]; if (!!viewConfigurationPath) { const viewConfiguration = this._config.getViewByPath(viewConfigurationPath); this._navigationService.initializeCustomViewsOfView(viewConfiguration, viewConfigurationPath); } this.hiddenCustomItems$.subscribe(hiddenCustomItems => { this.hideMoreMenu = !hiddenCustomItems?.length; }); }); } ngOnDestroy() { this._breakpointSubscription?.unsubscribe(); this.loggedOut.complete(); this.stateChanged.complete(); this.itemClicked.complete(); this.resized.complete(); this.itemLoaded.complete(); this._currentNodeSubscription?.unsubscribe(); this._currentPathSubscription?.unsubscribe(); this._loggedUserSubscription?.unsubscribe(); } get currentPath() { return this._navigationService.currentPath; } set currentPath(node) { this._navigationService.currentPath = node; } get configLeftMenu() { return this._configLeftMenu; } get configRightMenu() { return this._configRightMenu; } get leftItems$() { return this._navigationService.leftItems$; } get leftItems() { return this._navigationService.leftItems; } get rightItems$() { return this._navigationService.rightItems$; } get rightItems() { return this._navigationService.rightItems; } get moreItems$() { return this._navigationService.moreItems$; } get moreItems() { return this._navigationService.moreItems; } get hiddenCustomItems$() { return this._navigationService.hiddenCustomItems$; } get hiddenCustomItems() { return this._navigationService.hiddenCustomItems; } get leftLoading$() { return this._navigationService.leftLoading$; } get rightLoading$() { return this._navigationService.rightLoading$; } get pathResolverLoading$() { return this._pathResolverLoading$; } toggleMenu() { this.toggleRightMenu(); if (this.allClosable) { this.toggleLeftMenu(); } } toggleLeftMenu() { this._configLeftMenu.opened = !this._configLeftMenu.opened; this.stateChanged.emit({ menu: 'left', isOpened: this._configLeftMenu.opened }); } toggleRightMenu() { this._configRightMenu.opened = !this._configRightMenu.opened; this.stateChanged.emit({ menu: 'right', isOpened: this._configRightMenu.opened }); } getLang() { return this._languageService.getLanguage(); } logout() { this._userService.logout().subscribe(response => { this._log.debug('User is logged out'); this.loggedOut.emit(response); if (this._config.get().services && this._config.get().services.auth && this._config.getOnLogoutPath()) { const redirectPath = this._config.getOnLogoutPath(); this._log.info('Redirecting to ' + redirectPath); this._router.navigate([redirectPath]); } }); } impersonate() { this._impersonationUserSelect.selectImpersonate(); } stopImpersonating() { this._impersonation.cease(); } get user() { return this._userService.user; } get canGoBackLoading$() { return this._navigationService.canGoBackLoading$; } /** * On home click, the current level is set to 0, and current parent is * set to root node. * */ onHomeClick() { this._navigationService.onHomeClick(); } /** * On back click, the parent is set to parent of left nodes, that will solve * the right side menu (elements that were in left side, after backward * navigation will be on the right side). * Current level is set to a lower number in order to set the left side menu. * */ onBackClick() { this._navigationService.onBackClick(); } onItemClick(item) { this._navigationService.onItemClick(item); } loadMoreItems() { this._navigationService.loadMoreItems(); } isAscending() { return this._navigationService.isAscending(); } switchOrder() { this._navigationService.switchOrder(); } /** * Function to check whether the back button should be displayed * @returns boolean if the back button should be displayed * */ isOnZeroLevel() { return this.currentPath === PathService.SEPARATOR; } isItemAndPathEqual(item, path) { return item.resource?.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_NODE_PATH)?.value === path; } isLeftItemsEmpty() { return this._navigationService.leftItems === undefined || this._navigationService.leftItems.length === 0; } isRightItemsEmpty() { return this._navigationService.rightItems === undefined || this._navigationService.rightItems.length === 0; } itemsTrackBy(index, item) { return item.id; } onResizeEvent(event) { if (event.rectangle.width > RIGHT_DRAWER_MAX_WIDTH) { this._configRightMenu.width = RIGHT_DRAWER_MAX_WIDTH; } else if (event.rectangle.width < RIGHT_DRAWER_DEFAULT_MIN_WIDTH) { this._configRightMenu.width = RIGHT_DRAWER_DEFAULT_MIN_WIDTH; } else { this._configRightMenu.width = event.rectangle.width; } this.resized.emit({ width: this._configRightMenu.width }); // TODO implement saving drawer width to user preferences // this.userPreferenceService._drawerWidthChanged$.next(this.width); // this.contentWidth.next(this.width); } resolveLayout(isLargeScreen) { this._configLeftMenu = isLargeScreen ? { mode: 'side', opened: true, disableClose: true, width: this._configLeftMenu.width, } : { mode: 'over', opened: false, disableClose: false, width: this._configLeftMenu.width, }; this._configRightMenu = isLargeScreen ? { mode: 'side', opened: true, disableClose: true, width: this._configRightMenu.width, } : { mode: 'over', opened: false, disableClose: false, width: this._configRightMenu.width, }; } canApplyAutoSelect() { return this.configUrl === this._router.url; } openAvailableView() { this._navigationService.openAvailableView(); } resolveInitialValueOfPath() { if (this.currentPath === undefined) { const groupNavigationRoute = this._config.getServicesConfiguration()?.groupNavigation?.groupNavigationRoute; if (this._router.url.includes(groupNavigationRoute)) { this._pathResolverLoading$.on(); this._pathService.datafieldsForMenuResolver.pipe(take(1)).subscribe(data => { this._pathResolverLoading$.off(); let nodePath; let hasChildren; try { nodePath = extractFieldValueFromData(data, GroupNavigationConstants.ITEM_FIELD_ID_NODE_PATH); hasChildren = extractFieldValueFromData(data, GroupNavigationConstants.ITEM_FIELD_ID_HAS_CHILDREN); } catch (e) { this._log.info("Couldn't resolve menu, skipping..."); } if (hasChildren && nodePath) { this._navigationService.fromResolver = true; this._pathService.activePath = nodePath; } else if (nodePath) { this._navigationService.fromResolver = true; this._pathService.activePath = this._navigationService.extractParentPath(nodePath); } }, error => { this._pathResolverLoading$.off(); this.currentPath = this._pathService.activePath; }); } else { const viewConfiguration = this._config.getViewByUrl(this._router.url); if (viewConfiguration?.processUri) { this._navigationService.fromResolver = true; this._pathService.activePath = viewConfiguration.processUri; } } } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AbstractNavigationDoubleDrawerComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i2.BreakpointObserver }, { token: i3.LanguageService }, { token: i4.TranslateService }, { token: i5.UserService }, { token: i6.LoggerService }, { token: i7.ConfigurationService }, { token: i8.PathService }, { token: i9.CaseResourceService }, { token: i10.ImpersonationUserSelectService }, { token: i11.ImpersonationService }, { token: i12.DoubleDrawerNavigationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AbstractNavigationDoubleDrawerComponent, selector: "ncc-abstract-navigation-double-drawer", inputs: { portalLeftMenu: "portalLeftMenu", portalRightMenu: "portalRightMenu", imageRouterLink: "imageRouterLink", imageAlt: "imageAlt", image: "image", profileRouterLink: "profileRouterLink", includeUser: "includeUser", includeLanguage: "includeLanguage", includeMoreMenu: "includeMoreMenu", includeImpersonation: "includeImpersonation", allClosable: "allClosable", folderIcon: "folderIcon", openedFolderIcon: "openedFolderIcon", filterIcon: "filterIcon", foldersCategoryName: "foldersCategoryName", viewsCategoryName: "viewsCategoryName" }, outputs: { loggedOut: "loggedOut", stateChanged: "stateChanged", itemClicked: "itemClicked", resized: "resized", itemLoaded: "itemLoaded" }, ngImport: i0, template: '', isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AbstractNavigationDoubleDrawerComponent, decorators: [{ type: Component, args: [{ selector: 'ncc-abstract-navigation-double-drawer', template: '', }] }], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.BreakpointObserver }, { type: i3.LanguageService }, { type: i4.TranslateService }, { type: i5.UserService }, { type: i6.LoggerService }, { type: i7.ConfigurationService }, { type: i8.PathService }, { type: i9.CaseResourceService }, { type: i10.ImpersonationUserSelectService }, { type: i11.ImpersonationService }, { type: i12.DoubleDrawerNavigationService }], propDecorators: { portalLeftMenu: [{ type: Input }], portalRightMenu: [{ type: Input }], imageRouterLink: [{ type: Input }], imageAlt: [{ type: Input }], image: [{ type: Input }], profileRouterLink: [{ type: Input }], includeUser: [{ type: Input }], includeLanguage: [{ type: Input }], includeMoreMenu: [{ type: Input }], includeImpersonation: [{ type: Input }], allClosable: [{ type: Input }], folderIcon: [{ type: Input }], openedFolderIcon: [{ type: Input }], filterIcon: [{ type: Input }], foldersCategoryName: [{ type: Input }], viewsCategoryName: [{ type: Input }], loggedOut: [{ type: Output }], stateChanged: [{ type: Output }], itemClicked: [{ type: Output }], resized: [{ type: Output }], itemLoaded: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3QtbmF2aWdhdGlvbi1kb3VibGUtZHJhd2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmV0Z3JpZi1jb21wb25lbnRzLWNvcmUvc3JjL2xpYi9uYXZpZ2F0aW9uL25hdmlnYXRpb24tZG91YmxlLWRyYXdlci9hYnN0cmFjdC1uYXZpZ2F0aW9uLWRvdWJsZS1kcmF3ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFxQixXQUFXLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRSxPQUFPLEVBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBYyxNQUFNLGVBQWUsQ0FBQztBQUtyRyxPQUFPLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBTTVDLE9BQU8sRUFBQyw4QkFBOEIsRUFBQyxNQUFNLHVEQUF1RCxDQUFDO0FBSXJHLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBRUgseUJBQXlCLEVBRXpCLDhCQUE4QixFQUM5QiwwQkFBMEIsRUFDMUIsc0JBQXNCLEdBQ3pCLE1BQU0sNkJBQTZCLENBQUM7QUFRckMsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDN0UsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0saURBQWlELENBQUM7QUFDMUYsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLCtCQUErQixDQUFDOzs7Ozs7Ozs7Ozs7OztBQU03RCxNQUFNLE9BQWdCLHVDQUF1QztJQW9EekI7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUE5RHZCLGNBQWMsQ0FBbUI7SUFDakMsZUFBZSxDQUFtQjtJQUNsQyxlQUFlLEdBQVcsR0FBRyxDQUFDO0lBQzlCLFFBQVEsR0FBVyxN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QyxDQUFBO2dCQUNyRSxJQUFJLGlCQUFpQixFQUFFLFVBQVUsRUFBRTtvQkFDL0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7b0JBQzVDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxHQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQztpQkFDL0Q7YUFDSjtTQUNKO0lBQ0wsQ0FBQzt3R0E1WGlCLHVDQUF1Qzs0RkFBdkMsdUNBQXVDLDB2QkFGL0MsRUFBRTs7NEZBRU0sdUNBQXVDO2tCQUo1RCxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSx1Q0FBdUM7b0JBQ2pELFFBQVEsRUFBRSxFQUFFO2lCQUNmOzBkQUdZLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBRUksU0FBUztzQkFBbEIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csT0FBTztzQkFBaEIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtCcmVha3BvaW50T2JzZXJ2ZXIsIEJyZWFrcG9pbnRzfSBmcm9tICdAYW5ndWxhci9jZGsvbGF5b3V0JztcbmltcG9ydCB7Q29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBUZW1wbGF0ZVJlZn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlLCBSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtSZXNpemVFdmVudH0gZnJvbSAnYW5ndWxhci1yZXNpemFibGUtZWxlbWVudCc7XG5pbXBvcnQge09ic2VydmFibGUsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2ZpbHRlciwgdGFrZX0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtDb25maWd1cmF0aW9uU2VydmljZX0gZnJvbSAnLi4vLi4vY29uZmlndXJhdGlvbi9jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtJbXBlcnNvbmF0aW9uVXNlclNlbGVjdFNlcnZpY2V9IGZyb20gJy4uLy4uL2ltcGVyc29uYXRpb24vc2VydmljZXMvaW1wZXJzb25hdGlvbi11c2VyLXNlbGVjdC5zZXJ2aWNlJztcbmltcG9ydCB7SW1wZXJzb25hdGlvblNlcnZpY2V9IGZyb20gJy4uLy4uL2ltcGVyc29uYXRpb24vc2VydmljZXMvaW1wZXJzb25hdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7TG9nZ2VyU2VydmljZX0gZnJvbSAnLi4vLi4vbG9nZ2VyL3NlcnZpY2VzL2xvZ2dlci5zZXJ2aWNlJztcbmltcG9ydCB7Q2FzZVJlc291cmNlU2VydmljZX0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2VuZ2luZS1lbmRwb2ludC9jYXNlLXJlc291cmNlLnNlcnZpY2UnO1xuaW1wb3J0IHtOQUVfUk9VVElOR19DT05GSUdVUkFUSU9OX1BBVEh9IGZyb20gJy4uLy4uL3JvdXRpbmcvcm91dGluZy1idWlsZGVyL3JvdXRpbmctYnVpbGRlci5zZXJ2aWNlJztcbmltcG9ydCB7TGFuZ3VhZ2VTZXJ2aWNlfSBmcm9tICcuLi8uLi90cmFuc2xhdGUvbGFuZ3VhZ2Uuc2VydmljZSc7XG5pbXBvcnQge1VzZXJ9IGZyb20gJy4uLy4uL3VzZXIvbW9kZWxzL3VzZXInO1xuaW1wb3J0IHtVc2VyU2VydmljZX0gZnJvbSAnLi4vLi4vdXNlci9zZXJ2aWNlcy91c2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtQYXRoU2VydmljZX0gZnJvbSAnLi4vc2VydmljZS9wYXRoLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgICBDb25maWdEb3VibGVNZW51LFxuICAgIExFRlRfRFJBV0VSX0RFRkFVTFRfV0lEVEgsXG4gICAgTmF2aWdhdGlvbkl0ZW0sXG4gICAgUklHSFRfRFJBV0VSX0RFRkFVTFRfTUlOX1dJRFRILFxuICAgIFJJR0hUX0RSQVdFUl9ERUZBVUxUX1dJRFRILFxuICAgIFJJR0hUX0RSQVdFUl9NQVhfV0lEVEgsXG59IGZyb20gJy4uL21vZGVsL25hdmlnYXRpb24tY29uZmlncyc7XG5pbXBvcnQge1xuICAgIE1lbnVJdGVtQ2xpY2tFdmVudCxcbiAgICBNZW51SXRlbUxvYWRlZEV2ZW50LFxuICAgIE1lbnVSZXNpemVFdmVudCxcbiAgICBNZW51U3RhdGVDaGFuZ2VFdmVudCxcbn0gZnJvbSAnLi4vbW9kZWwvbmF2aWdhdGlvbi1tZW51LWV2ZW50cyc7XG5pbXBvcnQge0RvdWJsZURyYXdlck5hdmlnYXRpb25TZXJ2aWNlfSBmcm9tIFwiLi9zZXJ2aWNlL2RvdWJsZS1kcmF3ZXItbmF2aWdhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQge0dyb3VwTmF2aWdhdGlvbkNvbnN0YW50c30gZnJvbSBcIi4uL21vZGVsL2dyb3VwLW5hdmlnYXRpb24tY29uc3RhbnRzXCI7XG5pbXBvcnQge2V4dHJhY3RGaWVsZFZhbHVlRnJvbURhdGF9IGZyb20gXCIuLi91dGlsaXR5L25hdmlnYXRpb24taXRlbS10YXNrLXV0aWxpdHktbWV0aG9kc1wiO1xuaW1wb3J0IHtMb2FkaW5nRW1pdHRlcn0gZnJvbSBcIi4uLy4uL3V0aWxpdHkvbG9hZGluZy1lbWl0dGVyXCI7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmNjLWFic3RyYWN0LW5hdmlnYXRpb24tZG91YmxlLWRyYXdlcicsXG4gICAgdGVtcGxhdGU6ICcnLFxufSlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE5hdmlnYXRpb25Eb3VibGVEcmF3ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgICBASW5wdXQoKSBwb3J0YWxMZWZ0TWVudTogVGVtcGxhdGVSZWY8YW55PjtcbiAgICBASW5wdXQoKSBwb3J0YWxSaWdodE1lbnU6IFRlbXBsYXRlUmVmPGFueT47XG4gICAgQElucHV0KCkgaW1hZ2VSb3V0ZXJMaW5rOiBzdHJpbmcgPSAnLyc7XG4gICAgQElucHV0KCkgaW1hZ2VBbHQ6IHN0cmluZyA9ICdMb2dvJztcbiAgICBASW5wdXQoKSBpbWFnZTogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHByb2ZpbGVSb3V0ZXJMaW5rOiBzdHJpbmcgPSAnL3Byb2ZpbGUnO1xuICAgIEBJbnB1dCgpIGluY2x1ZGVVc2VyOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBpbmNsdWRlTGFuZ3VhZ2U6IGJvb2xlYW4gPSB0cnVlO1xuICAgIEBJbnB1dCgpIGluY2x1ZGVNb3JlTWVudTogYm9vbGVhbiA9IHRydWU7XG4gICAgQElucHV0KCkgaW5jbHVkZUltcGVyc29uYXRpb246IGJvb2xlYW4gPSB0cnVlO1xuICAgIEBJbnB1dCgpIGFsbENsb3NhYmxlOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBmb2xkZXJJY29uOiBzdHJpbmcgPSAnZm9sZGVyJztcbiAgICBASW5wdXQoKSBvcGVuZWRGb2xkZXJJY29uOiBzdHJpbmcgPSAnZm9sZGVyX29wZW4nO1xuICAgIEBJbnB1dCgpIGZpbHRlckljb246IHN0cmluZyA9ICdmaWx0ZXJfYWx0JztcbiAgICBASW5wdXQoKSBmb2xkZXJzQ2F0ZWdvcnlOYW1lOiBzdHJpbmcgPSAndG9vbGJhci5tZW51LmZvbGRlcnMnO1xuICAgIEBJbnB1dCgpIHZpZXdzQ2F0ZWdvcnlOYW1lOiBzdHJpbmcgPSAndG9vbGJhci5tZW51LnZpZXdzJztcblxuICAgIEBPdXRwdXQoKSBsb2dnZWRPdXQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4odHJ1ZSk7IC8vIG9uIGxvZ291dFxuICAgIEBPdXRwdXQoKSBzdGF0ZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPE1lbnVTdGF0ZUNoYW5nZUV2ZW50PigpOyAvLyBvbiBtZW51IHN0YXRlIGNoYW5nZVxuICAgIEBPdXRwdXQoKSBpdGVtQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8TWVudUl0ZW1DbGlja0V2ZW50PigpOyAvLyBvbiBpdGVtIGNsaWNrXG4gICAgQE91dHB1dCgpIHJlc2l6ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPE1lbnVSZXNpemVFdmVudD4odHJ1ZSk7IC8vIG9uIG1lbnUgcmVzaXplXG4gICAgQE91dHB1dCgpIGl0ZW1Mb2FkZWQgPSBuZXcgRXZlbnRFbWl0dGVyPE1lbnVJdGVtTG9hZGVkRXZlbnQ+KHRydWUpOyAvLyBvbiBpdGVtIGxvYWRlZFxuXG4gICAgcHVibGljIGhpZGVNb3JlTWVudTogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX2JyZWFrcG9pbnRTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgICBwcm90ZWN0ZWQgX2N1cnJlbnROb2RlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gICAgcHJvdGVjdGVkIF9jdXJyZW50UGF0aFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICAgIHByb3RlY3RlZCBfbG9nZ2VkVXNlclN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICAgIC8qKlxuICAgICAqIEN1cnJlbnRseSBkaXNwbGF5IFBhdGhcbiAgICAgKiBTaWJsaW5ncyBvZiB0aGUgbm9kZSBhcmUgb24gdGhlIGxlZnQsIGNoaWxkcmVuIGFyZSBvbiB0aGUgcmlnaHRcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2N1cnJlbnRQYXRoOiBzdHJpbmc7XG4gICAgcHJvdGVjdGVkIF9wYXRoUmVzb2x2ZXJMb2FkaW5nJDogTG9hZGluZ0VtaXR0ZXI7XG5cbiAgICBwcm90ZWN0ZWQgX2NvbmZpZ0xlZnRNZW51OiBDb25maWdEb3VibGVNZW51ID0ge1xuICAgICAgICBtb2RlOiAnc2lkZScsXG4gICAgICAgIG9wZW5lZDogdHJ1ZSxcbiAgICAgICAgZGlzYWJsZUNsb3NlOiBmYWxzZSxcbiAgICAgICAgd2lkdGg6IExFRlRfRFJBV0VSX0RFRkFVTFRfV0lEVEgsXG4gICAgfTtcbiAgICBwcm90ZWN0ZWQgX2NvbmZpZ1JpZ2h0TWVudTogQ29uZmlnRG91YmxlTWVudSA9IHtcbiAgICAgICAgbW9kZTogJ3NpZGUnLFxuICAgICAgICBvcGVuZWQ6IHRydWUsXG4gICAgICAgIGRpc2FibGVDbG9zZTogZmFsc2UsXG4gICAgICAgIHdpZHRoOiBSSUdIVF9EUkFXRVJfREVGQVVMVF9XSURUSCxcbiAgICB9O1xuXG4gICAgcHJvdGVjdGVkIGNvbmZpZ1VybDogc3RyaW5nO1xuXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2JyZWFrcG9pbnQ6IEJyZWFrcG9pbnRPYnNlcnZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9sYW5ndWFnZVNlcnZpY2U6IExhbmd1YWdlU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF90cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3VzZXJTZXJ2aWNlOiBVc2VyU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9sb2c6IExvZ2dlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfY29uZmlnOiBDb25maWd1cmF0aW9uU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9wYXRoU2VydmljZTogUGF0aFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfY2FzZVJlc291cmNlU2VydmljZTogQ2FzZVJlc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9pbXBlcnNvbmF0aW9uVXNlclNlbGVjdDogSW1wZXJzb25hdGlvblVzZXJTZWxlY3RTZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2ltcGVyc29uYXRpb246IEltcGVyc29uYXRpb25TZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX25hdmlnYXRpb25TZXJ2aWNlOiBEb3VibGVEcmF3ZXJOYXZpZ2F0aW9uU2VydmljZSkge1xuICAgICAgICBsZXQgY29uZmlnVXJsOiBzdHJpbmcgPSB0aGlzLl9jb25maWcuZ2V0U2VydmljZXNDb25maWd1cmF0aW9uKCk/LmRvdWJsZURyYXdlcj8udXJsO1xuICAgICAgICBpZiAoY29uZmlnVXJsICE9PSB1bmRlZmluZWQgJiYgIWNvbmZpZ1VybC5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgICAgIGNvbmZpZ1VybCA9ICcvJyArIGNvbmZpZ1VybDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbmZpZ1VybCA9IGNvbmZpZ1VybDtcbiAgICAgICAgdGhpcy5oaWRlTW9yZU1lbnUgPSB0cnVlO1xuICAgICAgICB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5pdGVtQ2xpY2tlZCQuc3Vic2NyaWJlKChpdGVtQ2xpY2tFdmVudDogTWVudUl0ZW1DbGlja0V2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLml0ZW1DbGlja2VkLmVtaXQoaXRlbUNsaWNrRXZlbnQpO1xuICAgICAgICB9KVxuICAgICAgICB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5pdGVtTG9hZGVkJC5zdWJzY3JpYmUoKGl0ZW1Mb2FkZWRFdmVudDogTWVudUl0ZW1Mb2FkZWRFdmVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pdGVtTG9hZGVkLmVtaXQoaXRlbUxvYWRlZEV2ZW50KTtcbiAgICAgICAgfSlcbiAgICAgICAgdGhpcy5fcGF0aFJlc29sdmVyTG9hZGluZyQgPSBuZXcgTG9hZGluZ0VtaXR0ZXIoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2JyZWFrcG9pbnRTdWJzY3JpcHRpb24gPSB0aGlzLl9icmVha3BvaW50Lm9ic2VydmUoW0JyZWFrcG9pbnRzLkhhbmRzZXRMYW5kc2NhcGVdKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2JyZWFrcG9pbnQuaXNNYXRjaGVkKCcobWF4LXdpZHRoOiA5NTkuOTlweCknKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUxheW91dChmYWxzZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUxheW91dCh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fdXNlclNlcnZpY2UudXNlciQucGlwZShmaWx0ZXIodSA9PiAhIXUgJiYgdS5pZCAhPT0gJycpLCB0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5pdGlhbFZhbHVlT2ZQYXRoKCk7XG5cbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRQYXRoU3Vic2NyaXB0aW9uID0gdGhpcy5fcGF0aFNlcnZpY2UuYWN0aXZlUGF0aCQuc3Vic2NyaWJlKHBhdGggPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwYXRoICE9PSB0aGlzLmN1cnJlbnRQYXRoICYmICF0aGlzLl9wYXRoUmVzb2x2ZXJMb2FkaW5nJC5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRQYXRoID0gcGF0aDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLl9wYXRoUmVzb2x2ZXJMb2FkaW5nJC5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW5BdmFpbGFibGVWaWV3KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmNhbkFwcGx5QXV0b1NlbGVjdCgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yaWdodEl0ZW1zJC5waXBlKFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXIocmlnaHRJdGVtcyA9PiByaWdodEl0ZW1zLmxlbmd0aCA+IDApLFxuICAgICAgICAgICAgICAgICAgICB0YWtlKDEpXG4gICAgICAgICAgICAgICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW5BdmFpbGFibGVWaWV3KCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgdmlld0NvbmZpZ3VyYXRpb25QYXRoID0gdGhpcy5fYWN0aXZhdGVkUm91dGUuc25hcHNob3QuZGF0YVtOQUVfUk9VVElOR19DT05GSUdVUkFUSU9OX1BBVEhdO1xuICAgICAgICAgICAgaWYgKCEhdmlld0NvbmZpZ3VyYXRpb25QYXRoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgdmlld0NvbmZpZ3VyYXRpb24gPSB0aGlzLl9jb25maWcuZ2V0Vmlld0J5UGF0aCh2aWV3Q29uZmlndXJhdGlvblBhdGgpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLmluaXRpYWxpemVDdXN0b21WaWV3c09mVmlldyh2aWV3Q29uZmlndXJhdGlvbiwgdmlld0NvbmZpZ3VyYXRpb25QYXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaGlkZGVuQ3VzdG9tSXRlbXMkLnN1YnNjcmliZShoaWRkZW5DdXN0b21JdGVtcyA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlTW9yZU1lbnUgPSAhaGlkZGVuQ3VzdG9tSXRlbXM/Lmxlbmd0aDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fYnJlYWtwb2ludFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5sb2dnZWRPdXQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5zdGF0ZUNoYW5nZWQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5pdGVtQ2xpY2tlZC5jb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLnJlc2l6ZWQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5pdGVtTG9hZGVkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuX2N1cnJlbnROb2RlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLl9jdXJyZW50UGF0aFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5fbG9nZ2VkVXNlclN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGN1cnJlbnRQYXRoKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5jdXJyZW50UGF0aDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IGN1cnJlbnRQYXRoKG5vZGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5jdXJyZW50UGF0aCA9IG5vZGU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjb25maWdMZWZ0TWVudSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbmZpZ0xlZnRNZW51O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgY29uZmlnUmlnaHRNZW51KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29uZmlnUmlnaHRNZW51O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbGVmdEl0ZW1zJCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLmxlZnRJdGVtcyQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsZWZ0SXRlbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5sZWZ0SXRlbXM7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCByaWdodEl0ZW1zJCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLnJpZ2h0SXRlbXMkO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgcmlnaHRJdGVtcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLnJpZ2h0SXRlbXM7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBtb3JlSXRlbXMkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbmF2aWdhdGlvblNlcnZpY2UubW9yZUl0ZW1zJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IG1vcmVJdGVtcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLm1vcmVJdGVtcztcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGhpZGRlbkN1c3RvbUl0ZW1zJCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLmhpZGRlbkN1c3RvbUl0ZW1zJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGhpZGRlbkN1c3RvbUl0ZW1zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbmF2aWdhdGlvblNlcnZpY2UuaGlkZGVuQ3VzdG9tSXRlbXM7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsZWZ0TG9hZGluZyQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5sZWZ0TG9hZGluZyQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCByaWdodExvYWRpbmckKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbmF2aWdhdGlvblNlcnZpY2UucmlnaHRMb2FkaW5nJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHBhdGhSZXNvbHZlckxvYWRpbmckKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGF0aFJlc29sdmVyTG9hZGluZyQ7XG4gICAgfVxuXG4gICAgcHVibGljIHRvZ2dsZU1lbnUoKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlUmlnaHRNZW51KCk7XG4gICAgICAgIGlmICh0aGlzLmFsbENsb3NhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLnRvZ2dsZUxlZnRNZW51KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgdG9nZ2xlTGVmdE1lbnUoKSB7XG4gICAgICAgIHRoaXMuX2NvbmZpZ0xlZnRNZW51Lm9wZW5lZCA9ICF0aGlzLl9jb25maWdMZWZ0TWVudS5vcGVuZWQ7XG4gICAgICAgIHRoaXMuc3RhdGVDaGFuZ2VkLmVtaXQoe21lbnU6ICdsZWZ0JywgaXNPcGVuZWQ6IHRoaXMuX2NvbmZpZ0xlZnRNZW51Lm9wZW5lZH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyB0b2dnbGVSaWdodE1lbnUoKSB7XG4gICAgICAgIHRoaXMuX2NvbmZpZ1JpZ2h0TWVudS5vcGVuZWQgPSAhdGhpcy5fY29uZmlnUmlnaHRNZW51Lm9wZW5lZDtcbiAgICAgICAgdGhpcy5zdGF0ZUNoYW5nZWQuZW1pdCh7bWVudTogJ3JpZ2h0JywgaXNPcGVuZWQ6IHRoaXMuX2NvbmZpZ1JpZ2h0TWVudS5vcGVuZWR9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0TGFuZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xhbmd1YWdlU2VydmljZS5nZXRMYW5ndWFnZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2dvdXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3VzZXJTZXJ2aWNlLmxvZ291dCgpLnN1YnNjcmliZShyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9sb2cuZGVidWcoJ1VzZXIgaXMgbG9nZ2VkIG91dCcpO1xuICAgICAgICAgICAgdGhpcy5sb2dnZWRPdXQuZW1pdChyZXNwb25zZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uZmlnLmdldCgpLnNlcnZpY2VzICYmIHRoaXMuX2NvbmZpZy5nZXQoKS5zZXJ2aWNlcy5hdXRoICYmIHRoaXMuX2NvbmZpZy5nZXRPbkxvZ291dFBhdGgoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZGlyZWN0UGF0aCA9IHRoaXMuX2NvbmZpZy5nZXRPbkxvZ291dFBhdGgoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2cuaW5mbygnUmVkaXJlY3RpbmcgdG8gJyArIHJlZGlyZWN0UGF0aCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm91dGVyLm5hdmlnYXRlKFtyZWRpcmVjdFBhdGhdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGltcGVyc29uYXRlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9pbXBlcnNvbmF0aW9uVXNlclNlbGVjdC5zZWxlY3RJbXBlcnNvbmF0ZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wSW1wZXJzb25hdGluZygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5faW1wZXJzb25hdGlvbi5jZWFzZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdXNlcigpOiBVc2VyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VzZXJTZXJ2aWNlLnVzZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjYW5Hb0JhY2tMb2FkaW5nJCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLmNhbkdvQmFja0xvYWRpbmckO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGhvbWUgY2xpY2ssIHRoZSBjdXJyZW50IGxldmVsIGlzIHNldCB0byAwLCBhbmQgY3VycmVudCBwYXJlbnQgaXNcbiAgICAgKiBzZXQgdG8gcm9vdCBub2RlLlxuICAgICAqICovXG4gICAgcHVibGljIG9uSG9tZUNsaWNrKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5vbkhvbWVDbGljaygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGJhY2sgY2xpY2ssIHRoZSBwYXJlbnQgaXMgc2V0IHRvIHBhcmVudCBvZiBsZWZ0IG5vZGVzLCB0aGF0IHdpbGwgc29sdmVcbiAgICAgKiB0aGUgcmlnaHQgc2lkZSBtZW51IChlbGVtZW50cyB0aGF0IHdlcmUgaW4gbGVmdCBzaWRlLCBhZnRlciBiYWNrd2FyZFxuICAgICAqIG5hdmlnYXRpb24gd2lsbCBiZSBvbiB0aGUgcmlnaHQgc2lkZSkuXG4gICAgICogQ3VycmVudCBsZXZlbCBpcyBzZXQgdG8gYSBsb3dlciBudW1iZXIgaW4gb3JkZXIgdG8gc2V0IHRoZSBsZWZ0IHNpZGUgbWVudS5cbiAgICAgKiAqL1xuICAgIHB1YmxpYyBvbkJhY2tDbGljaygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fbmF2aWdhdGlvblNlcnZpY2Uub25CYWNrQ2xpY2soKVxuICAgIH1cblxuICAgIHB1YmxpYyBvbkl0ZW1DbGljayhpdGVtOiBOYXZpZ2F0aW9uSXRlbSk6IHZvaWQge1xuICAgICAgICB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5vbkl0ZW1DbGljayhpdGVtKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbG9hZE1vcmVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5fbmF2aWdhdGlvblNlcnZpY2UubG9hZE1vcmVJdGVtcygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0FzY2VuZGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLmlzQXNjZW5kaW5nKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHN3aXRjaE9yZGVyKCkge1xuICAgICAgICB0aGlzLl9uYXZpZ2F0aW9uU2VydmljZS5zd2l0Y2hPcmRlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRvIGNoZWNrIHdoZXRoZXIgdGhlIGJhY2sgYnV0dG9uIHNob3VsZCBiZSBkaXNwbGF5ZWRcbiAgICAgKiBAcmV0dXJucyBib29sZWFuIGlmIHRoZSBiYWNrIGJ1dHRvbiBzaG91bGQgYmUgZGlzcGxheWVkXG4gICAgICogKi9cbiAgICBwdWJsaWMgaXNPblplcm9MZXZlbCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFBhdGggPT09IFBhdGhTZXJ2aWNlLlNFUEFSQVRPUjtcbiAgICB9XG5cbiAgICBpc0l0ZW1BbmRQYXRoRXF1YWwoaXRlbTogTmF2aWdhdGlvbkl0ZW0sIHBhdGg6