@tsclean/core
Version:
Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.
364 lines • 49 kB
JavaScript
"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