@tsclean/core
Version:
Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.
405 lines • 77.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Injector = void 0;
const iterare_1 = require("iterare");
const runtime_1 = require("../../errors/exceptions/runtime");
const undefined_dependency_1 = require("../../errors/exceptions/undefined-dependency");
const unknown_dependencies_1 = require("../../errors/exceptions/unknown-dependencies");
const constants_1 = require("./constants");
const inquirer_1 = require("./inquirer");
const instance_wrapper_1 = require("./instance-wrapper");
const utils_1 = require("../../utils");
const helpers_1 = require("../../helpers");
const services_1 = require("../../services");
class Injector {
constructor(options) {
this.options = options;
this.logger = new services_1.Logger('InjectorLogger');
}
loadPrototype({ token }, collection, contextId = constants_1.STATIC_CONTEXT) {
if (!collection) {
return;
}
const target = collection.get(token);
const instance = target.createPrototype(contextId);
if (instance) {
const wrapper = new instance_wrapper_1.InstanceWrapper(Object.assign(Object.assign({}, target), { instance }));
collection.set(token, wrapper);
}
}
async loadInstance(wrapper, collection, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) {
const inquirerId = Injector.getInquirerId(inquirer);
const instanceHost = wrapper.getInstanceByContextId(contextId, inquirerId);
if (instanceHost.isPending) {
return instanceHost.donePromise;
}
const done = this.applyDoneHook(instanceHost);
const token = wrapper.token || wrapper.name;
const { inject } = wrapper;
const targetWrapper = collection.get(token);
if ((0, utils_1.isUndefined)(targetWrapper)) {
throw new runtime_1.RuntimeException();
}
if (instanceHost.isResolved) {
return done();
}
const callback = async (instances) => {
const properties = await this.resolveProperties(wrapper, moduleRef, inject, contextId, wrapper, inquirer);
const instance = await this.instantiateClass(instances, wrapper, targetWrapper, contextId, inquirer);
this.applyProperties(instance, properties);
done();
};
await this.resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId, wrapper, inquirer);
}
async loadMiddleware(wrapper, collection, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) {
const { metaType, token } = wrapper;
const targetWrapper = collection.get(token);
if (!(0, utils_1.isUndefined)(targetWrapper.instance)) {
return;
}
targetWrapper.instance = Object.create(metaType.prototype);
await this.loadInstance(wrapper, collection, moduleRef, contextId, inquirer || wrapper);
}
async loadController(wrapper, moduleRef, contextId = constants_1.STATIC_CONTEXT) {
const controllers = moduleRef.controllers;
await this.loadInstance(wrapper, controllers, moduleRef, contextId, wrapper);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
async loadInjectable(wrapper, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) {
const injectables = moduleRef.injectables;
await this.loadInstance(wrapper, injectables, moduleRef, contextId, inquirer);
}
async loadProvider(wrapper, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer) {
const providers = moduleRef.providers;
await this.loadInstance(wrapper, providers, moduleRef, contextId, inquirer);
await this.loadEnhancersPerContext(wrapper, contextId, wrapper);
}
applyDoneHook(wrapper) {
let done;
wrapper.donePromise = new Promise((resolve, reject) => {
done = resolve;
});
wrapper.isPending = true;
return done;
}
async resolveConstructorParams(wrapper, moduleRef, inject, callback, contextId = constants_1.STATIC_CONTEXT, inquirer, parentInquirer) {
let inquirerId = Injector.getInquirerId(inquirer);
const metadata = wrapper.getCtorMetadata();
if (metadata && contextId !== constants_1.STATIC_CONTEXT) {
const deps = await this.loadCtorMetadata(metadata, contextId, inquirer, parentInquirer);
return callback(deps);
}
const dependencies = (0, utils_1.isNil)(inject)
? this.reflectConstructorParams(wrapper.metaType)
: inject;
const optionalDependenciesIds = (0, utils_1.isNil)(inject)
? this.reflectOptionalParams(wrapper.metaType)
: [];
let isResolved = true;
const resolveParam = async (param, index) => {
try {
if (Injector.isInquirer(param, parentInquirer)) {
return parentInquirer && parentInquirer.instance;
}
if ((inquirer === null || inquirer === void 0 ? void 0 : inquirer.isTransient) && parentInquirer) {
inquirer = parentInquirer;
inquirerId = Injector.getInquirerId(parentInquirer);
}
const paramWrapper = await this.resolveSingleParam(wrapper, param, { index, dependencies }, moduleRef, contextId, inquirer, index);
const instanceHost = paramWrapper.getInstanceByContextId(contextId, inquirerId);
if (!instanceHost.isResolved && !paramWrapper.forwardRef) {
isResolved = false;
}
return instanceHost === null || instanceHost === void 0 ? void 0 : instanceHost.instance;
}
catch (err) {
const isOptional = optionalDependenciesIds.includes(index);
if (!isOptional) {
throw err;
}
return undefined;
}
};
const instances = await Promise.all(dependencies.map(resolveParam));
isResolved && (await callback(instances));
}
reflectConstructorParams(type) {
const paramtypes = Reflect.getMetadata(helpers_1.PARAMTYPES_METADATA, type) || [];
const selfParams = this.reflectSelfParams(type);
selfParams.forEach(({ index, param }) => (paramtypes[index] = param));
return paramtypes;
}
reflectOptionalParams(type) {
return Reflect.getMetadata(helpers_1.OPTIONAL_DEPS_METADATA, type) || [];
}
reflectSelfParams(type) {
return Reflect.getMetadata(helpers_1.SELF_DECLARED_DEPS_METADATA, type) || [];
}
async resolveSingleParam(wrapper, param, dependencyContext, moduleRef, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) {
if ((0, utils_1.isUndefined)(param)) {
throw new undefined_dependency_1.UndefinedDependencyException(wrapper.name, dependencyContext, moduleRef);
}
const token = this.resolveParamToken(wrapper, param);
return this.resolveComponentInstance(moduleRef, token, dependencyContext, wrapper, contextId, inquirer, keyOrIndex);
}
resolveParamToken(wrapper, param) {
if (!param.forwardRef) {
return param;
}
wrapper.forwardRef = true;
return param.forwardRef();
}
async resolveComponentInstance(moduleRef, token, dependencyContext, wrapper, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) {
this.printResolvingDependenciesLog(token, inquirer);
this.printLookingForProviderLog(token, moduleRef);
const providers = moduleRef.providers;
const instanceWrapper = await this.lookupComponent(providers, moduleRef, Object.assign(Object.assign({}, dependencyContext), { name: token }), wrapper, contextId, inquirer, keyOrIndex);
return this.resolveComponentHost(moduleRef, instanceWrapper, contextId, inquirer);
}
async resolveComponentHost(moduleRef, instanceWrapper, contextId = constants_1.STATIC_CONTEXT, inquirer) {
const inquirerId = Injector.getInquirerId(inquirer);
const instanceHost = instanceWrapper.getInstanceByContextId(contextId, inquirerId);
if (!instanceHost.isResolved && !instanceWrapper.forwardRef) {
await this.loadProvider(instanceWrapper, moduleRef, contextId, inquirer);
}
else if (!instanceHost.isResolved &&
instanceWrapper.forwardRef &&
(contextId !== constants_1.STATIC_CONTEXT || !!inquirerId)) {
/**
* When circular dependency has been detected between
* either request/transient providers, we have to asynchronously
* resolve instance host for a specific contextId or inquirer, to ensure
* that eventual lazily created instance will be merged with the prototype
* instantiated beforehand.
*/
instanceHost.donePromise &&
instanceHost.donePromise.then(() => this.loadProvider(instanceWrapper, moduleRef, contextId, inquirer));
}
if (instanceWrapper.async) {
const host = instanceWrapper.getInstanceByContextId(contextId, inquirerId);
host.instance = await host.instance;
instanceWrapper.setInstanceByContextId(contextId, host, inquirerId);
}
return instanceWrapper;
}
async lookupComponent(providers, moduleRef, dependencyContext, wrapper, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) {
const { name } = dependencyContext;
if (wrapper && wrapper.name === name) {
throw new unknown_dependencies_1.UnknownDependenciesException(wrapper.name, dependencyContext, moduleRef);
}
if (providers.has(name)) {
const instanceWrapper = providers.get(name);
this.printFoundInModuleLog(name, moduleRef);
Injector.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapper);
return instanceWrapper;
}
return this.lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, contextId, inquirer, keyOrIndex);
}
async lookupComponentInParentModules(dependencyContext, moduleRef, wrapper, contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex) {
const instanceWrapper = await this.lookupComponentInImports(moduleRef, dependencyContext.name, wrapper, [], contextId, inquirer, keyOrIndex);
if ((0, utils_1.isNil)(instanceWrapper)) {
throw new unknown_dependencies_1.UnknownDependenciesException(wrapper.name, dependencyContext, moduleRef);
}
return instanceWrapper;
}
async lookupComponentInImports(moduleRef, name, wrapper, moduleRegistry = [], contextId = constants_1.STATIC_CONTEXT, inquirer, keyOrIndex, isTraversing) {
let instanceWrapperRef = null;
const imports = moduleRef.imports || new Set();
const identity = (item) => item;
let children = [...imports.values()].filter(identity);
if (isTraversing) {
const contextModuleExports = moduleRef.exports;
children = children.filter(child => contextModuleExports.has(child.metaType));
}
for (const relatedModule of children) {
if (moduleRegistry.includes(relatedModule.id)) {
continue;
}
this.printLookingForProviderLog(name, relatedModule);
moduleRegistry.push(relatedModule.id);
const { providers, exports } = relatedModule;
if (!exports.has(name) || !providers.has(name)) {
const instanceRef = await this.lookupComponentInImports(relatedModule, name, wrapper, moduleRegistry, contextId, inquirer, keyOrIndex, true);
if (instanceRef) {
Injector.addDependencyMetadata(keyOrIndex, wrapper, instanceRef);
return instanceRef;
}
continue;
}
this.printFoundInModuleLog(name, relatedModule);
instanceWrapperRef = providers.get(name);
Injector.addDependencyMetadata(keyOrIndex, wrapper, instanceWrapperRef);
const inquirerId = Injector.getInquirerId(inquirer);
const instanceHost = instanceWrapperRef.getInstanceByContextId(contextId, inquirerId);
if (!instanceHost.isResolved && !instanceWrapperRef.forwardRef) {
await this.loadProvider(instanceWrapperRef, relatedModule, contextId, wrapper);
break;
}
}
return instanceWrapperRef;
}
async resolveProperties(wrapper, moduleRef, inject, contextId = constants_1.STATIC_CONTEXT, inquirer, parentInquirer) {
if (!(0, utils_1.isNil)(inject)) {
return [];
}
const metadata = wrapper.getPropertiesMetadata();
if (metadata && contextId !== constants_1.STATIC_CONTEXT) {
return this.loadPropertiesMetadata(metadata, contextId, inquirer);
}
const properties = this.reflectProperties(wrapper.metaType);
const instances = await Promise.all(properties.map(async (item) => {
try {
const dependencyContext = {
key: item.key,
name: item.name
};
if (Injector.isInquirer(item.name, parentInquirer)) {
return parentInquirer && parentInquirer.instance;
}
const paramWrapper = await this.resolveSingleParam(wrapper, item.name, dependencyContext, moduleRef, contextId, inquirer, item.key);
if (!paramWrapper) {
return undefined;
}
const inquirerId = Injector.getInquirerId(inquirer);
const instanceHost = paramWrapper.getInstanceByContextId(contextId, inquirerId);
return instanceHost.instance;
}
catch (err) {
if (!item.isOptional) {
throw err;
}
return undefined;
}
}));
return properties.map((item, index) => (Object.assign(Object.assign({}, item), { instance: instances[index] })));
}
reflectProperties(type) {
const properties = Reflect.getMetadata(helpers_1.PROPERTY_DEPS_METADATA, type) || [];
const optionalKeys = Reflect.getMetadata(helpers_1.OPTIONAL_PROPERTY_DEPS_METADATA, type) || [];
return properties.map((item) => (Object.assign(Object.assign({}, item), { name: item.type, isOptional: optionalKeys.includes(item.key) })));
}
applyProperties(instance, properties) {
if (!(0, utils_1.isObject)(instance)) {
return undefined;
}
(0, iterare_1.iterate)(properties)
.filter(item => !(0, utils_1.isNil)(item.instance))
.forEach(item => (instance[item.key] = item.instance));
}
async instantiateClass(instances, wrapper, targetMetatype, contextId = constants_1.STATIC_CONTEXT, inquirer) {
var _a, _b;
const { metaType, inject } = wrapper;
const inquirerId = Injector.getInquirerId(inquirer);
const instanceHost = targetMetatype.getInstanceByContextId(contextId, inquirerId);
const isInContext = wrapper.isStatic(contextId, inquirer) ||
wrapper.isInRequestScope(contextId, inquirer) ||
wrapper.isLazyTransient(contextId, inquirer) ||
wrapper.isExplicitlyRequested(contextId, inquirer);
if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.preview) && !((_b = wrapper.host) === null || _b === void 0 ? void 0 : _b.initOnPreview)) {
instanceHost.isResolved = true;
return instanceHost.instance;
}
if ((0, utils_1.isNil)(inject) && isInContext) {
instanceHost.instance = wrapper.forwardRef
? Object.assign(instanceHost.instance, new metaType(...instances))
: new metaType(...instances);
}
else if (isInContext) {
const factoryReturnValue = targetMetatype.metaType(...instances);
instanceHost.instance = await factoryReturnValue;
}
instanceHost.isResolved = true;
return instanceHost.instance;
}
async loadPerContext(instance, moduleRef, collection, ctx, wrapper) {
if (!wrapper) {
const injectionToken = instance.constructor;
wrapper = collection.get(injectionToken);
}
await this.loadInstance(wrapper, collection, moduleRef, ctx, wrapper);
await this.loadEnhancersPerContext(wrapper, ctx, wrapper);
const host = wrapper.getInstanceByContextId(ctx, wrapper.id);
return host && host.instance;
}
async loadEnhancersPerContext(wrapper, ctx, inquirer) {
const enhancers = wrapper.getEnhancersMetadata() || [];
const loadEnhancer = (item) => {
const hostModule = item.host;
return this.loadInstance(item, hostModule.injectables, hostModule, ctx, inquirer);
};
await Promise.all(enhancers.map(loadEnhancer));
}
async loadCtorMetadata(metadata, contextId, inquirer, parentInquirer) {
const hosts = await Promise.all(metadata.map(async (item) => this.resolveScopedComponentHost(item, contextId, inquirer, parentInquirer)));
const inquirerId = Injector.getInquirerId(inquirer);
return hosts.map(item => item.getInstanceByContextId(contextId, inquirerId).instance);
}
async loadPropertiesMetadata(metadata, contextId, inquirer) {
const dependenciesHosts = await Promise.all(metadata.map(async ({ wrapper: item, key }) => ({
key,
host: await this.resolveComponentHost(item.host, item, contextId, inquirer)
})));
const inquirerId = Injector.getInquirerId(inquirer);
return dependenciesHosts.map(({ key, host }) => ({
key,
name: key,
instance: host.getInstanceByContextId(contextId, inquirerId).instance
}));
}
static getInquirerId(inquirer) {
return inquirer && inquirer.id;
}
resolveScopedComponentHost(item, contextId, inquirer, parentInquirer) {
return Injector.isInquirerRequest(item, parentInquirer)
? parentInquirer
: this.resolveComponentHost(item.host, item, contextId, inquirer);
}
static isInquirerRequest(item, parentInquirer) {
return item.isTransient && item.name === inquirer_1.INQUIRER && parentInquirer;
}
static isInquirer(param, parentInquirer) {
return param === inquirer_1.INQUIRER && parentInquirer;
}
static addDependencyMetadata(keyOrIndex, hostWrapper, instanceWrapper) {
(0, utils_1.isString)(keyOrIndex)
? hostWrapper.addPropertiesMetadata(keyOrIndex, instanceWrapper)
: hostWrapper.addCtorMetadata(keyOrIndex, instanceWrapper);
}
static getTokenName(token) {
return (0, utils_1.isFunction)(token) ? token.name : token.toString();
}
printResolvingDependenciesLog(token, inquirer) {
var _a;
if (!Injector.isDebugMode()) {
return;
}
const tokenName = Injector.getTokenName(token);
const dependentName = (_a = inquirer === null || inquirer === void 0 ? void 0 : inquirer.name) !== null && _a !== void 0 ? _a : 'unknown';
const isAlias = dependentName === tokenName;
const messageToPrint = `Resolving dependency ${utils_1.clc.cyanBright(tokenName)}${utils_1.clc.green(' in the ')}${utils_1.clc.yellow(dependentName)}${utils_1.clc.green(` provider ${isAlias ? '(alias)' : ''}`)}`;
this.logger.log(messageToPrint);
}
printLookingForProviderLog(token, moduleRef) {
var _a, _b;
if (!Injector.isDebugMode()) {
return;
}
const tokenName = Injector.getTokenName(token);
const moduleRefName = (_b = (_a = moduleRef === null || moduleRef === void 0 ? void 0 : moduleRef.metaType) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'unknown';
this.logger.log(`Looking for ${utils_1.clc.cyanBright(tokenName)}${utils_1.clc.green(' in ')}${utils_1.clc.magentaBright(moduleRefName)}`);
}
printFoundInModuleLog(token, moduleRef) {
var _a, _b;
if (!Injector.isDebugMode()) {
return;
}
const tokenName = Injector.getTokenName(token);
const moduleRefName = (_b = (_a = moduleRef === null || moduleRef === void 0 ? void 0 : moduleRef.metaType) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'unknown';
this.logger.log(`Found ${utils_1.clc.cyanBright(tokenName)}${utils_1.clc.green(' in ')}${utils_1.clc.magentaBright(moduleRefName)}`);
}
static isDebugMode() {
return !!process.env.NEST_DEBUG;
}
}
exports.Injector = Injector;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9pbmplY3Rvci9pbmplY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxQ0FBaUM7QUFDakMsNkRBQWtFO0FBQ2xFLHVGQUEyRjtBQUMzRix1RkFBMkY7QUFDM0YsMkNBQTRDO0FBQzVDLHlDQUFxQztBQUNyQyx5REFLMkI7QUFHM0IsdUNBT29CO0FBQ3BCLDJDQU1zQjtBQUN0Qiw2Q0FBc0Q7QUFzQnRELE1BQWEsUUFBUTtJQUduQixZQUE4QixPQUE4QjtRQUE5QixZQUFPLEdBQVAsT0FBTyxDQUF1QjtRQUZwRCxXQUFNLEdBQWtCLElBQUksaUJBQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBRUcsQ0FBQztJQUV6RCxhQUFhLENBQ2xCLEVBQUUsS0FBSyxFQUFzQixFQUM3QixVQUFzRCxFQUN0RCxTQUFTLEdBQUcsMEJBQWM7UUFFMUIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE9BQU07UUFDUixDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNwQyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQ2xELElBQUksUUFBUSxFQUFFLENBQUM7WUFDYixNQUFNLE9BQU8sR0FBRyxJQUFJLGtDQUFlLGlDQUM5QixNQUFNLEtBQ1QsUUFBUSxJQUNSLENBQUE7WUFDRixVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVNLEtBQUssQ0FBQyxZQUFZLENBQ3ZCLE9BQTJCLEVBQzNCLFVBQW1ELEVBQ25ELFNBQWlCLEVBQ2pCLFNBQVMsR0FBRywwQkFBYyxFQUMxQixRQUEwQjtRQUUxQixNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFD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QUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUE7SUFDakMsQ0FBQztDQUNGO0FBMXdCRCw0QkEwd0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXRlcmF0ZSB9IGZyb20gJ2l0ZXJhcmUnXG5pbXBvcnQgeyBSdW50aW1lRXhjZXB0aW9uIH0gZnJvbSAnLi4vLi4vZXJyb3JzL2V4Y2VwdGlvbnMvcnVudGltZSdcbmltcG9ydCB7IFVuZGVmaW5lZERlcGVuZGVuY3lFeGNlcHRpb24gfSBmcm9tICcuLi8uLi9lcnJvcnMvZXhjZXB0aW9ucy91bmRlZmluZWQtZGVwZW5kZW5jeSdcbmltcG9ydCB7IFVua25vd25EZXBlbmRlbmNpZXNFeGNlcHRpb24gfSBmcm9tICcuLi8uLi9lcnJvcnMvZXhjZXB0aW9ucy91bmtub3duLWRlcGVuZGVuY2llcydcbmltcG9ydCB7IFNUQVRJQ19DT05URVhUIH0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBJTlFVSVJFUiB9IGZyb20gJy4vaW5xdWlyZXInXG5pbXBvcnQge1xuICBDb250ZXh0SWQsXG4gIEluc3RhbmNlUGVyQ29udGV4dCxcbiAgSW5zdGFuY2VXcmFwcGVyLFxuICBQcm9wZXJ0eU1ldGFkYXRhXG59IGZyb20gJy4vaW5zdGFuY2Utd3JhcHBlcidcbmltcG9ydCB7IE1vZHVsZSB9IGZyb20gJy4vbW9kdWxlJ1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cydcbmltcG9ydCB7XG4gIGlzRnVuY3Rpb24sXG4gIGlzTmlsLFxuICBpc09iamVjdCxcbiAgaXNTdHJpbmcsXG4gIGlzVW5kZWZpbmVkLFxuICBjbGNcbn0gZnJvbSAnLi4vLi4vdXRpbHMnXG5pbXBvcnQge1xuICBPUFRJT05BTF9ERVBTX01FVEFEQVRBLFxuICBPUFRJT05BTF9QUk9QRVJUWV9ERVBTX01FVEFEQVRBLFxuICBQQVJBTVRZUEVTX01FVEFEQVRBLFxuICBQUk9QRVJUWV9ERVBTX01FVEFEQVRBLFxuICBTRUxGX0RFQ0xBUkVEX0RFUFNfTUVUQURBVEFcbn0gZnJvbSAnLi4vLi4vaGVscGVycydcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2VyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzJ1xuaW1wb3J0IHsgQ29udHJvbGxlclR5cGUsIEluamVjdGFibGVUeXBlLCBJbnN0YW5jZVRva2VuVHlwZSB9IGZyb20gJy4uLy4uL3R5cGVzJ1xuXG5leHBvcnQgdHlwZSBJbmplY3RvckRlcGVuZGVuY3kgPSBUeXBlPGFueT4gfCBGdW5jdGlvbiB8IHN0cmluZyB8IHN5bWJvbFxuXG5leHBvcnQgaW50ZXJmYWNlIFByb3BlcnR5RGVwZW5kZW5jeSB7XG4gIGtleTogc3RyaW5nXG4gIG5hbWU6IEluamVjdG9yRGVwZW5kZW5jeVxuICBpc09wdGlvbmFsPzogYm9vbGVhblxuICBpbnN0YW5jZT86IGFueVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluamVjdG9yRGVwZW5kZW5jeUNvbnRleHQge1xuICBrZXk/OiBzdHJpbmcgfCBzeW1ib2xcblxuICBuYW1lPzogRnVuY3Rpb24gfCBzdHJpbmcgfCBzeW1ib2xcblxuICBpbmRleD86IG51bWJlclxuXG4gIGRlcGVuZGVuY2llcz86IEluamVjdG9yRGVwZW5kZW5jeVtdXG59XG5cbmV4cG9ydCBjbGFzcyBJbmplY3RvciB7XG4gIHByaXZhdGUgbG9nZ2VyOiBMb2dnZXJTZXJ2aWNlID0gbmV3IExvZ2dlcignSW5qZWN0b3JMb2dnZXInKVxuXG4gIGNvbnN0cnVjdG9yIChwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM/OiB7IHByZXZpZXc6IGJvb2xlYW4gfSkge31cblxuICBwdWJsaWMgbG9hZFByb3RvdHlwZTxUPiAoXG4gICAgeyB0b2tlbiB9OiBJbnN0YW5jZVdyYXBwZXI8VD4sXG4gICAgY29sbGVjdGlvbjogTWFwPEluc3RhbmNlVG9rZW5UeXBlLCBJbnN0YW5jZVdyYXBwZXI8VD4+LFxuICAgIGNvbnRleHRJZCA9IFNUQVRJQ19DT05URVhUXG4gICkge1xuICAgIGlmICghY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGNvbnN0IHRhcmdldCA9IGNvbGxlY3Rpb24uZ2V0KHRva2VuKVxuICAgIGNvbnN0IGluc3RhbmNlID0gdGFyZ2V0LmNyZWF0ZVByb3RvdHlwZShjb250ZXh0SWQpXG4gICAgaWYgKGluc3RhbmNlKSB7XG4gICAgICBjb25zdCB3cmFwcGVyID0gbmV3IEluc3RhbmNlV3JhcHBlcih7XG4gICAgICAgIC4uLnRhcmdldCxcbiAgICAgICAgaW5zdGFuY2VcbiAgICAgIH0pXG4gICAgICBjb2xsZWN0aW9uLnNldCh0b2tlbiwgd3JhcHBlcilcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbG9hZEluc3RhbmNlPFQ+IChcbiAgICB3cmFwcGVyOiBJbnN0YW5jZVdyYXBwZXI8VD4sXG4gICAgY29sbGVjdGlvbjogTWFwPEluc3RhbmNlVG9rZW5UeXBlLCBJbnN0YW5jZVdyYXBwZXI+LFxuICAgIG1vZHVsZVJlZjogTW9kdWxlLFxuICAgIGNvbnRleHRJZCA9IFNUQVRJQ19DT05URVhULFxuICAgIGlucXVpcmVyPzogSW5zdGFuY2VXcmFwcGVyXG4gICkge1xuICAgIGNvbnN0IGlucXVpcmVySWQgPSBJbmplY3Rvci5nZXRJbnF1aXJlcklkKGlucXVpcmVyKVxuICAgIGNvbnN0IGluc3RhbmNlSG9zdCA9IHdyYXBwZXIuZ2V0SW5zdGFuY2VCeUNvbnRleHRJZChjb250ZXh0SWQsIGlucXVpcmVySWQpXG4gICAgaWYgKGluc3RhbmNlSG9zdC5pc1BlbmRpbmcpIHtcbiAgICAgIHJldHVybiBpbnN0YW5jZUhvc3QuZG9uZVByb21pc2VcbiAgICB9XG4gICAgY29uc3QgZG9uZSA9IHRoaXMuYXBwbHlEb25lSG9vayhpbnN0YW5jZUhvc3QpXG4gICAgY29uc3QgdG9rZW4gPSB3cmFwcGVyLnRva2VuIHx8IHdyYXBwZXIubmFtZVxuXG4gICAgY29uc3QgeyBpbmplY3QgfSA9IHdyYXBwZXJcbiAgICBjb25zdCB0YXJnZXRXcmFwcGVyID0gY29sbGVjdGlvbi5nZXQodG9rZW4pXG4gICAgaWYgKGlzVW5kZWZpbmVkKHRhcmdldFdyYXBwZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigpXG4gICAgfVxuICAgIGlmIChpbnN0YW5jZUhvc3QuaXNSZXNvbHZlZCkge1xuICAgICAgcmV0dXJuIGRvbmUoKVxuICAgIH1cbiAgICBjb25zdCBjYWxsYmFjayA9IGFzeW5jIChpbnN0YW5jZXM6IHVua25vd25bXSkgPT4ge1xuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGF3YWl0IHRoaXMucmVzb2x2ZVByb3BlcnRpZXMoXG4gICAgICAgIHdyYXBwZXIsXG4gICAgICAgIG1vZHVsZVJlZixcbiAgICAgICAgaW5qZWN0LFxuICAgICAgICBjb250ZXh0SWQsXG4gICAgICAgIHdyYXBwZXIsXG4gICAgICAgIGlucXVpcmVyXG4gICAgICApXG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IHRoaXMuaW5zdGFudGlhdGVDbGFzcyhcbiAgICAgICAgaW5zdGFuY2VzLFxuICAgICAgICB3cmFwcGVyLFxuICAgICAgICB0YXJnZXRXcmFwcGVyLFxuICAgICAgICBjb250ZXh0SWQsXG4gICAgICAgIGlucXVpcmVyXG4gICAgICApXG4gICAgICB0aGlzLmFwcGx5UHJvcGVydGllcyhpbnN0YW5jZSwgcHJvcGVydGllcylcbiAgICAgIGRvbmUoKVxuICAgIH1cbiAgICBhd2FpdCB0aGlzLnJlc29sdmVDb25zdHJ1Y3RvclBhcmFtczxUPihcbiAgICAgIHdyYXBwZXIsXG4gICAgICBtb2R1bGVSZWYsXG4gICAgICBpbmplY3QsXG4gICAgICBjYWxsYmFjayxcbiAgICAgIGNvbnRleHRJZCxcbiAgICAgIHdyYXBwZXIsXG4gICAgICBpbnF1aXJlclxuICAgIClcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsb2FkTWlkZGxld2FyZSAoXG4gICAgd3JhcHBlcjogSW5zdGFuY2VXcmFwcGVyLFxuICAgIGNvbGxlY3Rpb246IE1hcDxJbnN0YW5jZVRva2VuVHlwZSwgSW5zdGFuY2VXcmFwcGVyPixcbiAgICBtb2R1bGVSZWY6IE1vZHVsZSxcbiAgICBjb250ZXh0SWQgPSBTVEFUSUNfQ09OVEVYVCxcbiAgICBpbnF1aXJlcj86IEluc3RhbmNlV3JhcH