@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
422 lines • 55.7 kB
JavaScript
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