UNPKG

@spartacus/core

Version:

Spartacus - the core framework

137 lines 19.2 kB
import { Injectable, isDevMode } from '@angular/core'; import { Router } from '@angular/router'; import * as i0 from "@angular/core"; import * as i1 from "./routing-config.service"; import * as i2 from "../services/url-matcher.service"; export class ConfigurableRoutesService { constructor(injector, routingConfigService, urlMatcherService) { this.injector = injector; this.routingConfigService = routingConfigService; this.urlMatcherService = urlMatcherService; this.initCalled = false; // guard not to call init() more than once } /** * Enhances existing Angular routes using the routing config of Spartacus. * Can be called only once. */ init() { if (!this.initCalled) { this.initCalled = true; this.configure(); } } /** * Enhances existing Angular routes using the routing config of Spartacus. */ configure() { // Router could not be injected in constructor due to cyclic dependency with APP_INITIALIZER: const router = this.injector.get(Router); router.resetConfig(this.configureRoutes(router.config)); } /** * Sets the property `path` or `matcher` for the given routes, based on the Spartacus' routing configuration. * * @param routes list of Angular `Route` objects */ configureRoutes(routes) { return routes.map((route) => { const configuredRoute = this.configureRoute(route); if (route.children && route.children.length) { configuredRoute.children = this.configureRoutes(route.children); } return configuredRoute; }); } /** * Sets the property `path` or `matcher` of the `Route`, based on the Spartacus' routing configuration. * Uses the property `data.cxRoute` to determine the name of the route. * It's the same name used as a key in the routing configuration: `routing.routes[ROUTE NAME]`. * * @param route Angular `Route` object */ configureRoute(route) { var _a; const routeName = this.getRouteName(route); if (routeName) { const routeConfig = this.routingConfigService.getRouteConfig(routeName); this.validateRouteConfig(routeConfig, routeName, route); if (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.disabled) { delete route.path; return Object.assign(Object.assign({}, route), { matcher: this.urlMatcherService.getFalsy() }); } else if (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.matchers) { delete route.path; return Object.assign(Object.assign({}, route), { matcher: this.resolveUrlMatchers(route, routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.matchers) }); } else if (((_a = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.paths) === null || _a === void 0 ? void 0 : _a.length) === 1) { delete route.matcher; return Object.assign(Object.assign({}, route), { path: routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.paths[0] }); } else { delete route.path; return Object.assign(Object.assign({}, route), { matcher: this.urlMatcherService.getFromPaths((routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.paths) || []) }); } } return route; // if route doesn't have a name, just pass the original route } /** * Creates a single `UrlMatcher` based on given matchers and factories of matchers. * * @param route Route object * @param matchersOrFactories `UrlMatcher`s or injection tokens with a factory functions * that create UrlMatchers based on the given route. */ resolveUrlMatchers(route, matchersOrFactories) { const matchers = matchersOrFactories.map((matcherOrFactory) => { return typeof matcherOrFactory === 'function' ? matcherOrFactory // matcher : this.resolveUrlMatcherFactory(route, matcherOrFactory); // factory injection token }); return this.urlMatcherService.getCombined(matchers); } /** * Creates an `UrlMatcher` based on the given route, using the factory function coming from the given injection token. * * @param route Route object * @param factoryToken injection token with a factory function that will create an UrlMatcher using given route */ resolveUrlMatcherFactory(route, factoryToken) { const factory = this.injector.get(factoryToken); return factory(route); } /** * Returns the name of the Route stored in its property `data.cxRoute` * @param route */ getRouteName(route) { return route.data && route.data.cxRoute; } validateRouteConfig(routeConfig, routeName, route) { if (isDevMode()) { // - null value of routeConfig or routeConfig.paths means explicit switching off the route - it's valid config // - routeConfig with defined `matchers` is valid, even if `paths` are undefined if (routeConfig === null || (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.paths) === null || (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.matchers)) { return; } // undefined value of routeConfig or routeConfig.paths is a misconfiguration if (!(routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.paths)) { this.warn(`Could not configure the named route '${routeName}'`, route, `due to undefined config or undefined 'paths' property for this route`); return; } } } warn(...args) { if (isDevMode()) { console.warn(...args); } } } ConfigurableRoutesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ConfigurableRoutesService, deps: [{ token: i0.Injector }, { token: i1.RoutingConfigService }, { token: i2.UrlMatcherService }], target: i0.ɵɵFactoryTarget.Injectable }); ConfigurableRoutesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ConfigurableRoutesService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ConfigurableRoutesService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.RoutingConfigService }, { type: i2.UrlMatcherService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhYmxlLXJvdXRlcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZS9zcmMvcm91dGluZy9jb25maWd1cmFibGUtcm91dGVzL2NvbmZpZ3VyYWJsZS1yb3V0ZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUE0QixTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEYsT0FBTyxFQUFTLE1BQU0sRUFBc0IsTUFBTSxpQkFBaUIsQ0FBQzs7OztBQU9wRSxNQUFNLE9BQU8seUJBQXlCO0lBQ3BDLFlBQ1ksUUFBa0IsRUFDbEIsb0JBQTBDLEVBQzFDLGlCQUFvQztRQUZwQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xCLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUd0QyxlQUFVLEdBQUcsS0FBSyxDQUFDLENBQUMsMENBQTBDO0lBRnJFLENBQUM7SUFJSjs7O09BR0c7SUFDSCxJQUFJO1FBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDcEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFFdkIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1NBQ2xCO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ08sU0FBUztRQUNqQiw2RkFBNkY7UUFDN0YsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDekMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRDs7OztPQUlHO0lBQ08sZUFBZSxDQUFDLE1BQWM7UUFDdEMsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMs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Q0FBQztJQUVEOzs7T0FHRztJQUNPLFlBQVksQ0FBQyxLQUFZO1FBQ2pDLE9BQU8sS0FBSyxDQUFDLElBQUksSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUMxQyxDQUFDO0lBRVMsbUJBQW1CLENBQzNCLFdBQXdCLEVBQ3hCLFNBQWlCLEVBQ2pCLEtBQVk7UUFFWixJQUFJLFNBQVMsRUFBRSxFQUFFO1lBQ2YsOEdBQThHO1lBQzlHLGdGQUFnRjtZQUNoRixJQUNFLFdBQVcsS0FBSyxJQUFJO2dCQUNwQixDQUFBLFdBQVcsYUFBWCxXQUFXLHVCQUFYLFdBQVcsQ0FBRSxLQUFLLE1BQUssSUFBSTtpQkFDM0IsV0FBVyxhQUFYLFdBQVcsdUJBQVgsV0FBVyxDQUFFLFFBQVEsQ0FBQSxFQUNyQjtnQkFDQSxPQUFPO2FBQ1I7WUFFRCw0RUFBNEU7WUFDNUUsSUFBSSxDQUFDLENBQUEsV0FBVyxhQUFYLFdBQVcsdUJBQVgsV0FBVyxDQUFFLEtBQUssQ0FBQSxFQUFFO2dCQUN2QixJQUFJLENBQUMsSUFBSSxDQUNQLHdDQUF3QyxTQUFTLEdBQUcsRUFDcEQsS0FBSyxFQUNMLHNFQUFzRSxDQUN2RSxDQUFDO2dCQUNGLE9BQU87YUFDUjtTQUNGO0lBQ0gsQ0FBQztJQUVPLElBQUksQ0FBQyxHQUFHLElBQUk7UUFDbEIsSUFBSSxTQUFTLEVBQUUsRUFBRTtZQUNmLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztTQUN2QjtJQUNILENBQUM7O3NIQWxLVSx5QkFBeUI7MEhBQXpCLHlCQUF5QixjQURaLE1BQU07MkZBQ25CLHlCQUF5QjtrQkFEckMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbiwgSW5qZWN0b3IsIGlzRGV2TW9kZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUm91dGUsIFJvdXRlciwgUm91dGVzLCBVcmxNYXRjaGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFVybE1hdGNoZXJTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvdXJsLW1hdGNoZXIuc2VydmljZSc7XG5pbXBvcnQgeyBVcmxNYXRjaGVyRmFjdG9yeSB9IGZyb20gJy4uL3VybC1tYXRjaGVyL3VybC1tYXRjaGVyLWZhY3RvcnknO1xuaW1wb3J0IHsgUm91dGVDb25maWcgfSBmcm9tICcuL3JvdXRlcy1jb25maWcnO1xuaW1wb3J0IHsgUm91dGluZ0NvbmZpZ1NlcnZpY2UgfSBmcm9tICcuL3JvdXRpbmctY29uZmlnLnNlcnZpY2UnO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIENvbmZpZ3VyYWJsZVJvdXRlc1NlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByb3RlY3RlZCByb3V0aW5nQ29uZmlnU2VydmljZTogUm91dGluZ0NvbmZpZ1NlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHVybE1hdGNoZXJTZXJ2aWNlOiBVcmxNYXRjaGVyU2VydmljZVxuICApIHt9XG5cbiAgcHJvdGVjdGVkIGluaXRDYWxsZWQgPSBmYWxzZTsgLy8gZ3VhcmQgbm90IHRvIGNhbGwgaW5pdCgpIG1vcmUgdGhhbiBvbmNlXG5cbiAgLyoqXG4gICAqIEVuaGFuY2VzIGV4aXN0aW5nIEFuZ3VsYXIgcm91dGVzIHVzaW5nIHRoZSByb3V0aW5nIGNvbmZpZyBvZiBTcGFydGFjdXMuXG4gICAqIENhbiBiZSBjYWxsZWQgb25seSBvbmNlLlxuICAgKi9cbiAgaW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5pdENhbGxlZCkge1xuICAgICAgdGhpcy5pbml0Q2FsbGVkID0gdHJ1ZTtcblxuICAgICAgdGhpcy5jb25maWd1cmUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRW5oYW5jZXMgZXhpc3RpbmcgQW5ndWxhciByb3V0ZXMgdXNpbmcgdGhlIHJvdXRpbmcgY29uZmlnIG9mIFNwYXJ0YWN1cy5cbiAgICovXG4gIHByb3RlY3RlZCBjb25maWd1cmUoKTogdm9pZCB7XG4gICAgLy8gUm91dGVyIGNvdWxkIG5vdCBiZSBpbmplY3RlZCBpbiBjb25zdHJ1Y3RvciBkdWUgdG8gY3ljbGljIGRlcGVuZGVuY3kgd2l0aCBBUFBfSU5JVElBTElaRVI6XG4gICAgY29uc3Qgcm91dGVyID0gdGhpcy5pbmplY3Rvci5nZXQoUm91dGVyKTtcbiAgICByb3V0ZXIucmVzZXRDb25maWcodGhpcy5jb25maWd1cmVSb3V0ZXMocm91dGVyLmNvbmZpZykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHByb3BlcnR5IGBwYXRoYCBvciBgbWF0Y2hlcmAgZm9yIHRoZSBnaXZlbiByb3V0ZXMsIGJhc2VkIG9uIHRoZSBTcGFydGFjdXMnIHJvdXRpbmcgY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHJvdXRlcyBsaXN0IG9mIEFuZ3VsYXIgYFJvdXRlYCBvYmplY3RzXG4gICAqL1xuICBwcm90ZWN0ZWQgY29uZmlndXJlUm91dGVzKHJvdXRlczogUm91dGVzKTogUm91dGVzIHtcbiAgICByZXR1cm4gcm91dGVzLm1hcCgocm91dGUpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZ3VyZWRSb3V0ZSA9IHRoaXMuY29uZmlndXJlUm91dGUocm91dGUpO1xuXG4gICAgICBpZiAocm91dGUuY2hpbGRyZW4gJiYgcm91dGUuY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAgIGNvbmZpZ3VyZWRSb3V0ZS5jaGlsZHJlbiA9IHRoaXMuY29uZmlndXJlUm91dGVzKHJvdXRlLmNoaWxkcmVuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb25maWd1cmVkUm91dGU7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgcHJvcGVydHkgYHBhdGhgIG9yIGBtYXRjaGVyYCBvZiB0aGUgYFJvdXRlYCwgYmFzZWQgb24gdGhlIFNwYXJ0YWN1cycgcm91dGluZyBjb25maWd1cmF0aW9uLlxuICAgKiBVc2VzIHRoZSBwcm9wZXJ0eSBgZGF0YS5jeFJvdXRlYCB0byBkZXRlcm1pbmUgdGhlIG5hbWUgb2YgdGhlIHJvdXRlLlxuICAgKiBJdCdzIHRoZSBzYW1lIG5hbWUgdXNlZCBhcyBhIGtleSBpbiB0aGUgcm91dGluZyBjb25maWd1cmF0aW9uOiBgcm91dGluZy5yb3V0ZXNbUk9VVEUgTkFNRV1gLlxuICAgKlxuICAgKiBAcGFyYW0gcm91dGUgQW5ndWxhciBgUm91dGVgIG9iamVjdFxuICAgKi9cbiAgcHJvdGVjdGVkIGNvbmZpZ3VyZVJvdXRlKHJvdXRlOiBSb3V0ZSk6IFJvdXRlIHtcbiAgICBjb25zdCByb3V0ZU5hbWUgPSB0aGlzLmdldFJvdXRlTmFtZShyb3V0ZSk7XG4gICAgaWYgKHJvdXRlTmFtZSkge1xuICAgICAgY29uc3Qgcm91dGVDb25maWcgPSB0aGlzLnJvdXRpbmdDb25maWdTZXJ2aWNlLmdldFJvdXRlQ29uZmlnKHJvdXRlTmFtZSk7XG4gICAgICB0aGlzLnZhbGlkYXRlUm91dGVDb25maWcocm91dGVDb25maWcsIHJvdXRlTmFtZSwgcm91dGUpO1xuXG4gICAgICBpZiAocm91dGVDb25maWc/LmRpc2FibGVkKSB7XG4gICAgICAgIGRlbGV0ZSByb3V0ZS5wYXRoO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnJvdXRlLFxuICAgICAgICAgIG1hdGNoZXI6IHRoaXMudXJsTWF0Y2hlclNlcnZpY2UuZ2V0RmFsc3koKSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAocm91dGVDb25maWc/Lm1hdGNoZXJzKSB7XG4gICAgICAgIGRlbGV0ZSByb3V0ZS5wYXRoO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnJvdXRlLFxuICAgICAgICAgIG1hdGNoZXI6IHRoaXMucmVzb2x2ZVVybE1hdGNoZXJzKHJvdXRlLCByb3V0ZUNvbmZpZz8ubWF0Y2hlcnMpLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIGlmIChyb3V0ZUNvbmZpZz8ucGF0aHM/Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBkZWxldGUgcm91dGUubWF0Y2hlcjtcbiAgICAgICAgcmV0dXJuIHsgLi4ucm91dGUsIHBhdGg6IHJvdXRlQ29uZmlnPy5wYXRoc1swXSB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIHJvdXRlLnBhdGg7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4ucm91dGUsXG4gICAgICAgICAgbWF0Y2hlcjogdGhpcy51cmxNYXRjaGVyU2VydmljZS5nZXRGcm9tUGF0aHMoXG4gICAgICAgICAgICByb3V0ZUNvbmZpZz8ucGF0aHMgfHwgW11cbiAgICAgICAgICApLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcm91dGU7IC8vIGlmIHJvdXRlIGRvZXNuJ3QgaGF2ZSBhIG5hbWUsIGp1c3QgcGFzcyB0aGUgb3JpZ2luYWwgcm91dGVcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc2luZ2xlIGBVcmxNYXRjaGVyYCBiYXNlZCBvbiBnaXZlbiBtYXRjaGVycyBhbmQgZmFjdG9yaWVzIG9mIG1hdGNoZXJzLlxuICAgKlxuICAgKiBAcGFyYW0gcm91dGUgUm91dGUgb2JqZWN0XG4gICAqIEBwYXJhbSBtYXRjaGVyc09yRmFjdG9yaWVzIGBVcmxNYXRjaGVyYHMgb3IgaW5qZWN0aW9uIHRva2VucyB3aXRoIGEgZmFjdG9yeSBmdW5jdGlvbnNcbiAgICogIHRoYXQgY3JlYXRlIFVybE1hdGNoZXJzIGJhc2VkIG9uIHRoZSBnaXZlbiByb3V0ZS5cbiAgICovXG4gIHByb3RlY3RlZCByZXNvbHZlVXJsTWF0Y2hlcnMoXG4gICAgcm91dGU6IFJvdXRlLFxuICAgIG1hdGNoZXJzT3JGYWN0b3JpZXM6IFJvdXRlQ29uZmlnWydtYXRjaGVycyddXG4gICk6IFVybE1hdGNoZXIge1xuICAgIGNvbnN0IG1hdGNoZXJzOiBVcmxNYXRjaGVyW10gPSBtYXRjaGVyc09yRmFjdG9yaWVzLm1hcChcbiAgICAgIChtYXRjaGVyT3JGYWN0b3J5KSA9PiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgbWF0Y2hlck9yRmFjdG9yeSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgID8gbWF0Y2hlck9yRmFjdG9yeSAvLyBtYXRjaGVyXG4gICAgICAgICAgOiB0aGlzLnJlc29sdmVVcmxNYXRjaGVyRmFjdG9yeShyb3V0ZSwgbWF0Y2hlck9yRmFjdG9yeSk7IC8vIGZhY3RvcnkgaW5qZWN0aW9uIHRva2VuXG4gICAgICB9XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy51cmxNYXRjaGVyU2VydmljZS5nZXRDb21iaW5lZChtYXRjaGVycyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBgVXJsTWF0Y2hlcmAgYmFzZWQgb24gdGhlIGdpdmVuIHJvdXRlLCB1c2luZyB0aGUgZmFjdG9yeSBmdW5jdGlvbiBjb21pbmcgZnJvbSB0aGUgZ2l2ZW4gaW5qZWN0aW9uIHRva2VuLlxuICAgKlxuICAgKiBAcGFyYW0gcm91dGUgUm91dGUgb2JqZWN0XG4gICAqIEBwYXJhbSBmYWN0b3J5VG9rZW4gaW5qZWN0aW9uIHRva2VuIHdpdGggYSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgd2lsbCBjcmVhdGUgYW4gVXJsTWF0Y2hlciB1c2luZyBnaXZlbiByb3V0ZVxuICAgKi9cbiAgcHJvdGVjdGVkIHJlc29sdmVVcmxNYXRjaGVyRmFjdG9yeShcbiAgICByb3V0ZTogUm91dGUsXG4gICAgZmFjdG9yeVRva2VuOiBJbmplY3Rpb25Ub2tlbjxVcmxNYXRjaGVyRmFjdG9yeT5cbiAgKTogVXJsTWF0Y2hlciB7XG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuaW5qZWN0b3IuZ2V0KGZhY3RvcnlUb2tlbik7XG4gICAgcmV0dXJuIGZhY3Rvcnkocm91dGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIFJvdXRlIHN0b3JlZCBpbiBpdHMgcHJvcGVydHkgYGRhdGEuY3hSb3V0ZWBcbiAgICogQHBhcmFtIHJvdXRlXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Um91dGVOYW1lKHJvdXRlOiBSb3V0ZSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJvdXRlLmRhdGEgJiYgcm91dGUuZGF0YS5jeFJvdXRlO1xuICB9XG5cbiAgcHJvdGVjdGVkIHZhbGlkYXRlUm91dGVDb25maWcoXG4gICAgcm91dGVDb25maWc6IFJvdXRlQ29uZmlnLFxuICAgIHJvdXRlTmFtZTogc3RyaW5nLFxuICAgIHJvdXRlOiBSb3V0ZVxuICApIHtcbiAgICBpZiAoaXNEZXZNb2RlKCkpIHtcbiAgICAgIC8vIC0gbnVsbCB2YWx1ZSBvZiByb3V0ZUNvbmZpZyBvciByb3V0ZUNvbmZpZy5wYXRocyBtZWFucyBleHBsaWNpdCBzd2l0Y2hpbmcgb2ZmIHRoZSByb3V0ZSAtIGl0J3MgdmFsaWQgY29uZmlnXG4gICAgICAvLyAtIHJvdXRlQ29uZmlnIHdpdGggZGVmaW5lZCBgbWF0Y2hlcnNgIGlzIHZhbGlkLCBldmVuIGlmIGBwYXRoc2AgYXJlIHVuZGVmaW5lZFxuICAgICAgaWYgKFxuICAgICAgICByb3V0ZUNvbmZpZyA9PT0gbnVsbCB8fFxuICAgICAgICByb3V0ZUNvbmZpZz8ucGF0aHMgPT09IG51bGwgfHxcbiAgICAgICAgcm91dGVDb25maWc/Lm1hdGNoZXJzXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyB1bmRlZmluZWQgdmFsdWUgb2Ygcm91dGVDb25maWcgb3Igcm91dGVDb25maWcucGF0aHMgaXMgYSBtaXNjb25maWd1cmF0aW9uXG4gICAgICBpZiAoIXJvdXRlQ29uZmlnPy5wYXRocykge1xuICAgICAgICB0aGlzLndhcm4oXG4gICAgICAgICAgYENvdWxkIG5vdCBjb25maWd1cmUgdGhlIG5hbWVkIHJvdXRlICcke3JvdXRlTmFtZX0nYCxcbiAgICAgICAgICByb3V0ZSxcbiAgICAgICAgICBgZHVlIHRvIHVuZGVmaW5lZCBjb25maWcgb3IgdW5kZWZpbmVkICdwYXRocycgcHJvcGVydHkgZm9yIHRoaXMgcm91dGVgXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHdhcm4oLi4uYXJncykge1xuICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgY29uc29sZS53YXJuKC4uLmFyZ3MpO1xuICAgIH1cbiAgfVxufVxuIl19