@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
185 lines • 28.5 kB
JavaScript
import { Inject, Injectable, Optional } from '@angular/core';
import { AuthenticationGuardService } from '../../authentication/services/guard/authentication-guard.service';
import { ViewClassInfo } from '../../../commons/view-class-info';
import { classify } from '../../../commons/angular-cli-devkit-core-strings';
import { AuthorityGuardService } from '../../authorization/authority/authority-guard.service';
import { RoleGuardService } from '../../authorization/role/role-guard.service';
import { GroupGuardService } from '../../authorization/group/group-guard.service';
import { GroupNavigationConstants } from '../../navigation/model/group-navigation-constants';
import { NAE_GROUP_NAVIGATION_COMPONENT_RESOLVER_COMPONENT } from '../../navigation/model/group-navigation-component-resolver-component-injection-token';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "../../configuration/configuration.service";
import * as i3 from "../view-service/view.service";
import * as i4 from "../../logger/services/logger.service";
import * as i5 from "../dynamic-navigation-route-provider/dynamic-navigation-route-provider.service";
export const NAE_ROUTING_CONFIGURATION_PATH = "configPath";
/**
* Uses the information from nae.json to construct the application's routing
*/
export class RoutingBuilderService {
_configService;
_viewService;
_logger;
_dynamicNavigationRouteService;
_groupNavigationComponentResolverComponent;
_groupNavigationRouteGenerated = false;
constructor(router, _configService, _viewService, _logger, _dynamicNavigationRouteService, _groupNavigationComponentResolverComponent) {
this._configService = _configService;
this._viewService = _viewService;
this._logger = _logger;
this._dynamicNavigationRouteService = _dynamicNavigationRouteService;
this._groupNavigationComponentResolverComponent = _groupNavigationComponentResolverComponent;
router.config.splice(0, router.config.length);
for (const [pathSegment, view] of Object.entries(_configService.get().views)) {
const route = this.constructRouteObject(view, pathSegment);
if (route !== undefined) {
router.config.push(route);
}
}
router.config.push(...this.defaultRoutesRedirects());
}
constructRouteObject(view, configPath, ancestors = []) {
const component = this.resolveComponentClass(view, configPath);
if (component === undefined) {
return undefined;
}
if (!view.routing) {
this._logger.warn(`nae.json configuration is invalid. View at path '${configPath}'` +
` must define a 'routing' attribute. Skipping this view for routing generation.`);
return undefined;
}
const route = {
path: view.routing.path,
data: {
[NAE_ROUTING_CONFIGURATION_PATH]: configPath
},
component
};
if (view?.layout?.name === GroupNavigationConstants.GROUP_NAVIGATION_OUTLET) {
if (this._groupNavigationRouteGenerated) {
this._logger.warn(`Multiple groupNavigationOutlets are present in nae.json. Duplicate entry found at path ${configPath}`);
}
else {
this._logger.debug(`GroupNavigationOutlet found in nae.json at path '${configPath}'`);
}
const pathNoParams = route.path;
route.path = `${pathNoParams}/:${GroupNavigationConstants.GROUP_NAVIGATION_ROUTER_PARAM}`;
route.canActivate = [AuthenticationGuardService];
const parentPathSegments = ancestors.map(a => a.path);
parentPathSegments.push(pathNoParams);
this._dynamicNavigationRouteService.route = parentPathSegments.join('/');
this._groupNavigationRouteGenerated = true;
return route;
}
if (view.routing.match !== undefined && view.routing.match) {
route['pathMatch'] = 'full';
}
route['canActivate'] = [];
if (view.access === 'private'
|| view.access.hasOwnProperty('role')
|| view.access.hasOwnProperty('group')
|| view.access.hasOwnProperty('authority')) {
route['canActivate'].push(AuthenticationGuardService);
}
if (view.access.hasOwnProperty('role')) {
route['canActivate'].push(RoleGuardService);
}
if (view.access.hasOwnProperty('authority')) {
route['canActivate'].push(AuthorityGuardService);
}
if (view.access.hasOwnProperty('group')) {
route['canActivate'].push(GroupGuardService);
}
if (!!view.children) {
route['children'] = [];
Object.entries(view.children).forEach(([configPathSegment, childView]) => {
// TODO check if routes are constructed correctly regarding empty route segments
const childRoute = this.constructRouteObject(childView, `${configPath}/${configPathSegment}`, [...ancestors, route]);
if (childRoute !== undefined) {
route['children'].push(childRoute);
}
});
}
if (view?.layout?.name === 'tabView') {
if (!view.children) {
route['children'] = [];
}
route['children'].push({
path: '**',
component
});
}
return route;
}
resolveComponentClass(view, configPath) {
let result;
if (!!view.component) {
result = this._viewService.resolveNameToClass(view.component.class);
}
else if (!!view.layout) {
result = this.resolveComponentClassFromLayout(view, configPath);
}
else {
this._logger.warn(`nae.json configuration is invalid. View at path '${configPath}'` +
` must define either a 'layout' or a 'component' attribute. Skipping this view for routing generation.`);
return undefined;
}
if (result === undefined) {
this._logger.warn(`Some views from nae.json configuration have not been created in the project.` +
` Run create-view schematic to rectify this. Skipping this view for routing generation.`);
return undefined;
}
return result;
}
resolveComponentClassFromLayout(view, configPath) {
if (view.layout.name === GroupNavigationConstants.GROUP_NAVIGATION_OUTLET) {
return this._groupNavigationComponentResolverComponent;
}
const className = RoutingBuilderService.parseClassNameFromView(view, configPath);
return this._viewService.resolveNameToClass(className);
}
static parseClassNameFromView(view, configPath) {
if (!!view.layout.componentName) {
return `${classify(view.layout.componentName)}Component`;
}
else {
const classInfo = new ViewClassInfo(configPath, view.layout.name, view.layout.componentName);
return classInfo.className;
}
}
defaultRoutesRedirects() {
const result = [];
const servicesConfig = this._configService.getServicesConfiguration();
if (!!servicesConfig && !!servicesConfig.routing) {
if (!!servicesConfig.routing.defaultRedirect) {
result.push({
path: '',
redirectTo: servicesConfig.routing.defaultRedirect,
pathMatch: 'full'
});
}
if (!!servicesConfig.routing.wildcardRedirect) {
result.push({
path: '**',
redirectTo: servicesConfig.routing.wildcardRedirect
});
}
}
return result;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RoutingBuilderService, deps: [{ token: i1.Router }, { token: i2.ConfigurationService }, { token: i3.ViewService }, { token: i4.LoggerService }, { token: i5.DynamicNavigationRouteProviderService }, { token: NAE_GROUP_NAVIGATION_COMPONENT_RESOLVER_COMPONENT, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RoutingBuilderService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RoutingBuilderService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.Router }, { type: i2.ConfigurationService }, { type: i3.ViewService }, { type: i4.LoggerService }, { type: i5.DynamicNavigationRouteProviderService }, { type: i0.Type, decorators: [{
type: Optional
}, {
type: Inject,
args: [NAE_GROUP_NAVIGATION_COMPONENT_RESOLVER_COMPONENT]
}] }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGluZy1idWlsZGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMtY29yZS9zcmMvbGliL3JvdXRpbmcvcm91dGluZy1idWlsZGVyL3JvdXRpbmctYnVpbGRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBTyxNQUFNLGVBQWUsQ0FBQztBQUtqRSxPQUFPLEVBQUMsMEJBQTBCLEVBQUMsTUFBTSxrRUFBa0UsQ0FBQztBQUM1RyxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDL0QsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGtEQUFrRCxDQUFDO0FBRTFFLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHVEQUF1RCxDQUFDO0FBQzVGLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDZDQUE2QyxDQUFDO0FBQzdFLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLCtDQUErQyxDQUFDO0FBQ2hGLE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLG1EQUFtRCxDQUFDO0FBQzNGLE9BQU8sRUFDSCxpREFBaUQsRUFDcEQsTUFBTSxzRkFBc0YsQ0FBQzs7Ozs7OztBQVE5RixNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRyxZQUFZLENBQUM7QUFFM0Q7O0dBRUc7QUFJSCxNQUFNLE9BQU8scUJBQXFCO0lBS1Y7SUFDQTtJQUNBO0lBQ0E7SUFFQTtJQVJaLDhCQUE4QixHQUFHLEtBQUssQ0FBQztJQUUvQyxZQUFZLE1BQWMsRUFDTixjQUFvQyxFQUNwQyxZQUF5QixFQUN6QixPQUFzQixFQUN0Qiw4QkFBcUUsRUFFckUsMENBQW1HO1FBTG5HLG1CQUFjLEdBQWQsY0FBYyxDQUFzQjtRQUNwQyxpQkFBWSxHQUFaLFlBQVksQ0FBYTtRQUN6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LENBQUM7b0JBQ1IsSUFBSSxFQUFFLEVBQUU7b0JBQ1IsVUFBVSxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsZUFBZTtvQkFDbEQsU0FBUyxFQUFFLE1BQU07aUJBQ3BCLENBQUMsQ0FBQzthQUNOO1lBQ0QsSUFBSSxDQUFDLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDM0MsTUFBTSxDQUFDLElBQUksQ0FBQztvQkFDUixJQUFJLEVBQUUsSUFBSTtvQkFDVixVQUFVLEVBQUUsY0FBYyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0I7aUJBQ3RELENBQUMsQ0FBQzthQUNOO1NBQ0o7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNsQixDQUFDO3dHQTVKUSxxQkFBcUIseUxBU0UsaURBQWlEOzRHQVR4RSxxQkFBcUIsY0FGbEIsTUFBTTs7NEZBRVQscUJBQXFCO2tCQUhqQyxVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQjs7MEJBVWdCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsaURBQWlEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsLCBUeXBlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q29uZmlndXJhdGlvblNlcnZpY2V9IGZyb20gJy4uLy4uL2NvbmZpZ3VyYXRpb24vY29uZmlndXJhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7Vmlld1NlcnZpY2V9IGZyb20gJy4uL3ZpZXctc2VydmljZS92aWV3LnNlcnZpY2UnO1xuaW1wb3J0IHtSb3V0ZSwgUm91dGVyfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtWaWV3fSBmcm9tICcuLi8uLi8uLi9jb21tb25zL3NjaGVtYSc7XG5pbXBvcnQge0F1dGhlbnRpY2F0aW9uR3VhcmRTZXJ2aWNlfSBmcm9tICcuLi8uLi9hdXRoZW50aWNhdGlvbi9zZXJ2aWNlcy9ndWFyZC9hdXRoZW50aWNhdGlvbi1ndWFyZC5zZXJ2aWNlJztcbmltcG9ydCB7Vmlld0NsYXNzSW5mb30gZnJvbSAnLi4vLi4vLi4vY29tbW9ucy92aWV3LWNsYXNzLWluZm8nO1xuaW1wb3J0IHtjbGFzc2lmeX0gZnJvbSAnLi4vLi4vLi4vY29tbW9ucy9hbmd1bGFyLWNsaS1kZXZraXQtY29yZS1zdHJpbmdzJztcbmltcG9ydCB7TG9nZ2VyU2VydmljZX0gZnJvbSAnLi4vLi4vbG9nZ2VyL3NlcnZpY2VzL2xvZ2dlci5zZXJ2aWNlJztcbmltcG9ydCB7QXV0aG9yaXR5R3VhcmRTZXJ2aWNlfSBmcm9tICcuLi8uLi9hdXRob3JpemF0aW9uL2F1dGhvcml0eS9hdXRob3JpdHktZ3VhcmQuc2VydmljZSc7XG5pbXBvcnQge1JvbGVHdWFyZFNlcnZpY2V9IGZyb20gJy4uLy4uL2F1dGhvcml6YXRpb24vcm9sZS9yb2xlLWd1YXJkLnNlcnZpY2UnO1xuaW1wb3J0IHtHcm91cEd1YXJkU2VydmljZX0gZnJvbSAnLi4vLi4vYXV0aG9yaXphdGlvbi9ncm91cC9ncm91cC1ndWFyZC5zZXJ2aWNlJztcbmltcG9ydCB7R3JvdXBOYXZpZ2F0aW9uQ29uc3RhbnRzfSBmcm9tICcuLi8uLi9uYXZpZ2F0aW9uL21vZGVsL2dyb3VwLW5hdmlnYXRpb24tY29uc3RhbnRzJztcbmltcG9ydCB7XG4gICAgTkFFX0dST1VQX05BVklHQVRJT05fQ09NUE9ORU5UX1JFU09MVkVSX0NPTVBPTkVOVFxufSBmcm9tICcuLi8uLi9uYXZpZ2F0aW9uL21vZGVsL2dyb3VwLW5hdmlnYXRpb24tY29tcG9uZW50LXJlc29sdmVyLWNvbXBvbmVudC1pbmplY3Rpb24tdG9rZW4nO1xuaW1wb3J0IHtcbiAgICBBYnN0cmFjdEdyb3VwTmF2aWdhdGlvbkNvbXBvbmVudFJlc29sdmVyQ29tcG9uZW50XG59IGZyb20gJy4uLy4uL25hdmlnYXRpb24vZ3JvdXAtbmF2aWdhdGlvbi1jb21wb25lbnQtcmVzb2x2ZXIvYWJzdHJhY3QtZ3JvdXAtbmF2aWdhdGlvbi1jb21wb25lbnQtcmVzb2x2ZXIuY29tcG9uZW50JztcbmltcG9ydCB7XG4gICAgRHluYW1pY05hdmlnYXRpb25Sb3V0ZVByb3ZpZGVyU2VydmljZVxufSBmcm9tICcuLi9keW5hbWljLW5hdmlnYXRpb24tcm91dGUtcHJvdmlkZXIvZHluYW1pYy1uYXZpZ2F0aW9uLXJvdXRlLXByb3ZpZGVyLnNlcnZpY2UnO1xuXG5leHBvcnQgY29uc3QgTkFFX1JPVVRJTkdfQ09ORklHVVJBVElPTl9QQVRIID0gXCJjb25maWdQYXRoXCI7XG5cbi8qKlxuICogVXNlcyB0aGUgaW5mb3JtYXRpb24gZnJvbSBuYWUuanNvbiB0byBjb25zdHJ1Y3QgdGhlIGFwcGxpY2F0aW9uJ3Mgcm91dGluZ1xuICovXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFJvdXRpbmdCdWlsZGVyU2VydmljZSB7XG5cbiAgICBwcml2YXRlIF9ncm91cE5hdmlnYXRpb25Sb3V0ZUdlbmVyYXRlZCA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3Iocm91dGVyOiBSb3V0ZXIsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfY29uZmlnU2VydmljZTogQ29uZmlndXJhdGlvblNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfdmlld1NlcnZpY2U6IFZpZXdTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgX2xvZ2dlcjogTG9nZ2VyU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIF9keW5hbWljTmF2aWdhdGlvblJvdXRlU2VydmljZTogRHluYW1pY05hdmlnYXRpb25Sb3V0ZVByb3ZpZGVyU2VydmljZSxcbiAgICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KE5BRV9HUk9VUF9OQVZJR0FUSU9OX0NPTVBPTkVOVF9SRVNPTFZFUl9DT01QT05FTlQpXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfZ3JvdXBOYXZpZ2F0aW9uQ29tcG9uZW50UmVzb2x2ZXJDb21wb25lbnQ6IFR5cGU8QWJzdHJhY3RHcm91cE5hdmlnYXRpb25Db21wb25lbnRSZXNvbHZlckNvbXBvbmVudD4pIHtcbiAgICAgICAgcm91dGVyLmNvbmZpZy5zcGxpY2UoMCwgcm91dGVyLmNvbmZpZy5sZW5ndGgpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwYXRoU2VnbWVudCwgdmlld10gb2YgT2JqZWN0LmVudHJpZXMoX2NvbmZpZ1NlcnZpY2UuZ2V0KCkudmlld3MpKSB7XG4gICAgICAgICAgICBjb25zdCByb3V0ZSA9IHRoaXMuY29uc3RydWN0Um91dGVPYmplY3QodmlldywgcGF0aFNlZ21lbnQpO1xuICAgICAgICAgICAgaWYgKHJvdXRlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByb3V0ZXIuY29uZmlnLnB1c2gocm91dGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJvdXRlci5jb25maWcucHVzaCguLi50aGlzLmRlZmF1bHRSb3V0ZXNSZWRpcmVjdHMoKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RSb3V0ZU9iamVjdCh2aWV3OiBWaWV3LCBjb25maWdQYXRoOiBzdHJpbmcsIGFuY2VzdG9yczogQXJyYXk8Um91dGU+ID0gW10pOiBSb3V0ZSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMucmVzb2x2ZUNvbXBvbmVudENsYXNzKHZpZXcsIGNvbmZpZ1BhdGgpO1xuICAgICAgICBpZiAoY29tcG9uZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF2aWV3LnJvdXRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKGBuYWUuanNvbiBjb25maWd1cmF0aW9uIGlzIGludmFsaWQuIFZpZXcgYXQgcGF0aCAnJHtjb25maWdQYXRofSdgICtcbiAgICAgICAgICAgICAgICBgIG11c3QgZGVmaW5lIGEgJ3JvdXRpbmcnIGF0dHJpYnV0ZS4gU2tpcHBpbmcgdGhpcyB2aWV3IGZvciByb3V0aW5nIGdlbmVyYXRpb24uYCk7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgcm91dGU6IFJvdXRlID0ge1xuICAgICAgICAgICAgcGF0aDogdmlldy5yb3V0aW5nLnBhdGgsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgW05BRV9ST1VUSU5HX0NPTkZJR1VSQVRJT05fUEFUSF06IGNvbmZpZ1BhdGhcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb21wb25lbnRcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodmlldz8ubGF5b3V0Py5uYW1lID09PSBHcm91cE5hdmlnYXRpb25Db25zdGFudHMuR1JPVVBfTkFWSUdBVElPTl9PVVRMRVQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9ncm91cE5hdmlnYXRpb25Sb3V0ZUdlbmVyYXRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKGBNdWx0aXBsZSBncm91cE5hdmlnYXRpb25PdXRsZXRzIGFyZSBwcmVzZW50IGluIG5hZS5qc29uLiBEdXBsaWNhdGUgZW50cnkgZm91bmQgYXQgcGF0aCAke2NvbmZpZ1BhdGh9YCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZyhgR3JvdXBOYXZpZ2F0aW9uT3V0bGV0IGZvdW5kIGluIG5hZS5qc29uIGF0IHBhdGggJyR7Y29uZmlnUGF0aH0nYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhdGhOb1BhcmFtcyA9IHJvdXRlLnBhdGg7XG4gICAgICAgICAgICByb3V0ZS5wYXRoID0gYCR7cGF0aE5vUGFyYW1zfS86JHtHcm91cE5hdmlnYXRpb25Db25zdGFudHMuR1JPVVBfTkFWSUdBVElPTl9ST1VURVJfUEFSQU19YDtcbiAgICAgICAgICAgIHJvdXRlLmNhbkFjdGl2YXRlID0gW0F1dGhlbnRpY2F0aW9uR3VhcmRTZXJ2aWNlXTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudFBhdGhTZWdtZW50cyA9IGFuY2VzdG9ycy5tYXAoYSA9PiBhLnBhdGgpO1xuICAgICAgICAgICAgcGFyZW50UGF0aFNlZ21lbnRzLnB1c2gocGF0aE5vUGFyYW1zKTtcbiAgICAgICAgICAgIHRoaXMuX2R5bmFtaWNOYXZpZ2F0aW9uUm91dGVTZXJ2aWNlLnJvdXRlID0gcGFyZW50UGF0aFNlZ21lbnRzLmpvaW4oJy8nKTtcblxuICAgICAgICAgICAgdGhpcy5fZ3JvdXBOYXZpZ2F0aW9uUm91dGVHZW5lcmF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIHJvdXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZpZXcucm91dGluZy5tYXRjaCAhPT0gdW5kZWZpbmVkICYmIHZpZXcucm91dGluZy5tYXRjaCkge1xuICAgICAgICAgICAgcm91dGVbJ3BhdGhNYXRjaCddID0gJ2Z1bGwnO1xuICAgICAgICB9XG4gICAgICAgIHJvdXRlWydjYW5BY3RpdmF0ZSddID0gW107XG4gICAgICAgIGlmICh2aWV3LmFjY2VzcyA9PT0gJ3ByaXZhdGUnXG4gICAgICAgICAgICB8fCB2aWV3LmFjY2Vzcy5oYXNPd25Qcm9wZXJ0eSgncm9sZScpXG4gICAgICAgICAgICB8fCB2aWV3LmFjY2Vzcy5oYXNPd25Qcm9wZXJ0eSgnZ3JvdXAnKVxuICAgICAgICAgICAgfHwgdmlldy5hY2Nlc3MuaGFzT3duUHJvcGVydHkoJ2F1dGhvcml0eScpKSB7XG4gICAgICAgICAgICByb3V0ZVsnY2FuQWN0aXZhdGUnXS5wdXNoKEF1dGhlbnRpY2F0aW9uR3VhcmRTZXJ2aWNlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlldy5hY2Nlc3MuaGFzT3duUHJvcGVydHkoJ3JvbGUnKSkge1xuICAgICAgICAgICAgcm91dGVbJ2NhbkFjdGl2YXRlJ10ucHVzaChSb2xlR3VhcmRTZXJ2aWNlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlldy5hY2Nlc3MuaGFzT3duUHJvcGVydHkoJ2F1dGhvcml0eScpKSB7XG4gICAgICAgICAgICByb3V0ZVsnY2FuQWN0aXZhdGUnXS5wdXNoKEF1dGhvcml0eUd1YXJkU2VydmljZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpZXcuYWNjZXNzLmhhc093blByb3BlcnR5KCdncm91cCcpKSB7XG4gICAgICAgICAgICByb3V0ZVsnY2FuQWN0aXZhdGUnXS5wdXNoKEdyb3VwR3VhcmRTZXJ2aWNlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF2aWV3LmNoaWxkcmVuKSB7XG4gICAgICAgICAgICByb3V0ZVsnY2hpbGRyZW4nXSA9IFtdO1xuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXModmlldy5jaGlsZHJlbikuZm9yRWFjaCgoW2NvbmZpZ1BhdGhTZWdtZW50LCBjaGlsZFZpZXddKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETyBjaGVjayBpZiByb3V0ZXMgYXJlIGNvbnN0cnVjdGVkIGNvcnJlY3RseSByZWdhcmRpbmcgZW1wdHkgcm91dGUgc2VnbWVudHNcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZFJvdXRlID0gdGhpcy5jb25zdHJ1Y3RSb3V0ZU9iamVjdChjaGlsZFZpZXcsIGAke2NvbmZpZ1BhdGh9LyR7Y29uZmlnUGF0aFNlZ21lbnR9YCwgWy4uLmFuY2VzdG9ycywgcm91dGVdKTtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGRSb3V0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJvdXRlWydjaGlsZHJlbiddLnB1c2goY2hpbGRSb3V0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpZXc/LmxheW91dD8ubmFtZSA9PT0gJ3RhYlZpZXcnKSB7XG4gICAgICAgICAgICBpZiAoIXZpZXcuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICByb3V0ZVsnY2hpbGRyZW4nXSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcm91dGVbJ2NoaWxkcmVuJ10ucHVzaCh7XG4gICAgICAgICAgICAgICAgcGF0aDogJyoqJyxcbiAgICAgICAgICAgICAgICBjb21wb25lbnRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJvdXRlO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzb2x2ZUNvbXBvbmVudENsYXNzKHZpZXc6IFZpZXcsIGNvbmZpZ1BhdGg6IHN0cmluZyk6IFR5cGU8YW55PiB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXN1bHQ7XG4gICAgICAgIGlmICghIXZpZXcuY29tcG9uZW50KSB7XG4gICAgICAgICAgICByZXN1bHQgPSB0aGlzLl92aWV3U2VydmljZS5yZXNvbHZlTmFtZVRvQ2xhc3Modmlldy5jb21wb25lbnQuY2xhc3MpO1xuICAgICAgICB9IGVsc2UgaWYgKCEhdmlldy5sYXlvdXQpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMucmVzb2x2ZUNvbXBvbmVudENsYXNzRnJvbUxheW91dCh2aWV3LCBjb25maWdQYXRoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2xvZ2dlci53YXJuKGBuYWUuanNvbiBjb25maWd1cmF0aW9uIGlzIGludmFsaWQuIFZpZXcgYXQgcGF0aCAnJHtjb25maWdQYXRofSdgICtcbiAgICAgICAgICAgICAgICBgIG11c3QgZGVmaW5lIGVpdGhlciBhICdsYXlvdXQnIG9yIGEgJ2NvbXBvbmVudCcgYXR0cmlidXRlLiBTa2lwcGluZyB0aGlzIHZpZXcgZm9yIHJvdXRpbmcgZ2VuZXJhdGlvbi5gKTtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2dnZXIud2FybihgU29tZSB2aWV3cyBmcm9tIG5hZS5qc29uIGNvbmZpZ3VyYXRpb24gaGF2ZSBub3QgYmVlbiBjcmVhdGVkIGluIHRoZSBwcm9qZWN0LmAgK1xuICAgICAgICAgICAgICAgIGAgUnVuIGNyZWF0ZS12aWV3IHNjaGVtYXRpYyB0byByZWN0aWZ5IHRoaXMuIFNraXBwaW5nIHRoaXMgdmlldyBmb3Igcm91dGluZyBnZW5lcmF0aW9uLmApO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzb2x2ZUNvbXBvbmVudENsYXNzRnJvbUxheW91dCh2aWV3OiBWaWV3LCBjb25maWdQYXRoOiBzdHJpbmcpOiBUeXBlPGFueT4gfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAodmlldy5sYXlvdXQubmFtZSA9PT0gR3JvdXBOYXZpZ2F0aW9uQ29uc3RhbnRzLkdST1VQX05BVklHQVRJT05fT1VUTEVUKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ3JvdXBOYXZpZ2F0aW9uQ29tcG9uZW50UmVzb2x2ZXJDb21wb25lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBSb3V0aW5nQnVpbGRlclNlcnZpY2UucGFyc2VDbGFzc05hbWVGcm9tVmlldyh2aWV3LCBjb25maWdQYXRoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZpZXdTZXJ2aWNlLnJlc29sdmVOYW1lVG9DbGFzcyhjbGFzc05hbWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgcGFyc2VDbGFzc05hbWVGcm9tVmlldyh2aWV3OiBWaWV3LCBjb25maWdQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAoISF2aWV3LmxheW91dC5jb21wb25lbnROYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7Y2xhc3NpZnkodmlldy5sYXlvdXQuY29tcG9uZW50TmFtZSl9Q29tcG9uZW50YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzSW5mbyA9IG5ldyBWaWV3Q2xhc3NJbmZvKGNvbmZpZ1BhdGgsIHZpZXcubGF5b3V0Lm5hbWUsIHZpZXcubGF5b3V0LmNvbXBvbmVudE5hbWUpO1xuICAgICAgICAgICAgcmV0dXJuIGNsYXNzSW5mby5jbGFzc05hbWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRlZmF1bHRSb3V0ZXNSZWRpcmVjdHMoKTogQXJyYXk8Um91dGU+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGNvbnN0IHNlcnZpY2VzQ29uZmlnID0gdGhpcy5fY29uZmlnU2VydmljZS5nZXRTZXJ2aWNlc0NvbmZpZ3VyYXRpb24oKTtcbiAgICAgICAgaWYgKCEhc2VydmljZXNDb25maWcgJiYgISFzZXJ2aWNlc0NvbmZpZy5yb3V0aW5nKSB7XG4gICAgICAgICAgICBpZiAoISFzZXJ2aWNlc0NvbmZpZy5yb3V0aW5nLmRlZmF1bHRSZWRpcmVjdCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0VG86IHNlcnZpY2VzQ29uZmlnLnJvdXRpbmcuZGVmYXVsdFJlZGlyZWN0LFxuICAgICAgICAgICAgICAgICAgICBwYXRoTWF0Y2g6ICdmdWxsJ1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhc2VydmljZXNDb25maWcucm91dGluZy53aWxkY2FyZFJlZGlyZWN0KSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiAnKionLFxuICAgICAgICAgICAgICAgICAgICByZWRpcmVjdFRvOiBzZXJ2aWNlc0NvbmZpZy5yb3V0aW5nLndpbGRjYXJkUmVkaXJlY3RcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn1cbiJdfQ==