UNPKG

@spartacus/storefront

Version:

Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.

209 lines 28.1 kB
import { isPlatformServer } from '@angular/common'; import { Inject, Injectable, isDevMode, PLATFORM_ID, } from '@angular/core'; import { deepMerge, } from '@spartacus/core'; import { defer, forkJoin, of } from 'rxjs'; import { mapTo, share, tap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@spartacus/core"; import * as i2 from "./cms-features.service"; /** * Service with logic related to resolving component from cms mapping */ export class CmsComponentsService { constructor(config, platformId, featureModules, configInitializer) { this.config = config; this.platformId = platformId; this.featureModules = featureModules; this.configInitializer = configInitializer; // Component mappings that were identified as missing this.missingComponents = []; // Already resolved mappings this.mappings = {}; // Contains already initialized resolvers for specified component typez this.mappingResolvers = new Map(); this.configInitializer .getStable('cmsComponents') .subscribe((cmsConfig) => { // we want to grab cms configuration available at config initialization phase // as lazy-loaded modules can affect global configuration resulting in // non-deterministic state this.staticCmsConfig = Object.assign({}, cmsConfig.cmsComponents); }); } /** * Should be called to make sure all component mappings are determined, * especially lazy loaded ones. * * It's recommended way to make sure all other methods of CmsComponentService * will be able to work synchronously for asked component types and avoid risk * of potential errors that could be thrown otherwise. */ determineMappings(componentTypes) { return defer(() => { var _a, _b; // we use defer, to be sure the logic below used to compose final observable // will be executed at subscription time (with up to date state at the time, // when it will be needed) const featureResolvers = []; for (const componentType of componentTypes) { if (!this.mappings[componentType]) { const staticConfig = (_b = ((_a = this.staticCmsConfig) !== null && _a !== void 0 ? _a : this.config.cmsComponents)) === null || _b === void 0 ? void 0 : _b[componentType]; // check if this component type is managed by feature module if (this.featureModules.hasFeatureFor(componentType)) { featureResolvers.push( // we delegate populating this.mappings to feature resolver this.getFeatureMappingResolver(componentType, staticConfig)); } else { // simply use only static config this.mappings[componentType] = staticConfig; } } } if (featureResolvers.length) { return forkJoin(featureResolvers).pipe(mapTo(componentTypes)); } else { return of(componentTypes); } }); } getFeatureMappingResolver(componentType, staticConfig) { if (!this.mappingResolvers.has(componentType)) { const mappingResolver$ = this.featureModules .getCmsMapping(componentType) .pipe(tap((featureComponentMapping) => { // We treat cms mapping configuration from a feature as a default, // that can be overridden by app/static configuration this.mappings[componentType] = deepMerge({}, featureComponentMapping, staticConfig); this.mappingResolvers.delete(componentType); }), share()); this.mappingResolvers.set(componentType, mappingResolver$); } return this.mappingResolvers.get(componentType); } /** * Returns the feature module for a cms component. * It will only work for cms components provided by feature modules. * * @param componentType */ getModule(componentType) { return (this.featureModules.hasFeatureFor(componentType) && this.featureModules.getModule(componentType)); } /** * Return collection of component mapping configuration for specified list of * component types. * * If component mapping can't be determined synchronously, for example, lazy * loaded one, it will throw an error. * * To make sure component mapping is available, determineMappings() * should be called and completed first. */ getMapping(componentType) { var _a, _b, _c; const componentConfig = (_a = this.mappings[componentType]) !== null && _a !== void 0 ? _a : (_c = ((_b = this.staticCmsConfig) !== null && _b !== void 0 ? _b : this.config.cmsComponents)) === null || _c === void 0 ? void 0 : _c[componentType]; if (isDevMode() && !componentConfig) { if (!this.missingComponents.includes(componentType)) { this.missingComponents.push(componentType); console.warn(`No component implementation found for the CMS component type '${componentType}'.\n`, `Make sure you implement a component and register it in the mapper.`); } } return componentConfig; } /** * Checks, if component should be rendered as some components * could be disabled for server side renderings */ shouldRender(componentType) { var _a; const isSSR = isPlatformServer(this.platformId); return !(isSSR && ((_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.disableSSR)); } /** * Return DeferLoadingStrategy for component type. */ getDeferLoadingStrategy(componentType) { var _a, _b, _c; return (_c = (_b = ((_a = this.staticCmsConfig) !== null && _a !== void 0 ? _a : this.config.cmsComponents)) === null || _b === void 0 ? void 0 : _b[componentType]) === null || _c === void 0 ? void 0 : _c.deferLoading; } /** * Get cms driven child routes for components */ getChildRoutes(componentTypes) { var _a, _b; const configs = []; for (const componentType of componentTypes) { if (this.shouldRender(componentType)) { configs.push((_b = (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.childRoutes) !== null && _b !== void 0 ? _b : []); } } return this.standardizeChildRoutes(configs); } /** * Returns the static data for the component type. */ getStaticData(componentType) { var _a; return (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.data; } /** * Standardizes the format of `childRoutes` config. * * Some `childRoutes` configs are simple arrays of Routes (without the notion of the parent route). * But some configs can be an object with children routes and their parent defined in separate property. */ standardizeChildRoutes(childRoutesConfigs) { const result = { children: [] }; (childRoutesConfigs || []).forEach((config) => { if (Array.isArray(config)) { result.children.push(...config); } else { result.children.push(...(config.children || [])); if (config.parent) { result.parent = config.parent; } } }); return result; } /** * Get cms driven guards for components */ getGuards(componentTypes) { var _a, _b; const guards = new Set(); for (const componentType of componentTypes) { (_b = (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.guards) === null || _b === void 0 ? void 0 : _b.forEach((guard) => guards.add(guard)); } return Array.from(guards); } /** * Get i18n keys associated with components */ getI18nKeys(componentTypes) { var _a, _b; const i18nKeys = new Set(); for (const componentType of componentTypes) { if (this.shouldRender(componentType)) { (_b = (_a = this.getMapping(componentType)) === null || _a === void 0 ? void 0 : _a.i18nKeys) === null || _b === void 0 ? void 0 : _b.forEach((key) => i18nKeys.add(key)); } } return Array.from(i18nKeys); } } CmsComponentsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CmsComponentsService, deps: [{ token: i1.CmsConfig }, { token: PLATFORM_ID }, { token: i2.CmsFeaturesService }, { token: i1.ConfigInitializerService }], target: i0.ɵɵFactoryTarget.Injectable }); CmsComponentsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CmsComponentsService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CmsComponentsService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: function () { return [{ type: i1.CmsConfig }, { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i2.CmsFeaturesService }, { type: i1.ConfigInitializerService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY21zLWNvbXBvbmVudHMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLXN0cnVjdHVyZS9zZXJ2aWNlcy9jbXMtY29tcG9uZW50cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFDTCxNQUFNLEVBQ04sVUFBVSxFQUNWLFNBQVMsRUFFVCxXQUFXLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQU9MLFNBQVMsR0FFVixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2RCxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUduRDs7R0FFRztBQUlILE1BQU0sT0FBTyxvQkFBb0I7SUFjL0IsWUFDWSxNQUFpQixFQUNJLFVBQWtCLEVBQ3ZDLGNBQWtDLEVBQ2xDLGlCQUEyQztRQUgzQyxXQUFNLEdBQU4sTUFBTSxDQUFXO1FBQ0ksZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUN2QyxtQkFBYyxHQUFkLGNBQWMsQ0FBb0I7UUFDbEMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUEwQjtRQWpCdkQscURBQXFEO1FBQzNDLHNCQUFpQixHQUFhLEVBQUUsQ0FBQztRQUUzQyw0QkFBNEI7UUFDbEIsYUFBUSxHQUFxRCxFQUFFLENBQUM7UUFLMUUsdUVBQXVFO1FBQzdELHFCQUFnQixHQUN4QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBUVYsSUFBSSxDQUFDLGlCQUFpQjthQUNuQixTQUFTLENBQUMsZUFBZSxDQUFDO2FBQzFCLFNBQVMsQ0FBQyxDQUFDLFNBQW9CLEVBQUUsRUFBRTtZQUNsQyw2RUFB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S0FBSyxDQUFDLENBQ2xCLENBQUM7U0FDSDtRQUNELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXLENBQUMsY0FBd0I7O1FBQ2xDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDbkMsS0FBSyxNQUFNLGFBQWEsSUFBSSxjQUFjLEVBQUU7WUFDMUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUNwQyxNQUFBLE1BQUEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsMENBQUUsUUFBUSwwQ0FBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUN4RCxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUNsQixDQUFDO2FBQ0g7U0FDRjtRQUNELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5QixDQUFDOztpSEF0T1Usb0JBQW9CLDJDQWdCckIsV0FBVztxSEFoQlYsb0JBQW9CLGNBRm5CLE1BQU07MkZBRVAsb0JBQW9CO2tCQUhoQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjtrRkFpQjhDLE1BQU07MEJBQWhELE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgSW5qZWN0LFxuICBJbmplY3RhYmxlLFxuICBpc0Rldk1vZGUsXG4gIE5nTW9kdWxlUmVmLFxuICBQTEFURk9STV9JRCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICBDbXNDb21wb25lbnQsXG4gIENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnLFxuICBDTVNDb21wb25lbnRDb25maWcsXG4gIENtc0NvbXBvbmVudE1hcHBpbmcsXG4gIENtc0NvbmZpZyxcbiAgQ29uZmlnSW5pdGlhbGl6ZXJTZXJ2aWNlLFxuICBkZWVwTWVyZ2UsXG4gIERlZmVyTG9hZGluZ1N0cmF0ZWd5LFxufSBmcm9tICdAc3BhcnRhY3VzL2NvcmUnO1xuaW1wb3J0IHsgZGVmZXIsIGZvcmtKb2luLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwVG8sIHNoYXJlLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDbXNGZWF0dXJlc1NlcnZpY2UgfSBmcm9tICcuL2Ntcy1mZWF0dXJlcy5zZXJ2aWNlJztcblxuLyoqXG4gKiBTZXJ2aWNlIHdpdGggbG9naWMgcmVsYXRlZCB0byByZXNvbHZpbmcgY29tcG9uZW50IGZyb20gY21zIG1hcHBpbmdcbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIENtc0NvbXBvbmVudHNTZXJ2aWNlIHtcbiAgLy8gQ29tcG9uZW50IG1hcHBpbmdzIHRoYXQgd2VyZSBpZGVudGlmaWVkIGFzIG1pc3NpbmdcbiAgcHJvdGVjdGVkIG1pc3NpbmdDb21wb25lbnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8vIEFscmVhZHkgcmVzb2x2ZWQgbWFwcGluZ3NcbiAgcHJvdGVjdGVkIG1hcHBpbmdzOiB7IFtjb21wb25lbnRUeXBlOiBzdHJpbmddOiBDbXNDb21wb25lbnRNYXBwaW5nIH0gPSB7fTtcblxuICAvLyBDb3B5IG9mIGluaXRpYWwvc3RhdGljIGNtcyBtYXBwaW5nIGNvbmZpZ3VyYXRpb24gdW5hZmZlY3RlZCBieSBsYXp5LWxvYWRlZCBtb2R1bGVzXG4gIHByb3RlY3RlZCBzdGF0aWNDbXNDb25maWc6IENNU0NvbXBvbmVudENvbmZpZyB8IHVuZGVmaW5lZDtcblxuICAvLyBDb250YWlucyBhbHJlYWR5IGluaXRpYWxpemVkIHJlc29sdmVycyBmb3Igc3BlY2lmaWVkIGNvbXBvbmVudCB0eXBlelxuICBwcm90ZWN0ZWQgbWFwcGluZ1Jlc29sdmVyczogTWFwPHN0cmluZywgT2JzZXJ2YWJsZTxDbXNDb21wb25lbnRNYXBwaW5nPj4gPVxuICAgIG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgY29uZmlnOiBDbXNDb25maWcsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJvdGVjdGVkIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgICBwcm90ZWN0ZWQgZmVhdHVyZU1vZHVsZXM6IENtc0ZlYXR1cmVzU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY29uZmlnSW5pdGlhbGl6ZXI6IENvbmZpZ0luaXRpYWxpemVyU2VydmljZVxuICApIHtcbiAgICB0aGlzLmNvbmZpZ0luaXRpYWxpemVyXG4gICAgICAuZ2V0U3RhYmxlKCdjbXNDb21wb25lbnRzJylcbiAgICAgIC5zdWJzY3JpYmUoKGNtc0NvbmZpZzogQ21zQ29uZmlnKSA9PiB7XG4gICAgICAgIC8vIHdlIHdhbnQgdG8gZ3JhYiBjbXMgY29uZmlndXJhdGlvbiBhdmFpbGFibGUgYXQgY29uZmlnIGluaXRpYWxpemF0aW9uIHBoYXNlXG4gICAgICAgIC8vIGFzIGxhenktbG9hZGVkIG1vZHVsZXMgY2FuIGFmZmVjdCBnbG9iYWwgY29uZmlndXJhdGlvbiByZXN1bHRpbmcgaW5cbiAgICAgICAgLy8gbm9uLWRldGVybWluaXN0aWMgc3RhdGVcbiAgICAgICAgdGhpcy5zdGF0aWNDbXNDb25maWcgPSB7IC4uLmNtc0NvbmZpZy5jbXNDb21wb25lbnRzIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaG91bGQgYmUgY2FsbGVkIHRvIG1ha2Ugc3VyZSBhbGwgY29tcG9uZW50IG1hcHBpbmdzIGFyZSBkZXRlcm1pbmVkLFxuICAgKiBlc3BlY2lhbGx5IGxhenkgbG9hZGVkIG9uZXMuXG4gICAqXG4gICAqIEl0J3MgcmVjb21tZW5kZWQgd2F5IHRvIG1ha2Ugc3VyZSBhbGwgb3RoZXIgbWV0aG9kcyBvZiBDbXNDb21wb25lbnRTZXJ2aWNlXG4gICAqIHdpbGwgYmUgYWJsZSB0byB3b3JrIHN5bmNocm9ub3VzbHkgZm9yIGFza2VkIGNvbXBvbmVudCB0eXBlcyBhbmQgYXZvaWQgcmlza1xuICAgKiBvZiBwb3RlbnRpYWwgZXJyb3JzIHRoYXQgY291bGQgYmUgdGhyb3duIG90aGVyd2lzZS5cbiAgICovXG4gIGRldGVybWluZU1hcHBpbmdzKGNvbXBvbmVudFR5cGVzOiBzdHJpbmdbXSk6IE9ic2VydmFibGU8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gZGVmZXIoKCkgPT4ge1xuICAgICAgLy8gd2UgdXNlIGRlZmVyLCB0byBiZSBzdXJlIHRoZSBsb2dpYyBiZWxvdyB1c2VkIHRvIGNvbXBvc2UgZmluYWwgb2JzZXJ2YWJsZVxuICAgICAgLy8gd2lsbCBiZSBleGVjdXRlZCBhdCBzdWJzY3JpcHRpb24gdGltZSAod2l0aCB1cCB0byBkYXRlIHN0YXRlIGF0IHRoZSB0aW1lLFxuICAgICAgLy8gd2hlbiBpdCB3aWxsIGJlIG5lZWRlZClcbiAgICAgIGNvbnN0IGZlYXR1cmVSZXNvbHZlcnMgPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjb21wb25lbnRUeXBlIG9mIGNvbXBvbmVudFR5cGVzKSB7XG4gICAgICAgIGlmICghdGhpcy5tYXBwaW5nc1tjb21wb25lbnRUeXBlXSkge1xuICAgICAgICAgIGNvbnN0IHN0YXRpY0NvbmZpZyA9ICh0aGlzLnN0YXRpY0Ntc0NvbmZpZyA/P1xuICAgICAgICAgICAgdGhpcy5jb25maWcuY21zQ29tcG9uZW50cyk/Lltjb21wb25lbnRUeXBlXTtcblxuICAgICAgICAgIC8vIGNoZWNrIGlmIHRoaXMgY29tcG9uZW50IHR5cGUgaXMgbWFuYWdlZCBieSBmZWF0dXJlIG1vZHVsZVxuICAgICAgICAgIGlmICh0aGlzLmZlYXR1cmVNb2R1bGVzLmhhc0ZlYXR1cmVGb3IoY29tcG9uZW50VHlwZSkpIHtcbiAgICAgICAgICAgIGZlYXR1cmVSZXNvbHZlcnMucHVzaChcbiAgICAgICAgICAgICAgLy8gd2UgZGVsZWdhdGUgcG9wdWxhdGluZyB0aGlzLm1hcHBpbmdzIHRvIGZlYXR1cmUgcmVzb2x2ZXJcbiAgICAgICAgICAgICAgdGhpcy5nZXRGZWF0dXJlTWFwcGluZ1Jlc29sdmVyKGNvbXBvbmVudFR5cGUsIHN0YXRpY0NvbmZpZylcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNpbXBseSB1c2Ugb25seSBzdGF0aWMgY29uZmlnXG4gICAgICAgICAgICB0aGlzLm1hcHBpbmdzW2NvbXBvbmVudFR5cGVdID0gc3RhdGljQ29uZmlnO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmVhdHVyZVJlc29sdmVycy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKGZlYXR1cmVSZXNvbHZlcnMpLnBpcGUobWFwVG8oY29tcG9uZW50VHlwZXMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvZihjb21wb25lbnRUeXBlcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldEZlYXR1cmVNYXBwaW5nUmVzb2x2ZXIoXG4gICAgY29tcG9uZW50VHlwZTogc3RyaW5nLFxuICAgIHN0YXRpY0NvbmZpZz86IENtc0NvbXBvbmVudE1hcHBpbmdcbiAgKTogT2JzZXJ2YWJsZTxDbXNDb21wb25lbnRNYXBwaW5nPiB7XG4gICAgaWYgKCF0aGlzLm1hcHBpbmdSZXNvbHZlcnMuaGFzKGNvbXBvbmVudFR5cGUpKSB7XG4gICAgICBjb25zdCBtYXBwaW5nUmVzb2x2ZXIkID0gdGhpcy5mZWF0dXJlTW9kdWxlc1xuICAgICAgICAuZ2V0Q21zTWFwcGluZyhjb21wb25lbnRUeXBlKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YXAoKGZlYXR1cmVDb21wb25lbnRNYXBwaW5nKSA9PiB7XG4gICAgICAgICAgICAvLyBXZSB0cmVhdCBjbXMgbWFwcGluZyBjb25maWd1cmF0aW9uIGZyb20gYSBmZWF0dXJlIGFzIGEgZGVmYXVsdCxcbiAgICAgICAgICAgIC8vIHRoYXQgY2FuIGJlIG92ZXJyaWRkZW4gYnkgYXBwL3N0YXRpYyBjb25maWd1cmF0aW9uXG4gICAgICAgICAgICB0aGlzLm1hcHBpbmdzW2NvbXBvbmVudFR5cGVdID0gZGVlcE1lcmdlKFxuICAgICAgICAgICAgICB7fSxcbiAgICAgICAgICAgICAgZmVhdHVyZUNvbXBvbmVudE1hcHBpbmcsXG4gICAgICAgICAgICAgIHN0YXRpY0NvbmZpZ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubWFwcGluZ1Jlc29sdmVycy5kZWxldGUoY29tcG9uZW50VHlwZSk7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgc2hhcmUoKVxuICAgICAgICApO1xuICAgICAgdGhpcy5tYXBwaW5nUmVzb2x2ZXJzLnNldChjb21wb25lbnRUeXBlLCBtYXBwaW5nUmVzb2x2ZXIkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubWFwcGluZ1Jlc29sdmVycy5nZXQoY29tcG9uZW50VHlwZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZmVhdHVyZSBtb2R1bGUgZm9yIGEgY21zIGNvbXBvbmVudC5cbiAgICogSXQgd2lsbCBvbmx5IHdvcmsgZm9yIGNtcyBjb21wb25lbnRzIHByb3ZpZGVkIGJ5IGZlYXR1cmUgbW9kdWxlcy5cbiAgICpcbiAgICogQHBhcmFtIGNvbXBvbmVudFR5cGVcbiAgICovXG4gIGdldE1vZHVsZShjb21wb25lbnRUeXBlOiBzdHJpbmcpOiBOZ01vZHVsZVJlZjxhbnk+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5mZWF0dXJlTW9kdWxlcy5oYXNGZWF0dXJlRm9yKGNvbXBvbmVudFR5cGUpICYmXG4gICAgICB0aGlzLmZlYXR1cmVNb2R1bGVzLmdldE1vZHVsZShjb21wb25lbnRUeXBlKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGNvbGxlY3Rpb24gb2YgY29tcG9uZW50IG1hcHBpbmcgY29uZmlndXJhdGlvbiBmb3Igc3BlY2lmaWVkIGxpc3Qgb2ZcbiAgICogY29tcG9uZW50IHR5cGVzLlxuICAgKlxuICAgKiBJZiBjb21wb25lbnQgbWFwcGluZyBjYW4ndCBiZSBkZXRlcm1pbmVkIHN5bmNocm9ub3VzbHksIGZvciBleGFtcGxlLCBsYXp5XG4gICAqIGxvYWRlZCBvbmUsIGl0IHdpbGwgdGhyb3cgYW4gZXJyb3IuXG4gICAqXG4gICAqIFRvIG1ha2Ugc3VyZSBjb21wb25lbnQgbWFwcGluZyBpcyBhdmFpbGFibGUsIGRldGVybWluZU1hcHBpbmdzKClcbiAgICogc2hvdWxkIGJlIGNhbGxlZCBhbmQgY29tcGxldGVkIGZpcnN0LlxuICAgKi9cbiAgZ2V0TWFwcGluZyhjb21wb25lbnRUeXBlOiBzdHJpbmcpOiBDbXNDb21wb25lbnRNYXBwaW5nIHtcbiAgICBjb25zdCBjb21wb25lbnRDb25maWcgPVxuICAgICAgdGhpcy5tYXBwaW5nc1tjb21wb25lbnRUeXBlXSA/P1xuICAgICAgKHRoaXMuc3RhdGljQ21zQ29uZmlnID8/IHRoaXMuY29uZmlnLmNtc0NvbXBvbmVudHMpPy5bY29tcG9uZW50VHlwZV07XG5cbiAgICBpZiAoaXNEZXZNb2RlKCkgJiYgIWNvbXBvbmVudENvbmZpZykge1xuICAgICAgaWYgKCF0aGlzLm1pc3NpbmdDb21wb25lbnRzLmluY2x1ZGVzKGNvbXBvbmVudFR5cGUpKSB7XG4gICAgICAgIHRoaXMubWlzc2luZ0NvbXBvbmVudHMucHVzaChjb21wb25lbnRUeXBlKTtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBObyBjb21wb25lbnQgaW1wbGVtZW50YXRpb24gZm91bmQgZm9yIHRoZSBDTVMgY29tcG9uZW50IHR5cGUgJyR7Y29tcG9uZW50VHlwZX0nLlxcbmAsXG4gICAgICAgICAgYE1ha2Ugc3VyZSB5b3UgaW1wbGVtZW50IGEgY29tcG9uZW50IGFuZCByZWdpc3RlciBpdCBpbiB0aGUgbWFwcGVyLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29tcG9uZW50Q29uZmlnO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcywgaWYgY29tcG9uZW50IHNob3VsZCBiZSByZW5kZXJlZCBhcyBzb21lIGNvbXBvbmVudHNcbiAgICogY291bGQgYmUgZGlzYWJsZWQgZm9yIHNlcnZlciBzaWRlIHJlbmRlcmluZ3NcbiAgICovXG4gIHNob3VsZFJlbmRlcihjb21wb25lbnRUeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBpc1NTUiA9IGlzUGxhdGZvcm1TZXJ2ZXIodGhpcy5wbGF0Zm9ybUlkKTtcbiAgICByZXR1cm4gIShpc1NTUiAmJiB0aGlzLmdldE1hcHBpbmcoY29tcG9uZW50VHlwZSk/LmRpc2FibGVTU1IpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBEZWZlckxvYWRpbmdTdHJhdGVneSBmb3IgY29tcG9uZW50IHR5cGUuXG4gICAqL1xuICBnZXREZWZlckxvYWRpbmdTdHJhdGVneShcbiAgICBjb21wb25lbnRUeXBlOiBzdHJpbmdcbiAgKTogRGVmZXJMb2FkaW5nU3RyYXRlZ3kgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiAodGhpcy5zdGF0aWNDbXNDb25maWcgPz8gdGhpcy5jb25maWcuY21zQ29tcG9uZW50cyk/Lltjb21wb25lbnRUeXBlXVxuICAgICAgPy5kZWZlckxvYWRpbmc7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNtcyBkcml2ZW4gY2hpbGQgcm91dGVzIGZvciBjb21wb25lbnRzXG4gICAqL1xuICBnZXRDaGlsZFJvdXRlcyhjb21wb25lbnRUeXBlczogc3RyaW5nW10pOiBDbXNDb21wb25lbnRDaGlsZFJvdXRlc0NvbmZpZyB7XG4gICAgY29uc3QgY29uZmlncyA9IFtdO1xuICAgIGZvciAoY29uc3QgY29tcG9uZW50VHlwZSBvZiBjb21wb25lbnRUeXBlcykge1xuICAgICAgaWYgKHRoaXMuc2hvdWxkUmVuZGVyKGNvbXBvbmVudFR5cGUpKSB7XG4gICAgICAgIGNvbmZpZ3MucHVzaCh0aGlzLmdldE1hcHBpbmcoY29tcG9uZW50VHlwZSk/LmNoaWxkUm91dGVzID8/IFtdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdGFuZGFyZGl6ZUNoaWxkUm91dGVzKGNvbmZpZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHN0YXRpYyBkYXRhIGZvciB0aGUgY29tcG9uZW50IHR5cGUuXG4gICAqL1xuICBnZXRTdGF0aWNEYXRhPFQgZXh0ZW5kcyBDbXNDb21wb25lbnQgPSBDbXNDb21wb25lbnQ+KFxuICAgIGNvbXBvbmVudFR5cGU6IHN0cmluZ1xuICApOiBUIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNYXBwaW5nKGNvbXBvbmVudFR5cGUpPy5kYXRhIGFzIFQ7XG4gIH1cblxuICAvKipcbiAgICogU3RhbmRhcmRpemVzIHRoZSBmb3JtYXQgb2YgYGNoaWxkUm91dGVzYCBjb25maWcuXG4gICAqXG4gICAqIFNvbWUgYGNoaWxkUm91dGVzYCBjb25maWdzIGFyZSBzaW1wbGUgYXJyYXlzIG9mIFJvdXRlcyAod2l0aG91dCB0aGUgbm90aW9uIG9mIHRoZSBwYXJlbnQgcm91dGUpLlxuICAgKiBCdXQgc29tZSBjb25maWdzIGNhbiBiZSBhbiBvYmplY3Qgd2l0aCBjaGlsZHJlbiByb3V0ZXMgYW5kIHRoZWlyIHBhcmVudCBkZWZpbmVkIGluIHNlcGFyYXRlIHByb3BlcnR5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YW5kYXJkaXplQ2hpbGRSb3V0ZXMoXG4gICAgY2hpbGRSb3V0ZXNDb25maWdzOiAoUm91dGVbXSB8IENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnKVtdXG4gICk6IENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnIHtcbiAgICBjb25zdCByZXN1bHQ6IENtc0NvbXBvbmVudENoaWxkUm91dGVzQ29uZmlnID0geyBjaGlsZHJlbjogW10gfTtcblxuICAgIChjaGlsZFJvdXRlc0NvbmZpZ3MgfHwgW10pLmZvckVhY2goKGNvbmZpZykgPT4ge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29uZmlnKSkge1xuICAgICAgICByZXN1bHQuY2hpbGRyZW4ucHVzaCguLi5jb25maWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LmNoaWxkcmVuLnB1c2goLi4uKGNvbmZpZy5jaGlsZHJlbiB8fCBbXSkpO1xuICAgICAgICBpZiAoY29uZmlnLnBhcmVudCkge1xuICAgICAgICAgIHJlc3VsdC5wYXJlbnQgPSBjb25maWcucGFyZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjbXMgZHJpdmVuIGd1YXJkcyBmb3IgY29tcG9uZW50c1xuICAgKi9cbiAgZ2V0R3VhcmRzKGNvbXBvbmVudFR5cGVzOiBzdHJpbmdbXSk6IGFueVtdIHtcbiAgICBjb25zdCBndWFyZHMgPSBuZXcgU2V0PGFueT4oKTtcbiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudFR5cGUgb2YgY29tcG9uZW50VHlwZXMpIHtcbiAgICAgIHRoaXMuZ2V0TWFwcGluZyhjb21wb25lbnRUeXBlKT8uZ3VhcmRzPy5mb3JFYWNoKChndWFyZCkgPT5cbiAgICAgICAgZ3VhcmRzLmFkZChndWFyZClcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKGd1YXJkcyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGkxOG4ga2V5cyBhc3NvY2lhdGVkIHdpdGggY29tcG9uZW50c1xuICAgKi9cbiAgZ2V0STE4bktleXMoY29tcG9uZW50VHlwZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGkxOG5LZXlzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCBjb21wb25lbnRUeXBlIG9mIGNvbXBvbmVudFR5cGVzKSB7XG4gICAgICBpZiAodGhpcy5zaG91bGRSZW5kZXIoY29tcG9uZW50VHlwZSkpIHtcbiAgICAgICAgdGhpcy5nZXRNYXBwaW5nKGNvbXBvbmVudFR5cGUpPy5pMThuS2V5cz8uZm9yRWFjaCgoa2V5KSA9PlxuICAgICAgICAgIGkxOG5LZXlzLmFkZChrZXkpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKGkxOG5LZXlzKTtcbiAgfVxufVxuIl19