UNPKG

@tsclean/core

Version:

Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.

364 lines 49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Module = void 0; const iterare_1 = require("iterare"); const app_1 = require("../../app"); const errors_1 = require("../../errors"); const helpers_1 = require("../../helpers"); const constants_1 = require("./constants"); const instance_wrapper_1 = require("./instance-wrapper"); const module_ref_1 = require("./module-ref"); const utils_1 = require("../../utils"); class Module { constructor(_metaType, container) { this._metaType = _metaType; this.container = container; this._imports = new Set(); this._providers = new Map(); this._injectables = new Map(); this._middlewares = new Map(); this._controllers = new Map(); this._exports = new Set(); this._distance = 0; this._initOnPreview = false; this._isGlobal = false; this.addCoreProviders(); this._id = (0, utils_1.randomStringGenerator)(); } get id() { return this._id; } get token() { return this._token; } get name() { return this.metaType.name; } get isGlobal() { return this._isGlobal; } set isGlobal(global) { this._isGlobal = global; } get initOnPreview() { return this._initOnPreview; } set initOnPreview(initOnPreview) { this._initOnPreview = initOnPreview; } set token(token) { this._token = token; } get providers() { return this._providers; } get middlewares() { return this._middlewares; } get imports() { return this._imports; } get routes() { return this._controllers; } get injectables() { return this._injectables; } get controllers() { return this._controllers; } get exports() { return this._exports; } get instance() { if (!this._providers.has(this._metaType)) throw new errors_1.RuntimeException(); const module = this._providers.get(this._metaType); return module.instance; } get metaType() { return this._metaType; } get distance() { return this._distance; } set distance(value) { this._distance = value; } addCoreProviders() { this.addModuleAsProvider(); this.addModuleRef(); this.addApplicationConfig(); } addModuleRef() { const moduleRef = this.createModuleReferenceType(); this._providers.set(module_ref_1.ModuleRef, new instance_wrapper_1.InstanceWrapper({ token: module_ref_1.ModuleRef, name: module_ref_1.ModuleRef.name, metaType: module_ref_1.ModuleRef, isResolved: true, instance: new moduleRef(), host: this })); } addModuleAsProvider() { this._providers.set(this._metaType, new instance_wrapper_1.InstanceWrapper({ token: this._metaType, name: this._metaType.name, metaType: this._metaType, isResolved: false, instance: null, host: this })); } addApplicationConfig() { this._providers.set(app_1.ApplicationConfig, new instance_wrapper_1.InstanceWrapper({ token: app_1.ApplicationConfig, name: app_1.ApplicationConfig.name, isResolved: true, instance: this.container.applicationConfig, host: this })); } addInjectable(injectable, enhancerSubtype, host) { if (this.isCustomProvider(injectable)) { return this.addCustomProvider(injectable, this._injectables); } let instanceWrapper = this.injectables.get(injectable); if (!instanceWrapper) { instanceWrapper = new instance_wrapper_1.InstanceWrapper({ token: injectable, name: injectable.name, metaType: injectable, instance: null, isResolved: false, scope: (0, helpers_1.getClassScope)(injectable), host: this }); this._injectables.set(injectable, instanceWrapper); } if (host) { const hostWrapper = this._controllers.get(host) || this._providers.get(host); hostWrapper && hostWrapper.addEnhancerMetadata(instanceWrapper); } } addProvider(provider, enhancerSubtype) { if (this.isCustomProvider(provider)) { return this.addCustomProvider(provider, this._providers, enhancerSubtype); } this._providers.set(provider, new instance_wrapper_1.InstanceWrapper({ token: provider, name: provider.name, metaType: provider, instance: null, isResolved: false, scope: (0, helpers_1.getClassScope)(provider), host: this })); return provider; } isCustomProvider(provider) { return !(0, utils_1.isNil)(provider.provide); } addCustomProvider(provider, collection, enhancerSubtype) { if (this.isCustomClass(provider)) { this.addCustomClass(provider, collection, enhancerSubtype); } else if (this.isCustomValue(provider)) { this.addCustomValue(provider, collection, enhancerSubtype); } else if (this.isCustomFactory(provider)) { this.addCustomFactory(provider, collection, enhancerSubtype); } else if (this.isCustomUseExisting(provider)) { this.addCustomUseExisting(provider, collection, enhancerSubtype); } return provider.provide; } isCustomClass(provider) { return !(0, utils_1.isUndefined)(provider.useClass); } isCustomValue(provider) { return !(0, utils_1.isUndefined)(provider.useValue); } isCustomFactory(provider) { return !(0, utils_1.isUndefined)(provider.useFactory); } isCustomUseExisting(provider) { return !(0, utils_1.isUndefined)(provider.useExisting); } isDynamicModule(exported) { return exported && exported.module; } addCustomClass(provider, collection, enhancerSubtype) { let { scope } = provider; const { useClass } = provider; if ((0, utils_1.isUndefined)(scope)) { scope = (0, helpers_1.getClassScope)(useClass); } collection.set(provider.provide, new instance_wrapper_1.InstanceWrapper({ token: provider.provide, name: (useClass === null || useClass === void 0 ? void 0 : useClass.name) || useClass, metaType: useClass, instance: null, isResolved: false, scope, host: this, subtype: enhancerSubtype })); } addCustomValue(provider, collection, enhancerSubtype) { const { useValue: value, provide: providerToken } = provider; collection.set(providerToken, new instance_wrapper_1.InstanceWrapper({ token: providerToken, name: (providerToken === null || providerToken === void 0 ? void 0 : providerToken.name) || providerToken, metaType: null, instance: value, isResolved: true, async: value instanceof Promise, host: this, subtype: enhancerSubtype })); } addCustomFactory(provider, collection, enhancerSubtype) { const { useFactory: factory, inject, scope, provide: providerToken } = provider; collection.set(providerToken, new instance_wrapper_1.InstanceWrapper({ token: providerToken, name: (providerToken === null || providerToken === void 0 ? void 0 : providerToken.name) || providerToken, metaType: factory, instance: null, isResolved: false, inject: inject || [], scope, host: this, subtype: enhancerSubtype })); } addCustomUseExisting(provider, collection, enhancerSubtype) { const { useExisting, provide: providerToken } = provider; collection.set(providerToken, new instance_wrapper_1.InstanceWrapper({ token: providerToken, name: (providerToken === null || providerToken === void 0 ? void 0 : providerToken.name) || providerToken, metaType: (instance => instance), instance: null, isResolved: false, inject: [useExisting], host: this, isAlias: true, subtype: enhancerSubtype })); } addExportedProvider(provider) { const addExportedUnit = (token) => this._exports.add(this.validateExportedProvider(token)); if (this.isCustomProvider(provider)) { return this.addCustomExportedProvider(provider); } else if ((0, utils_1.isString)(provider) || (0, utils_1.isSymbol)(provider)) { return addExportedUnit(provider); } else if (this.isDynamicModule(provider)) { const { module: moduleClassRef } = provider; return addExportedUnit(moduleClassRef); } addExportedUnit(provider); } addCustomExportedProvider(provider) { const provide = provider.provide; if ((0, utils_1.isString)(provide) || (0, utils_1.isSymbol)(provide)) { return this._exports.add(this.validateExportedProvider(provide)); } this._exports.add(this.validateExportedProvider(provide)); } validateExportedProvider(token) { if (this._providers.has(token)) { return token; } const imports = (0, iterare_1.iterate)(this._imports.values()) .filter(item => !!item) .map(({ metaType }) => metaType) .filter(metaType => !!metaType) .toArray(); if (!imports.includes(token)) { const { name } = this._metaType; const providerName = (0, utils_1.isFunction)(token) ? token.name : token; throw new errors_1.UnknownExportException(providerName, name); } return token; } addController(controller) { this._controllers.set(controller, new instance_wrapper_1.InstanceWrapper({ token: controller, name: controller.name, metaType: controller, instance: null, isResolved: false, scope: (0, helpers_1.getClassScope)(controller), host: this })); this.assignControllerUniqueId(controller); } assignControllerUniqueId(controller) { Object.defineProperty(controller, constants_1.CONTROLLER_ID_KEY, { enumerable: false, writable: false, configurable: true, value: (0, utils_1.randomStringGenerator)() }); } addRelatedModule(module) { this._imports.add(module); } replace(toReplace, options) { if (options.isProvider && this.hasProvider(toReplace)) { const originalProvider = this._providers.get(toReplace); return originalProvider.mergeWith(Object.assign({ provide: toReplace }, options)); } else if (!options.isProvider && this.hasInjectable(toReplace)) { const originalInjectable = this._injectables.get(toReplace); return originalInjectable.mergeWith(Object.assign({ provide: toReplace }, options)); } } hasProvider(token) { return this._providers.has(token); } hasInjectable(token) { return this._injectables.has(token); } getProviderByKey(name) { return this._providers.get(name); } createModuleReferenceType() { // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; return class extends module_ref_1.ModuleRef { constructor() { super(self.container); } get(typeOrToken, options = {}) { var _a, _b; (_a = options.strict) !== null && _a !== void 0 ? _a : (options.strict = true); (_b = options.each) !== null && _b !== void 0 ? _b : (options.each = false); return this.find(typeOrToken, options.strict ? { moduleId: self.id, each: options.each, } : options); } resolve(typeOrToken, contextId = (0, helpers_1.createContextId)(), options = {}) { var _a, _b; (_a = options.strict) !== null && _a !== void 0 ? _a : (options.strict = true); (_b = options.each) !== null && _b !== void 0 ? _b : (options.each = false); return this.resolvePerContext(typeOrToken, self, contextId, options); } async create(type, contextId) { if (!(type && (0, utils_1.isFunction)(type) && type.prototype)) { throw new errors_1.InvalidClassException(type); } return this.instantiateClass(type, self, contextId); } }; } } exports.Module = Module; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvcmUvaW5qZWN0b3IvbW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFDQUFpQztBQUNqQyxtQ0FBNkM7QUFDN0MseUNBSXFCO0FBQ3JCLDJDQUErRTtBQUMvRSwyQ0FBK0M7QUFFL0MseURBQStEO0FBQy9ELDZDQUFtRTtBQVduRSx1Q0FPb0I7QUFRcEIsTUFBYSxNQUFNO0lBeUJqQixZQUNtQixTQUFvQixFQUNwQixTQUF1QjtRQUR2QixjQUFTLEdBQVQsU0FBUyxDQUFXO1FBQ3BCLGNBQVMsR0FBVCxTQUFTLENBQWM7UUF6QnpCLGFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFBO1FBQzVCLGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFHbEMsQ0FBQTtRQUNjLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBR3BDLENBQUE7UUFDYyxpQkFBWSxHQUFHLElBQUksR0FBRyxFQUdwQyxDQUFBO1FBQ2MsaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFHcEMsQ0FBQTtRQUNjLGFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQTtRQUNoRCxjQUFTLEdBQUcsQ0FBQyxDQUFBO1FBQ2IsbUJBQWMsR0FBRyxLQUFLLENBQUE7UUFDdEIsY0FBUyxHQUFHLEtBQUssQ0FBQTtRQU92QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtRQUN2QixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUEsNkJBQXFCLEdBQUUsQ0FBQTtJQUNwQyxDQUFDO0lBRUQsSUFBSSxFQUFFO1FBQ0osT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFBO0lBQ2pCLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUE7SUFDcEIsQ0FBQztJQUVELElBQUksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUE7SUFDM0IsQ0FBQztJQUVE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QU8sQ0FBQyxJQUFJLG9DQUFaLE9BQU8sQ0FBQyxJQUFJLEdBQUssS0FBSyxFQUFDO2dCQUV2QixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FDM0IsV0FBVyxFQUNYLElBQUksRUFDSixTQUFTLEVBQ1QsT0FBTyxDQUNSLENBQUM7WUFDSixDQUFDO1lBRU0sS0FBSyxDQUFDLE1BQU0sQ0FDakIsSUFBYSxFQUNiLFNBQXFCO2dCQUVyQixJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBQSxrQkFBVSxFQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO29CQUNsRCxNQUFNLElBQUksOEJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3hDLENBQUM7Z0JBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUksSUFBSSxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztZQUN6RCxDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQWhoQkQsd0JBZ2hCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGl0ZXJhdGUgfSBmcm9tICdpdGVyYXJlJ1xuaW1wb3J0IHsgQXBwbGljYXRpb25Db25maWcgfSBmcm9tICcuLi8uLi9hcHAnXG5pbXBvcnQge1xuICBJbnZhbGlkQ2xhc3NFeGNlcHRpb24sXG4gIFJ1bnRpbWVFeGNlcHRpb24sXG4gIFVua25vd25FeHBvcnRFeGNlcHRpb25cbn0gZnJvbSAnLi4vLi4vZXJyb3JzJ1xuaW1wb3J0IHsgY3JlYXRlQ29udGV4dElkLCBFbmhhbmNlclN1YnR5cGUsIGdldENsYXNzU2NvcGUgfSBmcm9tICcuLi8uLi9oZWxwZXJzJ1xuaW1wb3J0IHsgQ09OVFJPTExFUl9JRF9LRVkgfSBmcm9tICcuL2NvbnN0YW50cydcbmltcG9ydCB7IENvbnRhaW5lcklvQyB9IGZyb20gJy4vY29udGFpbmVyJ1xuaW1wb3J0IHsgQ29udGV4dElkLCBJbnN0YW5jZVdyYXBwZXIgfSBmcm9tICcuL2luc3RhbmNlLXdyYXBwZXInXG5pbXBvcnQgeyBNb2R1bGVSZWYsIE1vZHVsZVJlZkdldE9yUmVzb2x2ZU9wdHMgfSBmcm9tICcuL21vZHVsZS1yZWYnXG5pbXBvcnQge1xuICBDbGFzc1Byb3ZpZGVyLFxuICBEeW5hbWljTW9kdWxlSW50ZXJmYWNlLFxuICBFeGlzdGluZ1Byb3ZpZGVyLFxuICBGYWN0b3J5UHJvdmlkZXIsXG4gIEluamVjdGlvblRva2VuLFxuICBNb2R1bGVJbnRlcmZhY2UsXG4gIFR5cGUsXG4gIFZhbHVlUHJvdmlkZXJcbn0gZnJvbSAnLi4vLi4vY29udHJhY3RzJ1xuaW1wb3J0IHtcbiAgaXNGdW5jdGlvbixcbiAgaXNOaWwsXG4gIGlzU3RyaW5nLFxuICBpc1N5bWJvbCxcbiAgaXNVbmRlZmluZWQsXG4gIHJhbmRvbVN0cmluZ0dlbmVyYXRvclxufSBmcm9tICcuLi8uLi91dGlscydcbmltcG9ydCB7XG4gIENvbnRyb2xsZXJUeXBlLFxuICBJbmplY3RhYmxlVHlwZSxcbiAgSW5zdGFuY2VUb2tlblR5cGUsXG4gIFByb3ZpZGVyVHlwZVxufSBmcm9tICcuLi8uLi90eXBlcydcblxuZXhwb3J0IGNsYXNzIE1vZHVsZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2lkOiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSBfaW1wb3J0cyA9IG5ldyBTZXQ8TW9kdWxlPigpXG4gIHByaXZhdGUgcmVhZG9ubHkgX3Byb3ZpZGVycyA9IG5ldyBNYXA8XG4gICAgSW5zdGFuY2VUb2tlblR5cGUsXG4gICAgSW5zdGFuY2VXcmFwcGVyPEluamVjdGFibGVUeXBlPlxuICA+KClcbiAgcHJpdmF0ZSByZWFkb25seSBfaW5qZWN0YWJsZXMgPSBuZXcgTWFwPFxuICAgIEluc3RhbmNlVG9rZW5UeXBlLFxuICAgIEluc3RhbmNlV3JhcHBlcjxJbmplY3RhYmxlVHlwZT5cbiAgPigpXG4gIHByaXZhdGUgcmVhZG9ubHkgX21pZGRsZXdhcmVzID0gbmV3IE1hcDxcbiAgICBJbnN0YW5jZVRva2VuVHlwZSxcbiAgICBJbnN0YW5jZVdyYXBwZXI8SW5qZWN0YWJsZVR5cGU+XG4gID4oKVxuICBwcml2YXRlIHJlYWRvbmx5IF9jb250cm9sbGVycyA9IG5ldyBNYXA8XG4gICAgSW5zdGFuY2VUb2tlblR5cGUsXG4gICAgSW5zdGFuY2VXcmFwcGVyPENvbnRyb2xsZXJUeXBlPlxuICA+KClcbiAgcHJpdmF0ZSByZWFkb25seSBfZXhwb3J0cyA9IG5ldyBTZXQ8SW5zdGFuY2VUb2tlblR5cGU+KClcbiAgcHJpdmF0ZSBfZGlzdGFuY2UgPSAwXG4gIHByaXZhdGUgX2luaXRPblByZXZpZXcgPSBmYWxzZVxuICBwcml2YXRlIF9pc0dsb2JhbCA9IGZhbHNlXG4gIHByaXZhdGUgX3Rva2VuOiBzdHJpbmdcblxuICBjb25zdHJ1Y3RvciAoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbWV0YVR5cGU6IFR5cGU8YW55PixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbnRhaW5lcjogQ29udGFpbmVySW9DXG4gICkge1xuICAgIHRoaXMuYWRkQ29yZVByb3ZpZGVycygpXG4gICAgdGhpcy5faWQgPSByYW5kb21TdHJpbmdHZW5lcmF0b3IoKVxuICB9XG5cbiAgZ2V0IGlkICgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9pZFxuICB9XG5cbiAgZ2V0IHRva2VuICgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl90b2tlblxuICB9XG5cbiAgZ2V0IG5hbWUgKCkge1xuICAgIHJldHVybiB0aGlzLm1ldGFUeXBlLm5hbWVcbiAgfVxuXG4gIGdldCBpc0dsb2JhbCAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzR2xvYmFsXG4gIH1cblxuICBzZXQgaXNHbG9iYWwgKGdsb2JhbDogYm9vbGVhbikge1xuICAgIHRoaXMuX2lzR2xvYmFsID0gZ2xvYmFsXG4gIH1cblxuICBnZXQgaW5pdE9uUHJldmlldyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2luaXRPblByZXZpZXdcbiAgfVxuXG4gIHNldCBpbml0T25QcmV2aWV3IChpbml0T25QcmV2aWV3OiBib29sZWFuKSB7XG4gICAgdGhpcy5faW5pdE9uUHJldmlldyA9IGluaXRPblByZXZpZXdcbiAgfVxuXG4gIHNldCB0b2tlbiAodG9rZW46IHN0cmluZykge1xuICAgIHRoaXMuX3Rva2VuID0gdG9rZW5cbiAgfVxuXG4gIGdldCBwcm92aWRlcnMgKCk6IE1hcDxJbnN0YW5jZVRva2VuVHlwZSwgSW5zdGFuY2VXcmFwcGVyPEluamVjdGFibGVUeXBlPj4ge1xuICAgIHJldHVybiB0aGlzLl9wcm92aWRlcnNcbiAgfVxuXG4gIGdldCBtaWRkbGV3YXJlcyAoKTogTWFwPEluc3RhbmNlVG9rZW5UeXBlLCBJbnN0YW5jZVdyYXBwZXI8SW5qZWN0YWJsZVR5cGU+PiB7XG4gICAgcmV0dXJuIHRoaXMuX21pZGRsZXdhcmVzXG4gIH1cblxuICBnZXQgaW1wb3J0cyAoKTogU2V0PE1vZHVsZT4ge1xuICAgIHJldHVybiB0aGlzLl9pbXBvcnRzXG4gIH1cblxuICBnZXQgcm91dGVzICgpOiBNYXA8SW5zdGFuY2VUb2tlblR5cGUsIEluc3RhbmNlV3JhcHBlcjxDb250cm9sbGVyVHlwZT4+IHtcbiAgICByZXR1cm4gdGhpcy5fY29udHJvbGxlcnNcbiAgfVxuXG4gIGdldCBpbmplY3RhYmxlcyAoKTogTWFwPEluc3RhbmNlVG9rZW5UeXBlLCBJbnN0YW5jZVdyYXBwZXI8SW5qZWN0YWJsZVR5cGU+PiB7XG4gICAgcmV0dXJuIHRoaXMuX2luamVjdGFibGVzXG4gIH1cblxuICBnZXQgY29udHJvbGxlcnMgKCk6IE1hcDxJbnN0YW5jZVRva2VuVHlwZSwgSW5zdGFuY2VXcmFwcGVyPENvbnRyb2xsZXJUeXBlPj4ge1xuICAgIHJldHVybiB0aGlzLl9jb250cm9sbGVyc1xuICB9XG5cbiAgZ2V0IGV4cG9ydHMgKCk6IFNldDxJbnN0YW5jZVRva2VuVHlwZT4ge1xuICAgIHJldHVybiB0aGlzLl9leHBvcnRzXG4gIH1cblxuICBnZXQgaW5zdGFuY2UgKCk6IE1vZHVsZUludGVyZmFjZSB7XG4gICAgaWYgKCF0aGlzLl9wcm92aWRlcnMuaGFzKHRoaXMuX21ldGFUeXBlKSkgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oKVxuXG4gICAgY29uc3QgbW9kdWxlID0gdGhpcy5fcHJvdmlkZXJzLmdldCh0aGlzLl9tZXRhVHlwZSlcbiAgICByZXR1cm4gbW9kdWxlLmluc3RhbmNlIGFzIE1vZHVsZUludGVyZmFjZVxuICB9XG5cbiAgZ2V0IG1ldGFUeXBlICgpOiBUeXBlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLl9tZXRhVHlwZVxuICB9XG5cbiAgZ2V0IGRpc3RhbmNlICgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9kaXN0YW5jZVxuICB9XG5cbiAgc2V0IGRpc3RhbmNlICh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5fZGlzdGFuY2UgPSB2YWx1ZVxuICB9XG5cbiAgcHVibGljIGFkZENvcmVQcm92aWRlcnMgKCkge1xuICAgIHRoaXMuYWRkTW9kdWxlQXNQcm92aWRlcigpXG4gICAgdGhpcy5hZGRNb2R1bGVSZWYoKVxuICAgIHRoaXMuYWRkQXBwbGljYXRpb25Db25maWcoKVxuICB9XG5cbiAgcHVibGljIGFkZE1vZHVsZVJlZiAoKSB7XG4gICAgY29uc3QgbW9kdWxlUmVmID0gdGhpcy5jcmVhdGVNb2R1bGVSZWZlcmVuY2VUeXBlKClcbiAgICB0aGlzLl9wcm92aWRlcnMuc2V0KFxuICAgICAgTW9kdWxlUmVmLFxuICAgICAgbmV3IEluc3RhbmNlV3JhcHBlcih7XG4gICAgICAgIHRva2VuOiBNb2R1bGVSZWYsXG4gICAgICAgIG5hbWU6IE1vZHVsZVJlZi5uYW1lLFxuICAgICAgICBtZXRhVHlwZTogTW9kdWxlUmVmIGFzIGFueSxcbiAgICAgICAgaXNSZXNvbHZlZDogdHJ1ZSxcbiAgICAgICAgaW5zdGFuY2U6IG5ldyBtb2R1bGVSZWYoKSxcbiAgICAgICAgaG9zdDogdGhpc1xuICAgICAgfSlcbiAgICApXG4gIH1cblxuICBwdWJsaWMgYWRkTW9kdWxlQXNQcm92aWRlciAoKSB7XG4gICAgdGhpcy5fcHJvdmlkZXJzLnNldChcbiAgICAgIHRoaXMuX21ldGFUeXBlLFxuICAgICAgbmV3IEluc3RhbmNlV3JhcHBlcih7XG4gICAgICAgIHRva2VuOiB0aGlzLl9tZXRhVHlwZSxcbiAgICAgICAgbmFtZTogdGhpcy5fbWV0YVR5cGUubmFtZSxcbiAgICAgICAgbWV0YVR5cGU6IHRoaXMuX21ldGFUeXBlLFxuICAgICAgICBpc1Jlc29sdmVkOiBmYWxzZSxcbiAgICAgICAgaW5zdGFuY2U6IG51bGwsXG4gICAgICAgIGhvc3Q6IHRoaXNcbiAgICAgIH0pXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGFkZEFwcGxpY2F0aW9uQ29uZmlnICgpIHtcbiAgICB0aGlzLl9wcm92aWRlcnMuc2V0KFxuICAgICAgQXBwbGljYXRpb25Db25maWcsXG4gICAgICBuZXcgSW5zdGFuY2VXcmFwcGVyKHtcbiAgICAgICAgdG9rZW46IEFwcGxpY2F0aW9uQ29uZmlnLFxuICAgICAgICBuYW1lOiBBcHBsaWNhdGlvbkNvbmZpZy5uYW1lLFxuICAgICAgICBpc1Jlc29sdmVkOiB0cnVlLFxuICAgICAgICBpbnN0YW5jZTogdGhpcy5jb250YWluZXIuYXBwbGljYXRpb25Db25maWcsXG4gICAgICAgIGhvc3Q6IHRoaXNcbiAgICAgIH0pXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGFkZEluamVjdGFibGU8VCBleHRlbmRzIEluamVjdGFibGVUeXBlPiAoXG4gICAgaW5qZWN0YWJsZTogUHJvdmlkZXJUeXBlLFxuICAgIGVuaGFuY2VyU3VidHlwZTogRW5oYW5jZXJTdWJ0eXBlLFxuICAgIGhvc3Q/OiBUeXBlPFQ+XG4gICkge1xuICAgIGlmICh0aGlzLmlzQ3VzdG9tUHJvdmlkZXIoaW5qZWN0YWJsZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLmFkZEN1c3RvbVByb3ZpZGVyKGluamVjdGFibGUsIHRoaXMuX2luamVjdGFibGVzKVxuICAgIH1cbiAgICBsZXQgaW5zdGFuY2VXcmFwcGVyID0gdGhpcy5pbmplY3RhYmxlcy5nZXQoaW5qZWN0YWJsZSlcbiAgICBpZiAoIWluc3RhbmNlV3JhcHBlcikge1xuICAgICAgaW5zdGFuY2VXcmFwcGVyID0gbmV3IEluc3RhbmNlV3JhcHBlcih7XG4gICAgICAgIHRva2VuOiBpbmplY3RhYmxlLFxuICAgICAgICBuYW1lOiBpbmplY3RhYmxlLm5hbWUsXG4gICAgICAgIG1ldGFUeXBlOiBpbmplY3RhYmxlLFxuICAgICAgICBpbnN0YW5jZTogbnVsbCxcbiAgICAgICAgaXNSZXNvbHZlZDogZmFsc2UsXG4gICAgICAgIHNjb3BlOiBnZXRDbGFzc1Njb3BlKGluamVjdGFibGUpLFxuICAgICAgICBob3N0OiB0aGlzXG4gICAgICB9KVxuICAgICAgdGhpcy5faW5qZWN0YWJsZXMuc2V0KGluamVjdGFibGUsIGluc3RhbmNlV3JhcHBlcilcbiAgICB9XG4gICAgaWYgKGhvc3QpIHtcbiAgICAgIGNvbnN0IGhvc3RXcmFwcGVyID1cbiAgICAgICAgdGhpcy5fY29udHJvbGxlcnMuZ2V0KGhvc3QpIHx8IHRoaXMuX3Byb3ZpZGVycy5nZXQoaG9zdClcbiAgICAgIGhvc3RXcmFwcGVyICYmIGhvc3RXcmFwcGVyLmFkZEVuaGFuY2VyTWV0YWRhdGEoaW5zdGFuY2VXcmFwcGVyKVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGRQcm92aWRlcihwcm92aWRlcjogUHJvdmlkZXJUeXBlKTogSW5qZWN0aW9uVG9rZW5cbiAgcHVibGljIGFkZFByb3ZpZGVyKFxuICAgIHByb3ZpZGVyOiBQcm92aWRlclR5cGUsXG4gICAgZW5oYW5jZXJTdWJ0eXBlOiBFbmhhbmNlclN1YnR5cGVcbiAgKTogSW5qZWN0aW9uVG9rZW5cbiAgcHVibGljIGFkZFByb3ZpZGVyIChcbiAgICBwcm92aWRlcjogUHJvdmlkZXJUeXBlLFxuICAgIGVuaGFuY2VyU3VidHlwZT86IEVuaGFuY2VyU3VidHlwZVxuICApIHtcbiAgICBpZiAodGhpcy5pc0N1c3RvbVByb3ZpZGVyKHByb3ZpZGVyKSkge1xuICAgICAgcmV0dXJuIHRoaXMuYWRkQ3VzdG9tUHJvdmlkZXIocHJvdmlkZXIsIHRoaXMuX3Byb3ZpZGVycywgZW5oYW5jZXJTdWJ0eXBlKVxuICAgIH1cbiAgICB0aGlzLl9wcm92aWRlcnMuc2V0KFxuICAgICAgcHJvdmlkZXIsXG4gICAgICBuZXcgSW5zdGFuY2VXcmFwcGVyKHtcbiAgICAgICAgdG9rZW46IHByb3ZpZGVyLFxuICAgICAgICBuYW1lOiAocHJvdmlkZXIgYXMgVHlwZTxJbmplY3RhYmxlVHlwZT4pLm5hbWUsXG4gICAgICAgIG1ldGFUeXBlOiBwcm92aWRlciBhcyBUeXBlPEluamVjdGFibGVUeXBlPixcbiAgICAgICAgaW5zdGFuY2U6IG51bGwsXG4gICAgICAgIGlzUmVzb2x2ZWQ6IGZhbHNlLFxuICAgICAgICBzY29wZTogZ2V0Q2xhc3NTY29wZShwcm92aWRlciksXG4gICAgICAgIGhvc3Q6IHRoaXNcbiAgICAgIH0pXG4gICAgKVxuICAgIHJldHVybiBwcm92aWRlciBhcyBUeXBlPEluamVjdGFibGVUeXBlPlxuICB9XG5cbiAgcHVibGljIGlzQ3VzdG9tUHJvdmlkZXIgKFxuICAgIHByb3ZpZGVyOiBQcm92aWRlclR5cGVcbiAgKTogcHJvdmlkZXIgaXNcbiAgICB8IENsYXNzUHJvdmlkZXJcbiAgICB8IEZhY3RvcnlQcm92aWRlclxuICAgIHwgVmFsdWVQcm92aWRlclxuICAgIHwgRXhpc3RpbmdQcm92aWRlciB7XG4gICAgcmV0dXJuICFpc05pbChcbiAgICAgIChcbiAgICAgICAgcHJvdmlkZXIgYXNcbiAgICAgICAgICB8IENsYXNzUHJvdmlkZXJcbiAgICAgICAgICB8IEZhY3RvcnlQcm92aWRlclxuICAgICAgICAgIHwgVmFsdWVQcm92aWRlclxuICAgICAgICAgIHwgRXhpc3RpbmdQcm92aWRlclxuICAgICAgKS5wcm92aWRlXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGFkZEN1c3RvbVByb3ZpZGVyIChcbiAgICBwcm92aWRlcjpcbiAgICAgIHwgQ2xhc3NQcm92aWRlclxuICAgICAgfCBGYWN0b3J5UHJvdmlkZXJcbiAgICAgIHwgVmFsdWVQcm92aWRlclxuICAgICAgfCBFeGlzdGluZ1Byb3ZpZGVyLFxuICAgIGNvbGxlY3Rpb246IE1hcDxGdW5jdGlvbiB8IHN0cmluZyB8IHN5bWJvbCwgYW55PixcbiAgICBlbmhhbmNlclN1YnR5cGU/OiBFbmhhbmNlclN1YnR5cGVcbiAgKSB7XG4gICAgaWYgKHRoaXMuaXNDdXN0b21DbGFzcyhwcm92aWRlcikpIHtcbiAgICAgIHRoaXMuYWRkQ3VzdG9tQ2xhc3MocHJvdmlkZXIsIGNvbGxlY3Rpb24sIGVuaGFuY2VyU3VidHlwZSlcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNDdXN0b21WYWx1ZShwcm92aWRlcikpIHtcbiAgICAgIHRoaXMuYWRkQ3VzdG9tVmFsdWUocHJvdmlkZXIsIGNvbGxlY3Rpb24sIGVuaGFuY2VyU3VidHlwZSlcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNDdXN0b21GYWN0b3J5KHByb3ZpZGVyKSkge1xuICAgICAgdGhpcy5hZGRDdXN0b21GYWN0b3J5KHByb3ZpZGVyLCBjb2xsZWN0aW9uLCBlbmhhbmNlclN1YnR5cGUpXG4gICAgfSBlbHNlIGlmICh0aGlzLmlzQ3VzdG9tVXNlRXhpc3RpbmcocHJvdmlkZXIpKSB7XG4gICAgICB0aGlzLmFkZEN1c3RvbVVzZUV4aXN0aW5nKHByb3ZpZGVyLCBjb2xsZWN0aW9uLCBlbmhhbmNlclN1YnR5cGUpXG4gICAgfVxuICAgIHJldHVybiBwcm92aWRlci5wcm92aWRlXG4gIH1cblxuICBwdWJsaWMgaXNDdXN0b21DbGFzcyAocHJvdmlkZXI6IGFueSk6IHByb3ZpZGVyIGlzIENsYXNzUHJvdmlkZXIge1xuICAgIHJldHVybiAhaXNVbmRlZmluZWQoKHByb3ZpZGVyIGFzIENsYXNzUHJvdmlkZXIpLnVzZUNsYXNzKVxuICB9XG5cbiAgcHVibGljIGlzQ3VzdG9tVmFsdWUgKHByb3ZpZGVyOiBhbnkpOiBwcm92aWRlciBpcyBWYWx1ZVByb3ZpZGVyIHtcbiAgICByZXR1cm4gIWlzVW5kZWZpbmVkKChwcm92aWRlciBhcyBWYWx1ZVByb3ZpZGVyKS51c2VWYWx1ZSlcbiAgfVxuXG4gIHB1YmxpYyBpc0N1c3RvbUZhY3RvcnkgKHByb3ZpZGVyOiBhbnkpOiBwcm92aWRlciBpcyBGYWN0b3J5UHJvdmlkZXIge1xuICAgIHJldHVybiAhaXNVbmRlZmluZWQoKHByb3ZpZGVyIGFzIEZhY3RvcnlQcm92aWRlcikudXNlRmFjdG9yeSlcbiAgfVxuXG4gIHB1YmxpYyBpc0N1c3RvbVVzZUV4aXN0aW5nIChwcm92aWRlcjogYW55KTogcHJvdmlkZXIgaXMgRXhpc3RpbmdQcm92aWRlciB7XG4gICAgcmV0dXJuICFpc1VuZGVmaW5lZCgocHJvdmlkZXIgYXMgRXhpc3RpbmdQcm92aWRlcikudXNlRXhpc3RpbmcpXG4gIH1cblxuICBwdWJsaWMgaXNEeW5hbWljTW9kdWxlIChleHBvcnRlZDogYW55KTogZXhwb3J0ZWQgaXMgRHluYW1pY01vZHVsZUludGVyZmFjZSB7XG4gICAgcmV0dXJuIGV4cG9ydGVkICYmIGV4cG9ydGVkLm1vZHVsZVxuICB9XG5cbiAgcHVibGljIGFkZEN1c3RvbUNsYXNzIChcbiAgICBwcm92aWRlcjogQ2xhc3NQcm92aWRlcixcbiAgICBjb2xsZWN0aW9uOiBNYXA8SW5zdGFuY2VUb2tlblR5cGUsIEluc3RhbmNlV3JhcHBlcj4sXG4gICAgZW5oYW5jZXJTdWJ0eXBlPzogRW5oYW5jZXJTdWJ0eXBlXG4gICkge1xuICAgIGxldCB7IHNjb3BlIH0gPSBwcm92aWRlclxuXG4gICAgY29uc3QgeyB1c2VDbGFzcyB9ID0gcHJvdmlkZXJcbiAgICBpZiAoaXNVbmRlZmluZWQoc2NvcGUpKSB7XG4gICAgICBzY29wZSA9IGdldENsYXNzU2NvcGUodXNlQ2xhc3MpXG4gICAgfVxuICAgIGNvbGxlY3Rpb24uc2V0KFxuICAgICAgcHJvdmlkZXIucHJvdmlkZSxcbiAgICAgIG5ldyBJbnN0YW5jZVdyYXBwZXIoe1xuICAgICAgICB0b2tlbjogcHJvdmlkZXIucHJvdmlkZSxcbiAgICAgICAgbmFtZTogdXNlQ2xhc3M/Lm5hbWUgfHwgdXNlQ2xhc3MsXG4gICAgICAgIG1ldGFUeXBlOiB1c2VDbGFzcyxcbiAgICAgICAgaW5zdGFuY2U6IG51bGwsXG4gICAgICAgIGlzUmVzb2x2ZWQ6IGZhbHNlLFxuICAgICAgICBzY29wZSxcbiAgICAgICAgaG9zdDogdGhpcyxcbiAgICAgICAgc3VidHlwZTogZW5oYW5jZXJTdWJ0eXBlXG4gICAgICB9KVxuICAgIClcbiAgfVxuXG4gIHB1YmxpYyBhZGRDdXN0b21WYWx1ZSAoXG4gICAgcHJvdmlkZXI6IFZhbHVlUHJvdmlkZXIsXG4gICAgY29sbGVjdGlvbjogTWFwPEZ1bmN0aW9uIHwgc3RyaW5nIHwgc3ltYm9sLCBJbnN0YW5jZVdyYXBwZXI+LFxuICAgIGVuaGFuY2VyU3VidHlwZT86IEVuaGFuY2VyU3VidHlwZVxuICApIHtcbiAgICBjb25zdCB7IHVzZVZhbHVlOiB2YWx1ZSwgcHJvdmlkZTogcHJvdmlkZXJUb2tlbiB9ID0gcHJvdmlkZXJcbiAgICBjb2xsZWN0aW9uLnNldChcbiAgICAgIHByb3ZpZGVyVG9rZW4sXG4gICAgICBuZXcgSW5zdGFuY2VXcmFwcGVyKHtcbiAgICAgICAgdG9rZW46IHByb3ZpZGVyVG9rZW4sXG4gICAgICAgIG5hbWU6IChwcm92aWRlclRva2VuIGFzIEZ1bmN0aW9uKT8ubmFtZSB8fCBwcm92aWRlclRva2VuLFxuICAgICAgICBtZXRhVHlwZTogbnVsbCxcbiAgICAgICAgaW5zdGFuY2U6IHZhbHVlLFxuICAgICAgICBpc1Jlc29sdmVkOiB0cnVlLFxuICAgICAgICBhc3luYzogdmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlLFxuICAgICAgICBob3N0OiB0aGlzLFxuICAgICAgICBzdWJ0eXBlOiBlbmhhbmNlclN1YnR5cGVcbiAgICAgIH0pXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGFkZEN1c3RvbUZhY3RvcnkgKFxuICAgIHByb3ZpZGVyOiBGYWN0b3J5UHJvdmlkZXIsXG4gICAgY29sbGVjdGlvbjogTWFwPEZ1bmN0aW9uIHwgc3RyaW5nIHwgc3ltYm9sLCBJbnN0YW5jZVdyYXBwZXI+LFxuICAgIGVuaGFuY2VyU3VidHlwZT86IEVuaGFuY2VyU3VidHlwZVxuICApIHtcbiAgICBjb25zdCB7XG4gICAgICB1c2VGYWN0b3J5OiBmYWN0b3J5LFxuICAgICAgaW5qZWN0LFxuICAgICAgc2NvcGUsXG4gICAgICBwcm92aWRlOiBwcm92aWRlclRva2VuXG4gICAgfSA9IHByb3ZpZGVyXG5cbiAgICBjb2xsZWN0aW9uLnNldChcbiAgICAgIHByb3ZpZGVyVG9rZW4sXG4gICAgICBuZXcgSW5zdGFuY2VXcmFwcGVyKHtcbiAgICAgICAgdG9rZW46IHByb3ZpZGVyVG9rZW4sXG4gICAgICAgIG5hbWU6IChwcm92aWRlclRva2VuIGFzIEZ1bmN0aW9uKT8ubmFtZSB8fCBwcm92aWRlclRva2VuLFxuICAgICAgICBtZXRhVHlwZTogZmFjdG9yeSBhcyBhbnksXG4gICAgICAgIGluc3RhbmNlOiBudWxsLFxuICAgICAgICBpc1Jlc29sdmVkOiBmYWxzZSxcbiAgICAgICAgaW5qZWN0OiBpbmplY3QgfHwgW10sXG4gICAgICAgIHNjb3BlLFxuICAgICAgICBob3N0OiB0aGlzLFxuICAgICAgICBzdWJ0eXBlOiBlbmhhbmNlclN1YnR5cGVcbiAgICAgIH0pXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGFkZEN1c3RvbVVzZUV4aXN0aW5nIChcbiAgICBwcm92aWRlcjogRXhpc3RpbmdQcm92aWRlcixcbiAgICBjb2xsZWN0aW9uOiBNYXA8RnVuY3Rpb24gfCBzdHJpbmcgfCBzeW1ib2wsIEluc3RhbmNlV3JhcHBlcj4sXG4gICAgZW5oYW5jZXJTdWJ0eXBlPzogRW5oYW5jZXJTdWJ0eXBlXG4gICkge1xuICAgIGNvbnN0IHsgdXNlRXhpc3RpbmcsIHByb3ZpZGU6IHByb3ZpZGVyVG9rZW4gfSA9IHByb3ZpZGVyXG4gICAgY29sbGVjdGlvbi5zZXQoXG4gICAgICBwcm92aWRlclRva2VuLFxuICAgICAgbmV3IEluc3RhbmNlV3JhcHBlcih7XG4gICAgICAgIHRva2VuOiBwcm92aWRlclRva2VuLFxuICAgICAgICBuYW1lOiAocHJvdmlkZXJUb2tlbiBhcyBGdW5jdGlvbik/Lm5hbWUgfHwgcHJvdmlkZXJUb2tlbixcbiAgICAgICAgbWV0YVR5cGU6IChpbnN0YW5jZSA9PiBpbnN0YW5jZSkgYXMgYW55LFxuICAgICAgICBpbnN0YW5jZTogbnVsbCxcbiAgICAgICAgaXNSZXNvbHZlZDogZmFsc2UsXG4gICAgICAgIGluamVjdDogW3VzZUV4aXN0aW5nXSxcbiAgICAgICAgaG9zdDogdGhpcyxcbiAgICAgICAgaXNBbGlhczogdHJ1ZSxcbiAgICAgICAgc3VidHlwZTogZW5oYW5jZXJTdWJ0eXBlXG4gICAgICB9KVxuICAgIClcbiAgfVxuXG4gIHB1YmxpYyBhZGRFeHBvcnRlZFByb3ZpZGVyIChcbiAgICBwcm92aWRlcjogUHJvdmlkZXJUeXBlIHwgc3RyaW5nIHwgc3ltYm9sIHwgRHluYW1pY01vZHVsZUludGVyZmFjZVxuICApIHtcbiAgICBjb25zdCBhZGRFeHBvcnRlZFVuaXQgPSAodG9rZW46IEluc3RhbmNlVG9rZW5UeXBlKSA9PlxuICAgICAgdGhpcy5fZXhwb3J0cy5hZGQodGhpcy52YWxpZGF0ZUV4cG9ydGVkUHJvdmlkZXIodG9rZW4pKVxuXG4gICAgaWYgKHRoaXMuaXNDdXN0b21Qcm92aWRlcihwcm92aWRlciBhcyBhbnkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5hZGRDdXN0b21FeHBvcnRlZFByb3ZpZGVyKHByb3ZpZGVyIGFzIGFueSlcbiAgICB9IGVsc2UgaWYgKGlzU3RyaW5nKHByb3ZpZGVyKSB8fCBpc1N5bWJvbChwcm92aWRlcikpIHtcbiAgICAgIHJldHVybiBhZGRFeHBvcnRlZFVuaXQocHJvdmlkZXIpXG4gICAgfSBlbHNlIGlmICh0aGlzLmlzRHluYW1pY01vZHVsZShwcm92aWRlcikpIHtcbiAgICAgIGNvbnN0IHsgbW9kdWxlOiBtb2R1bGVDbGFzc1JlZiB9ID0gcHJvdmlkZXJcbiAgICAgIHJldHVybiBhZGRFeHBvcnRlZFVuaXQobW9kdWxlQ2xhc3NSZWYpXG4gICAgfVxuICAgIGFkZEV4cG9ydGVkVW5pdChwcm92aWRlciBhcyBUeXBlPGFueT4pXG4gIH1cblxuICBwdWJsaWMgYWRkQ3VzdG9tRXhwb3J0ZWRQcm92aWRlciAoXG4gICAgcHJvdmlkZXI6IEZhY3RvcnlQcm92aWRlciB8IFZhbHVlUHJvdmlkZXIgfCBDbGFzc1Byb3ZpZGVyIHwgRXhpc3RpbmdQcm92aWRlclxuICApIHtcbiAgICBjb25zdCBwcm92aWRlID0gcHJvdmlkZXIucHJvdmlkZVxuICAgIGlmIChpc1N0cmluZyhwcm92aWRlKSB8fCBpc1N5bWJvbChwcm92aWRlKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2V4cG9ydHMuYWRkKHRoaXMudmFsaWRhdGVFeHBvcnRlZFByb3ZpZGVyKHByb3ZpZGUpKVxuICAgIH1cbiAgICB0aGlzLl9leHBvcnRzLmFkZCh0aGlzLnZhbGlkYXRlRXhwb3J0ZWRQcm92aWRlcihwcm92aWRlKSlcbiAgfVxuXG4gIHB1YmxpYyB2YWxpZGF0ZUV4cG9ydGVkUHJvdmlkZXIgKHRva2VuOiBJbnN0YW5jZVRva2VuVHlwZSkge1xuICAgIGlmICh0aGlzLl9wcm92aWRlcnMuaGFzKHRva2VuKSkge1xuICAgICAgcmV0dXJuIHRva2VuXG4gICAgfVxuICAgIGNvbnN0IGltcG9ydHMgPSBpdGVyYXRlKHRoaXMuX2ltcG9ydHMudmFsdWVzKCkpXG4gICAgICAuZmlsdGVyKGl0ZW0gPT4gISFpdGVtKVxuICAgICAgLm1hcCgoeyBtZXRhVHlwZSB9KSA9PiBtZXRhVHlwZSlcbiAgICAgIC5maWx0ZXIobWV0YVR5cGUgPT4gISFtZXRhVHlwZSlcbiAgICAgIC50b0FycmF5KClcblxuICAgIGlmICghaW1wb3J0cy5pbmNsdWRlcyh0b2tlbiBhcyBUeXBlPHVua25vd24+KSkge1xuICAgICAgY29uc3QgeyBuYW1lIH0gPSB0aGlzLl9tZXRhVHlwZVxuICAgICAgY29uc3QgcHJvdmlkZXJOYW1lID0gaXNGdW5jdGlvbih0b2tlbikgPyAodG9rZW4gYXMgRnVuY3Rpb24pLm5hbWUgOiB0b2tlblxuICAgICAgdGhyb3cgbmV3IFVua25vd25FeHBvcnRFeGNlcHRpb24ocHJvdmlkZXJOYW1lIGFzIHN0cmluZywgbmFtZSlcbiAgICB9XG4gICAgcmV0dXJuIHRva2VuXG4gIH1cblxuICBwdWJsaWMgYWRkQ29udHJvbGxlciAoY29udHJvbGxlcjogVHlwZTxDb250cm9sbGVyVHlwZT4pIHtcbiAgICB0aGlzLl9jb250cm9sbGVycy5zZXQoXG4gICAgICBjb250cm9sbGVyLFxuICAgICAgbmV3IEluc3RhbmNlV3JhcHBlcih7XG4gICAgICAgIHRva2VuOiBjb250cm9sbGVyLFxuICAgICAgICBuYW1lOiBjb250cm9sbGVyLm5hbWUsXG4gICAgICAgIG1ldGFUeXBlOiBjb250cm9sbGVyLFxuICAgICAgICBpbnN0YW5jZTogbnVsbCxcbiAgICAgICAgaXNSZXNvbHZlZDogZmFsc2UsXG4gICAgICAgIHNjb3BlOiBnZXRDbGFzc1Njb3BlKGNvbnRyb2xsZXIpLFxuICAgICAgICBob3N0OiB0aGlzXG4gICAgICB9KVxuICAgIClcblxuICAgIHRoaXMuYXNzaWduQ29udHJvbGxlclVuaXF1ZUlkKGNvbnRyb2xsZXIpXG4gIH1cblxuICBwdWJsaWMgYXNzaWduQ29udHJvbGxlclVuaXF1ZUlkIChjb250cm9sbGVyOiBUeXBlPENvbnRyb2xsZXJUeXBlPikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb250cm9sbGVyLCBDT05UUk9MTEVSX0lEX0tFWSwge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB2YWx1ZTogcmFuZG9tU3RyaW5nR2VuZXJhdG9yKClcbiAgICB9KVxuICB9XG5cbiAgcHVibGljIGFkZFJlbGF0ZWRNb2R1bGUgKG1vZHVsZTogTW9kdWxlKSB7XG4gICAgdGhpcy5faW1wb3J0cy5hZGQobW9kdWxlKVxuICB9XG5cbiAgcHVibGljIHJlcGxhY2UgKHRvUmVwbGFjZTogSW5zdGFuY2VUb2tlblR5cGUsIG9wdGlvbnM6IGFueSkge1xuICAgIGlmIChvcHRpb25zLmlzUHJvdmlkZXIgJiYgdGhpcy5oYXNQcm92aWRlcih0b1JlcGxhY2UpKSB7XG4gICAgICBjb25zdCBvcmlnaW5hbFByb3ZpZGVyID0gdGhpcy5fcHJvdmlkZXJzLmdldCh0b1JlcGxhY2UpXG5cbiAgICAgIHJldHVybiBvcmlnaW5hbFByb3ZpZGVyLm1lcmdlV2l0aCh7IHByb3ZpZGU6IHRvUmVwbGFjZSwgLi4ub3B0aW9ucyB9KVxuICAgIH0gZWxzZSBpZiAoIW9wdGlvbnMuaXNQcm92aWRlciAmJiB0aGlzLmhhc0luamVjdGFibGUodG9SZXBsYWNlKSkge1xuICAgICAgY29uc3Qgb3JpZ2luYWxJbmplY3RhYmxlID0gdGhpcy5faW5qZWN0YWJsZXMuZ2V0KHRvUmVwbGFjZSlcblxuICAgICAgcmV0dXJuIG9yaWdpbmFsSW5qZWN0YWJsZS5tZXJnZVdpdGgoe1xuICAgICAgICBwcm92aWRlOiB0b1JlcGxhY2UsXG4gICAgICAgIC4uLm9wdGlvbnNcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgcHVibGljIGhhc1Byb3ZpZGVyICh0b2tlbjogSW5zdGFuY2VUb2tlblR5cGUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fcHJvdmlkZXJzLmhhcyh0b2tlbilcbiAgfVxuXG4gIHB1YmxpYyBoYXNJbmplY3RhYmxlICh0b2tlbjogSW5zdGFuY2VUb2tlblR5cGUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faW5qZWN0YWJsZXMuaGFzKHRva2VuKVxuICB9XG5cbiAgcHVibGljIGdldFByb3ZpZGVyQnlLZXk8VCA9IGFueT4gKFxuICAgIG5hbWU6IEluc3RhbmNlVG9rZW5UeXBlXG4gICk6IEluc3RhbmNlV3JhcHBlcjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb3ZpZGVycy5nZXQobmFtZSkgYXMgSW5zdGFuY2VXcmFwcGVyPFQ+XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlTW9kdWxlUmVmZXJlbmNlVHlwZSgpOiBUeXBlPE1vZHVsZVJlZj4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBjbGFzcyBleHRlbmRzIE1vZHVsZVJlZiB7XG4gICAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoc2VsZi5jb250YWluZXIpO1xuICAgICAgfVxuXG4gICAgICBwdWJsaWMgZ2V0PFRJbnB1dCA9IGFueSwgVFJlc3VsdCA9IFRJbnB1dD4oXG4gICAgICAgIHR5cGVPclRva2VuOiBUeXBlPFRJbnB1dD4gfCBzdHJpbmcgfCBzeW1ib2wsXG4gICAgICAgIG9wdGlvbnM6IE1vZHVsZVJlZkdldE9yUmVzb2x2ZU9wdHMgPSB7fSxcbiAgICAgICk6IFRSZXN1bHQgfCBBcnJheTxUUmVzdWx0PiB7XG4gICAgICAgIG9wdGlvbnMuc3RyaWN0ID8/PSB0cnVlO1xuICAgICAgICBvcHRpb25zLmVhY2ggPz89IGZhbHNlO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmZpbmQ8VElucHV0LCBUUmVzdWx0PihcbiAgICAgICAgICB0eXBlT3JUb2tlbixcbiAgICAgICAgICBvcHRpb25zLnN0cmljdFxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHNlbGYuaWQsXG4gICAgICAgICAgICAgICAgZWFjaDogb3B0aW9ucy5lYWNoLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IG9wdGlvbnMsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHB1YmxpYyByZXNvbHZlPFRJbnB1dCA9IGFueSwgVFJlc3VsdCA9IFRJbnB1dD4oXG4gICAgICAgIHR5cGVPclRva2VuOiBUeXBlPFRJbnB1dD4gfCBzdHJpbmcgfCBzeW1ib2wsXG4gICAgICAgIGNvbnRleHRJZCA9IGNyZWF0ZUNvbnRleHRJZCgpLFxuICAgICAgICBvcHRpb25zOiBNb2R1bGVSZWZHZXRPclJlc29sdmVPcHRzID0ge30sXG4gICAgICApOiBQcm9taXNlPFRSZXN1bHQgfCBBcnJheTxUUmVzdWx0Pj4ge1xuICAgICAgICBvcHRpb25zLnN0cmljdCA/Pz0gdHJ1ZTtcbiAgICAgICAgb3B0aW9ucy5lYWNoID8/PSBmYWxzZTtcblxuICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlUGVyQ29udGV4dDxUSW5wdXQsIFRSZXN1bHQ+KFxuICAgICAgICAgIHR5cGVPclRva2VuLFxuICAgICAgICAgIHNlbGYsXG4gICAgICAgICAgY29udGV4dElkLFxuICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHB1YmxpYyBhc3luYyBjcmVhdGU8VCA9IGFueT4oXG4gICAgICAgIHR5cGU6IFR5cGU8VD4sXG4gICAgICAgIGNvbnRleHRJZD86IENvbnRleHRJZCxcbiAgICAgICk6IFByb21pc2U8VD4ge1xuICAgICAgICBpZiAoISh0eXBlICYmIGlzRnVuY3Rpb24odHlwZSkgJiYgdHlwZS5wcm90b3R5cGUpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDbGFzc0V4Y2VwdGlvbih0eXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5pbnN0YW50aWF0ZUNsYXNzPFQ+KHR5cGUsIHNlbGYsIGNvbnRleHRJZCk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxuIl19