@spartacus/core
Version:
Spartacus - the core framework
137 lines • 19.2 kB
JavaScript
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