UNPKG

@netgrif/components-core

Version:

Netgrif Application engine frontend core Angular library

239 lines 35.1 kB
import { Component, Input } from '@angular/core'; import { NestedTreeControl } from '@angular/cdk/tree'; import { NavigationEnd } from '@angular/router'; import { MatTreeNestedDataSource } from '@angular/material/tree'; import { ReplaySubject } from 'rxjs'; import { AbstractNavigationResizableDrawerComponent } from '../navigation-drawer/abstract-navigation-resizable-drawer.component'; import { debounceTime, filter } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../../configuration/configuration.service"; import * as i2 from "@angular/router"; import * as i3 from "../../logger/services/logger.service"; import * as i4 from "../../user/services/user.service"; import * as i5 from "../../authorization/permission/access.service"; import * as i6 from "../../groups/services/active-group.service"; import * as i7 from "../../resources/engine-endpoint/task-resource.service"; import * as i8 from "../../translate/language.service"; import * as i9 from "../../routing/dynamic-navigation-route-provider/dynamic-navigation-route-provider.service"; export class AbstractNavigationTreeComponent extends AbstractNavigationResizableDrawerComponent { _config; _router; _log; _userService; _accessService; _activeGroupService; _taskResourceService; _languageService; _navigationRouteProvider; viewPath; parentUrl; routerChange; _reloadNavigation; _subscriptions; _subGroupResolution; _subLangChange; treeControl; dataSource; constructor(_config, _router, _log, _userService, _accessService, _activeGroupService, _taskResourceService, _languageService, _navigationRouteProvider) { super(); this._config = _config; this._router = _router; this._log = _log; this._userService = _userService; this._accessService = _accessService; this._activeGroupService = _activeGroupService; this._taskResourceService = _taskResourceService; this._languageService = _languageService; this._navigationRouteProvider = _navigationRouteProvider; this.treeControl = new NestedTreeControl(node => node.children); this.dataSource = new MatTreeNestedDataSource(); this.dataSource.data = this.resolveNavigationNodes(_config.getConfigurationSubtree(['views']), ''); this.resolveLevels(this.dataSource.data); this._reloadNavigation = new ReplaySubject(1); } ngOnInit() { super.ngOnInit(); if (this.viewPath && this.parentUrl !== undefined && this.routerChange) { this.resolveNavigationNodesWithOffsetRoot(); } this._subscriptions = [ this._router.events.pipe(filter(event => event instanceof NavigationEnd && this.routerChange)) .subscribe(() => this._reloadNavigation.next()), this._userService.user$.subscribe(() => this._reloadNavigation.next()), this._activeGroupService.activeGroups$.subscribe(() => this._reloadNavigation.next()) ]; this._subscriptions.push(this._reloadNavigation.pipe(debounceTime(100)).subscribe(() => { this.resolveNavigation(); })); } ngOnDestroy() { for (const sub of this._subscriptions) { if (!sub.closed) { sub.unsubscribe(); } } this._reloadNavigation.complete(); if (this._subGroupResolution !== undefined) { this._subGroupResolution.unsubscribe(); } if (this._subLangChange !== undefined) { this._subLangChange.unsubscribe(); } } hasChild(_, node) { return !!node.children && node.children.length > 0; } resolveNavigation() { let nodes; if (this.viewPath && this.parentUrl !== undefined && this.routerChange) { nodes = this.resolveNavigationNodesWithOffsetRoot(); } else { nodes = this.resolveNavigationNodes(this._config.getConfigurationSubtree(['views']), ''); } this.dataSource.data = nodes; this.resolveLevels(this.dataSource.data); } resolveNavigationNodesWithOffsetRoot() { const view = this._config.getViewByPath(this.viewPath); if (view && view.children) { return this.resolveNavigationNodes(view.children, this.parentUrl); } return this.dataSource.data; } /** * Converts the provided {@link Views} object into the corresponding navigation tree * @param views navigation configuration * @param parentUrl URL of the parent navigation tree node * @param ancestorNodeContainer if the parent node has no navigation this attribute contains the * closest ancestor that has navigation * @protected */ resolveNavigationNodes(views, parentUrl, ancestorNodeContainer) { if (!views || Object.keys(views).length === 0) { return null; } const nodes = []; Object.keys(views).forEach((viewKey) => { const view = views[viewKey]; if (!this.hasNavigation(view) && !this.hasSubRoutes(view)) { return; // continue } const routeSegment = this.getNodeRouteSegment(view); if (routeSegment === undefined) { throw new Error('Route segment doesnt exist in view ' + parentUrl + '/' + viewKey + ' !'); } if (!this._accessService.canAccessView(view, this.appendRouteSegment(parentUrl, routeSegment))) { return; // continue } if (this.hasNavigation(view)) { const node = this.buildNode(view, routeSegment, parentUrl); if (this.hasSubRoutes(view)) { node.children = this.resolveNavigationNodes(view.children, node.url); } nodes.push(node); } else { if (this.hasSubRoutes(view)) { nodes.push(...this.resolveNavigationNodes(view.children, this.appendRouteSegment(parentUrl, routeSegment), ancestorNodeContainer ?? nodes)); } } }); return nodes; } hasNavigation(route) { if (!route.navigation) { return false; } if (typeof route.navigation === 'boolean') { return route.navigation; } if (typeof route.navigation === 'object') { return Object.keys(route.navigation).length !== 0; } } hasSubRoutes(route) { if (!route.children) { return false; } if (typeof route.children === 'object') { return Object.keys(route.children).length !== 0; } } buildNode(view, routeSegment, parentUrl) { const node = { name: null, url: null }; node.name = this.getNodeName(view, routeSegment); node.icon = this.getNodeIcon(view); node.url = this.appendRouteSegment(parentUrl, routeSegment); node.translate = this.getNodeTranslateFlag(view); return node; } getNodeName(view, routeSegment) { if (view.navigation['title']) { return view.navigation['title']; } const str = routeSegment.replace('_', ' '); return str.charAt(0).toUpperCase() + str.substring(1); } getNodeIcon(view) { return !view.navigation['icon'] ? undefined : view.navigation['icon']; } /** * @param view configuration of some view, whose routeSegment we want to determine * @returns the routeSegment for the provided view, or undefined if none is specified */ getNodeRouteSegment(view) { return !!view.routing && (typeof view.routing.path === 'string') ? view.routing.path : undefined; } getNodeTranslateFlag(view) { return view.navigation['translate'] ?? false; } /** * Appends the route segment to the parent URL. * @param parentUrl URL of the parent. Should not end with '/' * @param routeSegment URL segment of the child * @returns `parentUrl/routeSegment` if the `routeSegment` is truthy (not an empty string). * Returns `parentUrl` if `routeSegment` is falsy (empty string). */ appendRouteSegment(parentUrl, routeSegment) { return routeSegment ? parentUrl + '/' + routeSegment : parentUrl; } resolveLevels(nodes, parentLevel) { if (!nodes) { return; } const currentLevel = parentLevel === null || parentLevel === undefined ? 0 : parentLevel + 1; nodes.forEach(node => { node.level = currentLevel; if (node.children) { this.resolveLevels(node.children, currentLevel); } }); } resolveChange() { const view = this._config.getViewByPath(this.viewPath); if (view && view.children) { this.dataSource.data = this.resolveNavigationNodes(view.children, this.parentUrl); } this.resolveLevels(this.dataSource.data); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AbstractNavigationTreeComponent, deps: [{ token: i1.ConfigurationService }, { token: i2.Router }, { token: i3.LoggerService }, { token: i4.UserService }, { token: i5.AccessService }, { token: i6.ActiveGroupService }, { token: i7.TaskResourceService }, { token: i8.LanguageService }, { token: i9.DynamicNavigationRouteProviderService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AbstractNavigationTreeComponent, selector: "ncc-abstract-navigation-tree", inputs: { viewPath: "viewPath", parentUrl: "parentUrl", routerChange: "routerChange" }, usesInheritance: true, ngImport: i0, template: '', isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AbstractNavigationTreeComponent, decorators: [{ type: Component, args: [{ selector: 'ncc-abstract-navigation-tree', template: '' }] }], ctorParameters: () => [{ type: i1.ConfigurationService }, { type: i2.Router }, { type: i3.LoggerService }, { type: i4.UserService }, { type: i5.AccessService }, { type: i6.ActiveGroupService }, { type: i7.TaskResourceService }, { type: i8.LanguageService }, { type: i9.DynamicNavigationRouteProviderService }], propDecorators: { viewPath: [{ type: Input }], parentUrl: [{ type: Input }], routerChange: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3QtbmF2aWdhdGlvbi10cmVlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy1jb3JlL3NyYy9saWIvbmF2aWdhdGlvbi9uYXZpZ2F0aW9uLXRyZWUvYWJzdHJhY3QtbmF2aWdhdGlvbi10cmVlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsU0FBUyxFQUFFLEtBQUssRUFBb0IsTUFBTSxlQUFlLENBQUM7QUFDbEUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFHcEQsT0FBTyxFQUFDLGFBQWEsRUFBUyxNQUFNLGlCQUFpQixDQUFDO0FBQ3RELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQy9ELE9BQU8sRUFBQyxhQUFhLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFHakQsT0FBTyxFQUNILDBDQUEwQyxFQUM3QyxNQUFNLHFFQUFxRSxDQUFDO0FBRTdFLE9BQU8sRUFBQyxZQUFZLEVBQUUsTUFBTSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7O0FBcUJwRCxNQUFNLE9BQWdCLCtCQUFnQyxTQUFRLDBDQUEwQztJQWVwRTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFyQmhCLFFBQVEsQ0FBUztJQUNqQixTQUFTLENBQVM7SUFDbEIsWUFBWSxDQUFVO0lBRTVCLGlCQUFpQixDQUFzQjtJQUV6QyxjQUFjLENBQXNCO0lBQ3BDLG1CQUFtQixDQUFlO0lBQ2xDLGNBQWMsQ0FBZTtJQUVyQyxXQUFXLENBQW9DO0lBQy9DLFVBQVUsQ0FBMEM7SUFFcEQsWUFBZ0MsT0FBNkIsRUFDN0IsT0FBZSxFQUNmLElBQW1CLEVBQ25CLFlBQXlCLEVBQ3pCLGNBQTZCLEVBQzdCLG1CQUF1QyxFQUN2QyxvQkFBeUMsRUFD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LENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNyRjtRQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDO3dHQXJPaUIsK0JBQStCOzRGQUEvQiwrQkFBK0IsbUxBRnZDLEVBQUU7OzRGQUVNLCtCQUErQjtrQkFKcEQsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsOEJBQThCO29CQUN4QyxRQUFRLEVBQUUsRUFBRTtpQkFDZjtxVkFHbUIsUUFBUTtzQkFBdkIsS0FBSztnQkFDVSxTQUFTO3NCQUF4QixLQUFLO2dCQUNVLFlBQVk7c0JBQTNCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7TmVzdGVkVHJlZUNvbnRyb2x9IGZyb20gJ0Bhbmd1bGFyL2Nkay90cmVlJztcbmltcG9ydCB7Q29uZmlndXJhdGlvblNlcnZpY2V9IGZyb20gJy4uLy4uL2NvbmZpZ3VyYXRpb24vY29uZmlndXJhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7VmlldywgVmlld3N9IGZyb20gJy4uLy4uLy4uL2NvbW1vbnMvc2NoZW1hJztcbmltcG9ydCB7TmF2aWdhdGlvbkVuZCwgUm91dGVyfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtNYXRUcmVlTmVzdGVkRGF0YVNvdXJjZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdHJlZSc7XG5pbXBvcnQge1JlcGxheVN1YmplY3QsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge0xvZ2dlclNlcnZpY2V9IGZyb20gJy4uLy4uL2xvZ2dlci9zZXJ2aWNlcy9sb2dnZXIuc2VydmljZSc7XG5pbXBvcnQge1VzZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi91c2VyL3NlcnZpY2VzL3VzZXIuc2VydmljZSc7XG5pbXBvcnQge1xuICAgIEFic3RyYWN0TmF2aWdhdGlvblJlc2l6YWJsZURyYXdlckNvbXBvbmVudFxufSBmcm9tICcuLi9uYXZpZ2F0aW9uLWRyYXdlci9hYnN0cmFjdC1uYXZpZ2F0aW9uLXJlc2l6YWJsZS1kcmF3ZXIuY29tcG9uZW50JztcbmltcG9ydCB7QWN0aXZlR3JvdXBTZXJ2aWNlfSBmcm9tICcuLi8uLi9ncm91cHMvc2VydmljZXMvYWN0aXZlLWdyb3VwLnNlcnZpY2UnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGZpbHRlcn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUYXNrUmVzb3VyY2VTZXJ2aWNlfSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvZW5naW5lLWVuZHBvaW50L3Rhc2stcmVzb3VyY2Uuc2VydmljZSc7XG5pbXBvcnQge0xhbmd1YWdlU2VydmljZX0gZnJvbSAnLi4vLi4vdHJhbnNsYXRlL2xhbmd1YWdlLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgICBEeW5hbWljTmF2aWdhdGlvblJvdXRlUHJvdmlkZXJTZXJ2aWNlXG59IGZyb20gJy4uLy4uL3JvdXRpbmcvZHluYW1pYy1uYXZpZ2F0aW9uLXJvdXRlLXByb3ZpZGVyL2R5bmFtaWMtbmF2aWdhdGlvbi1yb3V0ZS1wcm92aWRlci5zZXJ2aWNlJztcbmltcG9ydCB7QWNjZXNzU2VydmljZX0gZnJvbSBcIi4uLy4uL2F1dGhvcml6YXRpb24vcGVybWlzc2lvbi9hY2Nlc3Muc2VydmljZVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5hdmlnYXRpb25Ob2RlIHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgaWNvbj86IHN0cmluZztcbiAgICB1cmw6IHN0cmluZztcbiAgICBjaGlsZHJlbj86IEFycmF5PE5hdmlnYXRpb25Ob2RlPjtcbiAgICBsZXZlbD86IG51bWJlcjtcbiAgICB0cmFuc2xhdGU/OiBib29sZWFuO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25jYy1hYnN0cmFjdC1uYXZpZ2F0aW9uLXRyZWUnLFxuICAgIHRlbXBsYXRlOiAnJ1xufSlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE5hdmlnYXRpb25UcmVlQ29tcG9uZW50IGV4dGVuZHMgQWJzdHJhY3ROYXZpZ2F0aW9uUmVzaXphYmxlRHJhd2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgQElucHV0KCkgcHVibGljIHZpZXdQYXRoOiBzdHJpbmc7XG4gICAgQElucHV0KCkgcHVibGljIHBhcmVudFVybDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHB1YmxpYyByb3V0ZXJDaGFuZ2U6IGJvb2xlYW47XG5cbiAgICBwcm90ZWN0ZWQgX3JlbG9hZE5hdmlnYXRpb246IFJlcGxheVN1YmplY3Q8dm9pZD47XG5cbiAgICBwcml2YXRlIF9zdWJzY3JpcHRpb25zOiBBcnJheTxTdWJzY3JpcHRpb24+O1xuICAgIHByaXZhdGUgX3N1Ykdyb3VwUmVzb2x1dGlvbjogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgX3N1YkxhbmdDaGFuZ2U6IFN1YnNjcmlwdGlvbjtcblxuICAgIHRyZWVDb250cm9sOiBOZXN0ZWRUcmVlQ29udHJvbDxOYXZpZ2F0aW9uTm9kZT47XG4gICAgZGF0YVNvdXJjZTogTWF0VHJlZU5lc3RlZERhdGFTb3VyY2U8TmF2aWdhdGlvbk5vZGU+O1xuXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfY29uZmlnOiBDb25maWd1cmF0aW9uU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9yb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9sb2c6IExvZ2dlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdXNlclNlcnZpY2U6IFVzZXJTZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2FjY2Vzc1NlcnZpY2U6IEFjY2Vzc1NlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfYWN0aXZlR3JvdXBTZXJ2aWNlOiBBY3RpdmVHcm91cFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfdGFza1Jlc291cmNlU2VydmljZTogVGFza1Jlc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9sYW5ndWFnZVNlcnZpY2U6IExhbmd1YWdlU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9uYXZpZ2F0aW9uUm91dGVQcm92aWRlcjogRHluYW1pY05hdmlnYXRpb25Sb3V0ZVByb3ZpZGVyU2VydmljZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnRyZWVDb250cm9sID0gbmV3IE5lc3RlZFRyZWVDb250cm9sPE5hdmlnYXRpb25Ob2RlPihub2RlID0+IG5vZGUuY2hpbGRyZW4pO1xuICAgICAgICB0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VHJlZU5lc3RlZERhdGFTb3VyY2U8TmF2aWdhdGlvbk5vZGU+KCk7XG4gICAgICAgIHRoaXMuZGF0YVNvdXJjZS5kYXRhID0gdGhpcy5yZXNvbHZlTmF2aWdhdGlvbk5vZGVzKF9jb25maWcuZ2V0Q29uZmlndXJhdGlvblN1YnRyZWUoWyd2aWV3cyddKSwgJycpO1xuICAgICAgICB0aGlzLnJlc29sdmVMZXZlbHModGhpcy5kYXRhU291cmNlLmRhdGEpO1xuICAgICAgICB0aGlzLl9yZWxvYWROYXZpZ2F0aW9uID0gbmV3IFJlcGxheVN1YmplY3Q8dm9pZD4oMSk7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgICAgIGlmICh0aGlzLnZpZXdQYXRoICYmIHRoaXMucGFyZW50VXJsICE9PSB1bmRlZmluZWQgJiYgdGhpcy5yb3V0ZXJDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlc1dpdGhPZmZzZXRSb290KCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9zdWJzY3JpcHRpb25zID0gW1xuICAgICAgICAgICAgdGhpcy5fcm91dGVyLmV2ZW50cy5waXBlKGZpbHRlcihldmVudCA9PiBldmVudCBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQgJiYgdGhpcy5yb3V0ZXJDaGFuZ2UpKVxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fcmVsb2FkTmF2aWdhdGlvbi5uZXh0KCkpLFxuICAgICAgICAgICAgdGhpcy5fdXNlclNlcnZpY2UudXNlciQuc3Vic2NyaWJlKCgpID0+IHRoaXMuX3JlbG9hZE5hdmlnYXRpb24ubmV4dCgpKSxcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZUdyb3VwU2VydmljZS5hY3RpdmVHcm91cHMkLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yZWxvYWROYXZpZ2F0aW9uLm5leHQoKSlcbiAgICAgICAgXTtcblxuICAgICAgICB0aGlzLl9zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAgICAgICB0aGlzLl9yZWxvYWROYXZpZ2F0aW9uLnBpcGUoZGVib3VuY2VUaW1lKDEwMCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlTmF2aWdhdGlvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgZm9yIChjb25zdCBzdWIgb2YgdGhpcy5fc3Vic2NyaXB0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFzdWIuY2xvc2VkKSB7XG4gICAgICAgICAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcmVsb2FkTmF2aWdhdGlvbi5jb21wbGV0ZSgpO1xuICAgICAgICBpZiAodGhpcy5fc3ViR3JvdXBSZXNvbHV0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N1Ykdyb3VwUmVzb2x1dGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9zdWJMYW5nQ2hhbmdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N1YkxhbmdDaGFuZ2UudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBoYXNDaGlsZChfOiBudW1iZXIsIG5vZGU6IE5hdmlnYXRpb25Ob2RlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIW5vZGUuY2hpbGRyZW4gJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZXNvbHZlTmF2aWdhdGlvbigpOiB2b2lkIHtcbiAgICAgICAgbGV0IG5vZGVzO1xuICAgICAgICBpZiAodGhpcy52aWV3UGF0aCAmJiB0aGlzLnBhcmVudFVybCAhPT0gdW5kZWZpbmVkICYmIHRoaXMucm91dGVyQ2hhbmdlKSB7XG4gICAgICAgICAgICBub2RlcyA9IHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlc1dpdGhPZmZzZXRSb290KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBub2RlcyA9IHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlcyh0aGlzLl9jb25maWcuZ2V0Q29uZmlndXJhdGlvblN1YnRyZWUoWyd2aWV3cyddKSwgJycpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGF0YVNvdXJjZS5kYXRhID0gbm9kZXM7XG4gICAgICAgIHRoaXMucmVzb2x2ZUxldmVscyh0aGlzLmRhdGFTb3VyY2UuZGF0YSk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlc29sdmVOYXZpZ2F0aW9uTm9kZXNXaXRoT2Zmc2V0Um9vdCgpOiBBcnJheTxOYXZpZ2F0aW9uTm9kZT4ge1xuICAgICAgICBjb25zdCB2aWV3ID0gdGhpcy5fY29uZmlnLmdldFZpZXdCeVBhdGgodGhpcy52aWV3UGF0aCk7XG4gICAgICAgIGlmICh2aWV3ICYmIHZpZXcuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVOYXZpZ2F0aW9uTm9kZXModmlldy5jaGlsZHJlbiwgdGhpcy5wYXJlbnRVcmwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFTb3VyY2UuZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgcHJvdmlkZWQge0BsaW5rIFZpZXdzfSBvYmplY3QgaW50byB0aGUgY29ycmVzcG9uZGluZyBuYXZpZ2F0aW9uIHRyZWVcbiAgICAgKiBAcGFyYW0gdmlld3MgbmF2aWdhdGlvbiBjb25maWd1cmF0aW9uXG4gICAgICogQHBhcmFtIHBhcmVudFVybCBVUkwgb2YgdGhlIHBhcmVudCBuYXZpZ2F0aW9uIHRyZWUgbm9kZVxuICAgICAqIEBwYXJhbSBhbmNlc3Rvck5vZGVDb250YWluZXIgaWYgdGhlIHBhcmVudCBub2RlIGhhcyBubyBuYXZpZ2F0aW9uIHRoaXMgYXR0cmlidXRlIGNvbnRhaW5zIHRoZVxuICAgICAqIGNsb3Nlc3QgYW5jZXN0b3IgdGhhdCBoYXMgbmF2aWdhdGlvblxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVzb2x2ZU5hdmlnYXRpb25Ob2RlcyhcbiAgICAgICAgdmlld3M6IFZpZXdzLFxuICAgICAgICBwYXJlbnRVcmw6IHN0cmluZyxcbiAgICAgICAgYW5jZXN0b3JOb2RlQ29udGFpbmVyPzogQXJyYXk8TmF2aWdhdGlvbk5vZGU+XG4gICAgKTogQXJyYXk8TmF2aWdhdGlvbk5vZGU+IHtcbiAgICAgICAgaWYgKCF2aWV3cyB8fCBPYmplY3Qua2V5cyh2aWV3cykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5vZGVzOiBBcnJheTxOYXZpZ2F0aW9uTm9kZT4gPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXModmlld3MpLmZvckVhY2goKHZpZXdLZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmlldyA9IHZpZXdzW3ZpZXdLZXldO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuaGFzTmF2aWdhdGlvbih2aWV3KSAmJiAhdGhpcy5oYXNTdWJSb3V0ZXModmlldykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47IC8vIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByb3V0ZVNlZ21lbnQgPSB0aGlzLmdldE5vZGVSb3V0ZVNlZ21lbnQodmlldyk7XG5cbiAgICAgICAgICAgIGlmIChyb3V0ZVNlZ21lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUm91dGUgc2VnbWVudCBkb2VzbnQgZXhpc3QgaW4gdmlldyAnICsgcGFyZW50VXJsICsgJy8nICsgdmlld0tleSArICcgIScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRoaXMuX2FjY2Vzc1NlcnZpY2UuY2FuQWNjZXNzVmlldyh2aWV3LCB0aGlzLmFwcGVuZFJvdXRlU2VnbWVudChwYXJlbnRVcmwsIHJvdXRlU2VnbWVudCkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBjb250aW51ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5oYXNOYXZpZ2F0aW9uKHZpZXcpKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgbm9kZTogTmF2aWdhdGlvbk5vZGUgPSB0aGlzLmJ1aWxkTm9kZSh2aWV3LCByb3V0ZVNlZ21lbnQsIHBhcmVudFVybCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFzU3ViUm91dGVzKHZpZXcpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSB0aGlzLnJlc29sdmVOYXZpZ2F0aW9uTm9kZXModmlldy5jaGlsZHJlbiwgbm9kZS51cmwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBub2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNTdWJSb3V0ZXModmlldykpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZXMucHVzaCguLi50aGlzLnJlc29sdmVOYXZpZ2F0aW9uTm9kZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3LmNoaWxkcmVuLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBlbmRSb3V0ZVNlZ21lbnQocGFyZW50VXJsLCByb3V0ZVNlZ21lbnQpLCBhbmNlc3Rvck5vZGVDb250YWluZXIgPz8gbm9kZXMpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBoYXNOYXZpZ2F0aW9uKHJvdXRlOiBWaWV3KTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghcm91dGUubmF2aWdhdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygcm91dGUubmF2aWdhdGlvbiA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gcm91dGUubmF2aWdhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHJvdXRlLm5hdmlnYXRpb24gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMocm91dGUubmF2aWdhdGlvbikubGVuZ3RoICE9PSAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGhhc1N1YlJvdXRlcyhyb3V0ZTogVmlldyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXJvdXRlLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiByb3V0ZS5jaGlsZHJlbiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhyb3V0ZS5jaGlsZHJlbikubGVuZ3RoICE9PSAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGJ1aWxkTm9kZSh2aWV3OiBWaWV3LCByb3V0ZVNlZ21lbnQ6IHN0cmluZywgcGFyZW50VXJsOiBzdHJpbmcpOiBOYXZpZ2F0aW9uTm9kZSB7XG4gICAgICAgIGNvbnN0IG5vZGU6IE5hdmlnYXRpb25Ob2RlID0ge1xuICAgICAgICAgICAgbmFtZTogbnVsbCxcbiAgICAgICAgICAgIHVybDogbnVsbFxuICAgICAgICB9O1xuICAgICAgICBub2RlLm5hbWUgPSB0aGlzLmdldE5vZGVOYW1lKHZpZXcsIHJvdXRlU2VnbWVudCk7XG4gICAgICAgIG5vZGUuaWNvbiA9IHRoaXMuZ2V0Tm9kZUljb24odmlldyk7XG4gICAgICAgIG5vZGUudXJsID0gdGhpcy5hcHBlbmRSb3V0ZVNlZ21lbnQocGFyZW50VXJsLCByb3V0ZVNlZ21lbnQpO1xuICAgICAgICBub2RlLnRyYW5zbGF0ZSA9IHRoaXMuZ2V0Tm9kZVRyYW5zbGF0ZUZsYWcodmlldyk7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXROb2RlTmFtZSh2aWV3OiBWaWV3LCByb3V0ZVNlZ21lbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICh2aWV3Lm5hdmlnYXRpb25bJ3RpdGxlJ10pIHtcbiAgICAgICAgICAgIHJldHVybiB2aWV3Lm5hdmlnYXRpb25bJ3RpdGxlJ107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyID0gcm91dGVTZWdtZW50LnJlcGxhY2UoJ18nLCAnICcpO1xuICAgICAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnN1YnN0cmluZygxKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0Tm9kZUljb24odmlldzogVmlldyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAhdmlldy5uYXZpZ2F0aW9uWydpY29uJ10gPyB1bmRlZmluZWQgOiB2aWV3Lm5hdmlnYXRpb25bJ2ljb24nXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gdmlldyBjb25maWd1cmF0aW9uIG9mIHNvbWUgdmlldywgd2hvc2Ugcm91dGVTZWdtZW50IHdlIHdhbnQgdG8gZGV0ZXJtaW5lXG4gICAgICogQHJldHVybnMgdGhlIHJvdXRlU2VnbWVudCBmb3IgdGhlIHByb3ZpZGVkIHZpZXcsIG9yIHVuZGVmaW5lZCBpZiBub25lIGlzIHNwZWNpZmllZFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBnZXROb2RlUm91dGVTZWdtZW50KHZpZXc6IFZpZXcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gISF2aWV3LnJvdXRpbmcgJiYgKHR5cGVvZiB2aWV3LnJvdXRpbmcucGF0aCA9PT0gJ3N0cmluZycpID8gdmlldy5yb3V0aW5nLnBhdGggOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldE5vZGVUcmFuc2xhdGVGbGFnKHZpZXc6IFZpZXcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHZpZXcubmF2aWdhdGlvblsndHJhbnNsYXRlJ10gPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwZW5kcyB0aGUgcm91dGUgc2VnbWVudCB0byB0aGUgcGFyZW50IFVSTC5cbiAgICAgKiBAcGFyYW0gcGFyZW50VXJsIFVSTCBvZiB0aGUgcGFyZW50LiBTaG91bGQgbm90IGVuZCB3aXRoICcvJ1xuICAgICAqIEBwYXJhbSByb3V0ZVNlZ21lbnQgVVJMIHNlZ21lbnQgb2YgdGhlIGNoaWxkXG4gICAgICogQHJldHVybnMgYHBhcmVudFVybC9yb3V0ZVNlZ21lbnRgIGlmIHRoZSBgcm91dGVTZWdtZW50YCBpcyB0cnV0aHkgKG5vdCBhbiBlbXB0eSBzdHJpbmcpLlxuICAgICAqIFJldHVybnMgYHBhcmVudFVybGAgaWYgYHJvdXRlU2VnbWVudGAgaXMgZmFsc3kgKGVtcHR5IHN0cmluZykuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGFwcGVuZFJvdXRlU2VnbWVudChwYXJlbnRVcmw6IHN0cmluZywgcm91dGVTZWdtZW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gcm91dGVTZWdtZW50ID8gcGFyZW50VXJsICsgJy8nICsgcm91dGVTZWdtZW50IDogcGFyZW50VXJsO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZXNvbHZlTGV2ZWxzKG5vZGVzOiBBcnJheTxOYXZpZ2F0aW9uTm9kZT4sIHBhcmVudExldmVsPzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICghbm9kZXMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjdXJyZW50TGV2ZWwgPSBwYXJlbnRMZXZlbCA9PT0gbnVsbCB8fCBwYXJlbnRMZXZlbCA9PT0gdW5kZWZpbmVkID8gMCA6IHBhcmVudExldmVsICsgMTtcbiAgICAgICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgIG5vZGUubGV2ZWwgPSBjdXJyZW50TGV2ZWw7XG4gICAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUxldmVscyhub2RlLmNoaWxkcmVuLCBjdXJyZW50TGV2ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVzb2x2ZUNoYW5nZSgpIHtcbiAgICAgICAgY29uc3QgdmlldyA9IHRoaXMuX2NvbmZpZy5nZXRWaWV3QnlQYXRoKHRoaXMudmlld1BhdGgpO1xuICAgICAgICBpZiAodmlldyAmJiB2aWV3LmNoaWxkcmVuKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFTb3VyY2UuZGF0YSA9IHRoaXMucmVzb2x2ZU5hdmlnYXRpb25Ob2Rlcyh2aWV3LmNoaWxkcmVuLCB0aGlzLnBhcmVudFVybCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXNvbHZlTGV2ZWxzKHRoaXMuZGF0YVNvdXJjZS5kYXRhKTtcbiAgICB9XG59XG4iXX0=