@jsbailey/reactive-form-validators
Version:
[](https://badge.fury.io/js/%40rxweb%2Freactive-form-validators) [](https://gitter.im/rxweb-project/rxweb?utm_source=badge
388 lines (387 loc) • 53.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Injectable } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { alphaNumericValidator, alphaValidator, compareValidator, emailValidator, hexColorValidator, lowercaseValidator, maxDateValidator, maxNumberValidator, minDateValidator, minNumberValidator, containsValidator, uppercaseValidator, rangeValidator, patternValidator, requiredValidator, creditCardValidator, digitValidator, maxLengthValidator, minLengthValidator, passwordValidator, timeValidator, urlValidator, jsonValidator, greaterThanEqualToValidator, greaterThanValidator, lessThanEqualToValidator, lessThanValidator } from '../reactive-form-validators';
import { defaultContainer } from '../core/defaultContainer';
import { FormBuilderConfiguration } from "../models";
import { ARRAY_PROPERTY, OBJECT_PROPERTY, PROPERTY } from "../const";
import { AnnotationTypes } from "../core/validator.static";
import { conditionalChangeValidator } from "../reactive-form-validators/conditional-change.validator";
import { Linq } from '../util/linq';
/** @type {?} */
var APP_VALIDATORS = {
"alphaNumeric": alphaNumericValidator,
"alpha": alphaValidator,
"compare": compareValidator,
"email": emailValidator,
"hexColor": hexColorValidator,
"lowerCase": lowercaseValidator,
"maxDate": maxDateValidator,
"maxNumber": maxNumberValidator,
"minDate": minDateValidator,
"minNumber": minNumberValidator,
"contains": containsValidator,
"upperCase": uppercaseValidator,
"maxLength": maxLengthValidator,
"minLength": minLengthValidator,
"password": passwordValidator,
"range": rangeValidator,
"required": requiredValidator,
"creditCard": creditCardValidator,
"digit": digitValidator,
"pattern": patternValidator,
"time": timeValidator,
"url": urlValidator,
"json": jsonValidator,
"greaterThan": greaterThanValidator,
"greaterThanEqualTo": greaterThanEqualToValidator,
"lessThan": lessThanValidator,
"lessThanEqualTo": lessThanEqualToValidator
};
var RxFormBuilder = /** @class */ (function () {
function RxFormBuilder(formBuilder) {
this.formBuilder = formBuilder;
this.conditionalObjectProps = [];
this.conditionalValidationInstance = {};
this.builderConfigurationConditionalObjectProps = [];
this.isNested = false;
}
/**
* @param {?} instanceFunc
* @return {?}
*/
RxFormBuilder.prototype.getInstanceContainer = /**
* @param {?} instanceFunc
* @return {?}
*/
function (instanceFunc) {
return defaultContainer.get(instanceFunc);
};
/**
* @param {?} formGroup
* @param {?} object
* @return {?}
*/
RxFormBuilder.prototype.setValue = /**
* @param {?} formGroup
* @param {?} object
* @return {?}
*/
function (formGroup, object) {
for (var col in object) {
/** @type {?} */
var control = formGroup.get([col]);
control.setValue(object[col]);
control.updateValueAndValidity();
}
};
/**
* @param {?} fomrBuilderConfiguration
* @return {?}
*/
RxFormBuilder.prototype.extractExpressions = /**
* @param {?} fomrBuilderConfiguration
* @return {?}
*/
function (fomrBuilderConfiguration) {
if (fomrBuilderConfiguration && fomrBuilderConfiguration.validations) {
for (var property in fomrBuilderConfiguration.validations) {
for (var decorator in fomrBuilderConfiguration.validations[property]) {
if (fomrBuilderConfiguration.validations[property][decorator].conditionalExpression) {
/** @type {?} */
var columns = Linq.expressionColumns(fomrBuilderConfiguration.validations[property][decorator].conditionalExpression);
defaultContainer.addChangeValidation(this.conditionalValidationInstance, property, columns);
}
}
}
}
return null;
};
/**
* @param {?} property
* @param {?} propertyValidators
* @param {?} propValidationConfig
* @param {?} instance
* @return {?}
*/
RxFormBuilder.prototype.addFormControl = /**
* @param {?} property
* @param {?} propertyValidators
* @param {?} propValidationConfig
* @param {?} instance
* @return {?}
*/
function (property, propertyValidators, propValidationConfig, instance) {
/** @type {?} */
var validators = [];
/** @type {?} */
var columns = [];
if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name]) || (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name])) {
/** @type {?} */
var props_1 = [];
if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name]))
instance.conditionalValidationProps[property.name].forEach(function (t) { return props_1.push(t); });
if (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name])
this.conditionalValidationInstance.conditionalValidationProps[property.name].forEach(function (t) { return props_1.push(t); });
validators.push(conditionalChangeValidator(props_1));
}
if (this.conditionalObjectProps.length > 0 || this.builderConfigurationConditionalObjectProps.length > 0) {
/** @type {?} */
var propConditions_1 = [];
if (this.conditionalObjectProps)
propConditions_1 = this.conditionalObjectProps.filter(function (t) { return t.propName == property.name; });
if (this.builderConfigurationConditionalObjectProps)
this.builderConfigurationConditionalObjectProps.filter(function (t) { return t.propName == property.name; }).forEach(function (t) { return propConditions_1.push(t); });
propConditions_1.forEach(function (t) {
if (t.referencePropName && columns.indexOf(t.referencePropName) == -1)
columns.push(t.referencePropName);
});
if (columns.length > 0)
validators.push(conditionalChangeValidator(columns));
}
try {
for (var propertyValidators_1 = tslib_1.__values(propertyValidators), propertyValidators_1_1 = propertyValidators_1.next(); !propertyValidators_1_1.done; propertyValidators_1_1 = propertyValidators_1.next()) {
var propertyValidator = propertyValidators_1_1.value;
validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (propertyValidators_1_1 && !propertyValidators_1_1.done && (_a = propertyValidators_1.return)) _a.call(propertyValidators_1);
}
finally { if (e_1) throw e_1.error; }
}
if (propValidationConfig)
this.additionalValidation(validators, propValidationConfig);
return validators;
var e_1, _a;
};
/**
* @param {?} validations
* @param {?} propValidationConfig
* @return {?}
*/
RxFormBuilder.prototype.additionalValidation = /**
* @param {?} validations
* @param {?} propValidationConfig
* @return {?}
*/
function (validations, propValidationConfig) {
for (var col in AnnotationTypes) {
if (propValidationConfig[AnnotationTypes[col]] && col != "custom") {
validations.push(APP_VALIDATORS[AnnotationTypes[col]](propValidationConfig[AnnotationTypes[col]]));
}
else if (col == AnnotationTypes["custom"] && propValidationConfig[AnnotationTypes[col]])
validations.push(propValidationConfig[col]);
}
};
/**
* @template T
* @param {?} instanceContainer
* @param {?} object
* @return {?}
*/
RxFormBuilder.prototype.checkObjectPropAdditionalValidation = /**
* @template T
* @param {?} instanceContainer
* @param {?} object
* @return {?}
*/
function (instanceContainer, object) {
var _this = this;
/** @type {?} */
var props = instanceContainer.properties.filter(function (t) { return t.propertyType == OBJECT_PROPERTY || t.propertyType == ARRAY_PROPERTY; });
props.forEach(function (t) {
/** @type {?} */
var instance = _this.getInstanceContainer(t.entity);
if (instance.conditionalValidationProps) {
for (var key in instance.conditionalValidationProps) {
/** @type {?} */
var prop = instance.properties.filter(function (t) { return t.name == key; })[0];
if (!prop)
prop = instanceContainer.properties.filter(function (t) { return t.name == key; })[0];
if (prop) {
if (!instanceContainer.conditionalValidationProps) {
instanceContainer.conditionalValidationProps = {};
}
if (!instanceContainer.conditionalValidationProps[key]) {
instanceContainer.conditionalValidationProps[key] = [];
}
instance.conditionalValidationProps[key].forEach(function (x) {
if (t.propertyType != ARRAY_PROPERTY)
instanceContainer.conditionalValidationProps[key].push([t.name, x].join('.'));
else
instanceContainer.conditionalValidationProps[key].push([t.name, x].join('[]'));
});
}
}
}
});
};
/**
* @param {?} model
* @param {?=} entityObject
* @param {?=} formBuilderConfiguration
* @return {?}
*/
RxFormBuilder.prototype.getObject = /**
* @param {?} model
* @param {?=} entityObject
* @param {?=} formBuilderConfiguration
* @return {?}
*/
function (model, entityObject, formBuilderConfiguration) {
/** @type {?} */
var json = {};
if (typeof model == "function")
json["model"] = model;
if (entityObject && !(entityObject instanceof FormBuilderConfiguration))
json["entityObject"] = entityObject;
if (entityObject instanceof FormBuilderConfiguration && !formBuilderConfiguration)
json["formBuilderConfiguration"] = entityObject;
else if (!(entityObject instanceof FormBuilderConfiguration) && formBuilderConfiguration)
json["formBuilderConfiguration"] = formBuilderConfiguration;
if (!entityObject) {
json["entityObject"] = model;
if (typeof model == "object")
json["model"] = model.constructor;
}
else if (model && (entityObject instanceof FormBuilderConfiguration) && (typeof model == "object")) {
json["entityObject"] = model;
json["model"] = model.constructor;
}
return json;
};
/**
* @template T
* @param {?} model
* @param {?=} entityObject
* @param {?=} formBuilderConfiguration
* @return {?}
*/
RxFormBuilder.prototype.formGroup = /**
* @template T
* @param {?} model
* @param {?=} entityObject
* @param {?=} formBuilderConfiguration
* @return {?}
*/
function (model, entityObject, formBuilderConfiguration) {
var _this = this;
/** @type {?} */
var json = this.getObject(model, entityObject, formBuilderConfiguration);
model = json["model"];
entityObject = json["entityObject"];
formBuilderConfiguration = json["formBuilderConfiguration"];
if (formBuilderConfiguration)
this.extractExpressions(formBuilderConfiguration);
/** @type {?} */
var instanceContainer = this.getInstanceContainer(model);
this.checkObjectPropAdditionalValidation(instanceContainer, entityObject);
/** @type {?} */
var formGroupObject = {};
/** @type {?} */
var formChildGroup = undefined;
/** @type {?} */
var formArrayGroup = undefined;
/** @type {?} */
var additionalValidations = {};
instanceContainer.properties.forEach(function (property) {
/** @type {?} */
var isIncludeProp = true;
if (formBuilderConfiguration && formBuilderConfiguration.excludeProps && formBuilderConfiguration.excludeProps.length > 0)
isIncludeProp = formBuilderConfiguration.excludeProps.indexOf(property.name) == -1;
if (formBuilderConfiguration && formBuilderConfiguration.validations)
additionalValidations = formBuilderConfiguration.validations;
if (isIncludeProp) {
switch (property.propertyType) {
case PROPERTY:
/** @type {?} */
var propertyValidators = instanceContainer.propertyAnnotations.filter(function (t) { return t.propertyName == property.name; });
formGroupObject[property.name] = [entityObject[property.name], _this.addFormControl(property, propertyValidators, additionalValidations[property.name], instanceContainer)];
_this.isNested = false;
break;
case OBJECT_PROPERTY:
if (entityObject[property.name] && entityObject[property.name] instanceof Object) {
_this.isNested = true;
if (instanceContainer && instanceContainer.conditionalObjectProps)
_this.conditionalObjectProps = instanceContainer.conditionalObjectProps["filter"](function (t) { return t.objectPropName == property.name; });
if (_this.conditionalValidationInstance && _this.conditionalValidationInstance.conditionalObjectProps)
_this.builderConfigurationConditionalObjectProps = _this.conditionalValidationInstance.conditionalObjectProps.filter(function (t) { return t.objectPropName == property.name; });
formGroupObject[property.name] = _this.formGroup(property.entity, entityObject[property.name], formBuilderConfiguration);
_this.conditionalObjectProps = [];
_this.builderConfigurationConditionalObjectProps = [];
_this.isNested = false;
}
break;
case ARRAY_PROPERTY:
if (entityObject[property.name] && entityObject[property.name] instanceof Array) {
_this.isNested = true;
/** @type {?} */
var formArrayGroup = [];
/** @type {?} */
var index_1 = 0;
try {
for (var _a = tslib_1.__values(entityObject[property.name]), _b = _a.next(); !_b.done; _b = _a.next()) {
var subObject = _b.value;
if (instanceContainer && instanceContainer.conditionalObjectProps)
_this.conditionalObjectProps = instanceContainer.conditionalObjectProps["filter"](function (t) { return t.objectPropName == property.name && t.arrayIndex == index_1; });
if (_this.conditionalValidationInstance && _this.conditionalValidationInstance.conditionalObjectProps)
_this.builderConfigurationConditionalObjectProps = _this.conditionalValidationInstance.conditionalObjectProps.filter(function (t) { return t.objectPropName == property.name && t.arrayIndex == index_1; });
formArrayGroup.push(_this.formGroup(property.entity, subObject, formBuilderConfiguration));
index_1++;
_this.conditionalObjectProps = [];
_this.builderConfigurationConditionalObjectProps = [];
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_2) throw e_2.error; }
}
formGroupObject[property.name] = _this.formBuilder.array(formArrayGroup);
_this.isNested = false;
}
break;
}
}
var e_2, _c;
});
if (!this.isNested) {
this.conditionalValidationInstance = {};
this.builderConfigurationConditionalObjectProps = [];
}
return this.formBuilder.group(formGroupObject);
};
RxFormBuilder.decorators = [
{ type: Injectable }
];
/** @nocollapse */
RxFormBuilder.ctorParameters = function () { return [
{ type: FormBuilder }
]; };
return RxFormBuilder;
}());
export { RxFormBuilder };
if (false) {
/** @type {?} */
RxFormBuilder.prototype.nestedProp;
/** @type {?} */
RxFormBuilder.prototype.conditionalObjectProps;
/** @type {?} */
RxFormBuilder.prototype.conditionalValidationInstance;
/** @type {?} */
RxFormBuilder.prototype.builderConfigurationConditionalObjectProps;
/** @type {?} */
RxFormBuilder.prototype.isNested;
/** @type {?} */
RxFormBuilder.prototype.formBuilder;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicngtZm9ybS1idWlsZGVyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGpzYmFpbGV5L3JlYWN0aXZlLWZvcm0tdmFsaWRhdG9ycy8iLCJzb3VyY2VzIjpbInNlcnZpY2VzL3J4LWZvcm0tYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDMUMsT0FBTyxFQUFFLFdBQVcsRUFBeUIsTUFBTSxnQkFBZ0IsQ0FBQTtBQUVuRSxPQUFPLEVBQ0gscUJBQXFCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxrQkFBa0IsRUFDOUcsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQ2pILGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBRSxjQUFjLEVBQ3hGLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUNyRywyQkFBMkIsRUFBRSxvQkFBb0IsRUFBRSx3QkFBd0IsRUFBRSxpQkFBaUIsRUFDakcsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU1RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBRXBFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwwREFBMEQsQ0FBQztBQUN0RyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sY0FBYyxDQUFBOztBQUduQyxJQUFNLGNBQWMsR0FBZ0M7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QUcsS0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7NEJBQ3hFLEtBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO3lCQUN6Qjt3QkFDRCxLQUFLLENBQUM7aUJBQ2I7YUFDSjs7U0FFSixDQUFDLENBQUE7UUFDRixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLElBQUksQ0FBQyw2QkFBNkIsR0FBRyxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLDBDQUEwQyxHQUFHLEVBQUUsQ0FBQztTQUN4RDtRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztLQUNsRDs7Z0JBck1KLFVBQVU7Ozs7Z0JBcERGLFdBQVc7O3dCQURwQjs7U0FzRGEsYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiXHJcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIlxyXG5pbXBvcnQgeyBUeXBlLCBEZWNvcmF0b3JOYW1lIH0gZnJvbSBcIi4uL3V0aWxcIlxyXG5pbXBvcnQge1xyXG4gICAgYWxwaGFOdW1lcmljVmFsaWRhdG9yLCBhbHBoYVZhbGlkYXRvciwgY29tcGFyZVZhbGlkYXRvciwgZW1haWxWYWxpZGF0b3IsIGhleENvbG9yVmFsaWRhdG9yLCBsb3dlcmNhc2VWYWxpZGF0b3IsXHJcbiAgICBtYXhEYXRlVmFsaWRhdG9yLCBtYXhOdW1iZXJWYWxpZGF0b3IsIG1pbkRhdGVWYWxpZGF0b3IsIG1pbk51bWJlclZhbGlkYXRvciwgY29udGFpbnNWYWxpZGF0b3IsIHVwcGVyY2FzZVZhbGlkYXRvcixcclxuICAgIHJhbmdlVmFsaWRhdG9yLCBwYXR0ZXJuVmFsaWRhdG9yLCByZXF1aXJlZFZhbGlkYXRvciwgY3JlZGl0Q2FyZFZhbGlkYXRvciwgZGlnaXRWYWxpZGF0b3IsXHJcbiAgICBtYXhMZW5ndGhWYWxpZGF0b3IsIG1pbkxlbmd0aFZhbGlkYXRvciwgcGFzc3dvcmRWYWxpZGF0b3IsIHRpbWVWYWxpZGF0b3IsIHVybFZhbGlkYXRvciwganNvblZhbGlkYXRvcixcclxuICAgIGdyZWF0ZXJUaGFuRXF1YWxUb1ZhbGlkYXRvciwgZ3JlYXRlclRoYW5WYWxpZGF0b3IsIGxlc3NUaGFuRXF1YWxUb1ZhbGlkYXRvciwgbGVzc1RoYW5WYWxpZGF0b3JcclxufSBmcm9tICcuLi9yZWFjdGl2ZS1mb3JtLXZhbGlkYXRvcnMnO1xyXG5cclxuaW1wb3J0IHsgZGVmYXVsdENvbnRhaW5lciB9IGZyb20gJy4uL2NvcmUvZGVmYXVsdENvbnRhaW5lcic7XHJcbmltcG9ydCB7IERlY29yYXRvckNvbmZpZ3VyYXRpb24sIEluc3RhbmNlQ29udGFpbmVyLCBQcm9wZXJ0eUluZm8gfSBmcm9tICcuLi9jb3JlL3ZhbGlkYXRvci5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gfSBmcm9tIFwiLi4vbW9kZWxzXCJcclxuaW1wb3J0IHsgQVJSQVlfUFJPUEVSVFksIE9CSkVDVF9QUk9QRVJUWSwgUFJPUEVSVFkgfSBmcm9tIFwiLi4vY29uc3RcIlxyXG5pbXBvcnQgeyBQcm9wVmFsaWRhdGlvbkNvbmZpZyB9IGZyb20gXCIuLi9tb2RlbHMvcHJvcC12YWxpZGF0aW9uLWNvbmZpZ1wiO1xyXG5pbXBvcnQgeyBBbm5vdGF0aW9uVHlwZXMgfSBmcm9tIFwiLi4vY29yZS92YWxpZGF0b3Iuc3RhdGljXCI7XHJcbmltcG9ydCB7IGNvbmRpdGlvbmFsQ2hhbmdlVmFsaWRhdG9yIH0gZnJvbSBcIi4uL3JlYWN0aXZlLWZvcm0tdmFsaWRhdG9ycy9jb25kaXRpb25hbC1jaGFuZ2UudmFsaWRhdG9yXCI7XHJcbmltcG9ydCB7IExpbnEgfSBmcm9tICcuLi91dGlsL2xpbnEnXHJcblxyXG5cclxuY29uc3QgQVBQX1ZBTElEQVRPUlM6IHsgW2tleTogc3RyaW5nXTogRnVuY3Rpb24gfSA9IHtcclxuICAgIFwiYWxwaGFOdW1lcmljXCI6IGFscGhhTnVtZXJpY1ZhbGlkYXRvcixcclxuICAgIFwiYWxwaGFcIjogYWxwaGFWYWxpZGF0b3IsXHJcbiAgICBcImNvbXBhcmVcIjogY29tcGFyZVZhbGlkYXRvcixcclxuICAgIFwiZW1haWxcIjogZW1haWxWYWxpZGF0b3IsXHJcbiAgICBcImhleENvbG9yXCI6IGhleENvbG9yVmFsaWRhdG9yLFxyXG4gICAgXCJsb3dlckNhc2VcIjogbG93ZXJjYXNlVmFsaWRhdG9yLFxyXG4gICAgXCJtYXhEYXRlXCI6IG1heERhdGVWYWxpZGF0b3IsXHJcbiAgICBcIm1heE51bWJlclwiOiBtYXhOdW1iZXJWYWxpZGF0b3IsXHJcbiAgICBcIm1pbkRhdGVcIjogbWluRGF0ZVZhbGlkYXRvcixcclxuICAgIFwibWluTnVtYmVyXCI6IG1pbk51bWJlclZhbGlkYXRvcixcclxuICAgIFwiY29udGFpbnNcIjogY29udGFpbnNWYWxpZGF0b3IsXHJcbiAgICBcInVwcGVyQ2FzZVwiOiB1cHBlcmNhc2VWYWxpZGF0b3IsXHJcbiAgICBcIm1heExlbmd0aFwiOiBtYXhMZW5ndGhWYWxpZGF0b3IsXHJcbiAgICBcIm1pbkxlbmd0aFwiOiBtaW5MZW5ndGhWYWxpZGF0b3IsXHJcbiAgICBcInBhc3N3b3JkXCI6IHBhc3N3b3JkVmFsaWRhdG9yLFxyXG4gICAgXCJyYW5nZVwiOiByYW5nZVZhbGlkYXRvcixcclxuICAgIFwicmVxdWlyZWRcIjogcmVxdWlyZWRWYWxpZGF0b3IsXHJcbiAgICBcImNyZWRpdENhcmRcIjogY3JlZGl0Q2FyZFZhbGlkYXRvcixcclxuICAgIFwiZGlnaXRcIjogZGlnaXRWYWxpZGF0b3IsXHJcbiAgICBcInBhdHRlcm5cIjogcGF0dGVyblZhbGlkYXRvcixcclxuICAgIFwidGltZVwiOiB0aW1lVmFsaWRhdG9yLFxyXG4gICAgXCJ1cmxcIjogdXJsVmFsaWRhdG9yLFxyXG4gICAgXCJqc29uXCI6IGpzb25WYWxpZGF0b3IsXHJcbiAgICBcImdyZWF0ZXJUaGFuXCI6IGdyZWF0ZXJUaGFuVmFsaWRhdG9yLFxyXG4gICAgXCJncmVhdGVyVGhhbkVxdWFsVG9cIjogZ3JlYXRlclRoYW5FcXVhbFRvVmFsaWRhdG9yLFxyXG4gICAgXCJsZXNzVGhhblwiOiBsZXNzVGhhblZhbGlkYXRvcixcclxuICAgIFwibGVzc1RoYW5FcXVhbFRvXCI6IGxlc3NUaGFuRXF1YWxUb1ZhbGlkYXRvclxyXG59XHJcblxyXG5cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFJ4Rm9ybUJ1aWxkZXIge1xyXG4gICAgcHJpdmF0ZSBuZXN0ZWRQcm9wOiBzdHJpbmc7XHJcbiAgICBwcml2YXRlIGNvbmRpdGlvbmFsT2JqZWN0UHJvcHM6IGFueVtdID0gW107XHJcbiAgICBwcml2YXRlIGNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlOiBhbnkgPSB7fTtcclxuICAgIHByaXZhdGUgYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzOiBhbnlbXSA9IFtdO1xyXG4gICAgcHJpdmF0ZSBpc05lc3RlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXIpIHsgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0SW5zdGFuY2VDb250YWluZXIoaW5zdGFuY2VGdW5jOiBhbnkpOiBJbnN0YW5jZUNvbnRhaW5lciB7XHJcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRDb250YWluZXIuZ2V0KGluc3RhbmNlRnVuYyk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXRWYWx1ZShmb3JtR3JvdXA6IEZvcm1Hcm91cCwgb2JqZWN0OiBhbnkpOiB2b2lkIHtcclxuICAgICAgICBmb3IgKHZhciBjb2wgaW4gb2JqZWN0KSB7XHJcbiAgICAgICAgICAgIHZhciBjb250cm9sID0gZm9ybUdyb3VwLmdldChbY29sXSk7XHJcbiAgICAgICAgICAgIGNvbnRyb2wuc2V0VmFsdWUob2JqZWN0W2NvbF0pO1xyXG4gICAgICAgICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBleHRyYWN0RXhwcmVzc2lvbnMoZm9tckJ1aWxkZXJDb25maWd1cmF0aW9uOiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0ge1xyXG4gICAgICAgIGlmIChmb21yQnVpbGRlckNvbmZpZ3VyYXRpb24gJiYgZm9tckJ1aWxkZXJDb25maWd1cmF0aW9uLnZhbGlkYXRpb25zKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIHByb3BlcnR5IGluIGZvbXJCdWlsZGVyQ29uZmlndXJhdGlvbi52YWxpZGF0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgZGVjb3JhdG9yIGluIGZvbXJCdWlsZGVyQ29uZmlndXJhdGlvbi52YWxpZGF0aW9uc1twcm9wZXJ0eV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZm9tckJ1aWxkZXJDb25maWd1cmF0aW9uLnZhbGlkYXRpb25zW3Byb3BlcnR5XVtkZWNvcmF0b3JdLmNvbmRpdGlvbmFsRXhwcmVzc2lvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29sdW1ucyA9IExpbnEuZXhwcmVzc2lvbkNvbHVtbnMoZm9tckJ1aWxkZXJDb25maWd1cmF0aW9uLnZhbGlkYXRpb25zW3Byb3BlcnR5XVtkZWNvcmF0b3JdLmNvbmRpdGlvbmFsRXhwcmVzc2lvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRDb250YWluZXIuYWRkQ2hhbmdlVmFsaWRhdGlvbih0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlLCBwcm9wZXJ0eSwgY29sdW1ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYWRkRm9ybUNvbnRyb2wocHJvcGVydHk6IFByb3BlcnR5SW5mbywgcHJvcGVydHlWYWxpZGF0b3JzOiBEZWNvcmF0b3JDb25maWd1cmF0aW9uW10sIHByb3BWYWxpZGF0aW9uQ29uZmlnOiBQcm9wVmFsaWRhdGlvbkNvbmZpZywgaW5zdGFuY2U6IEluc3RhbmNlQ29udGFpbmVyKSB7XHJcbiAgICAgICAgbGV0IHZhbGlkYXRvcnMgPSBbXTtcclxuICAgICAgICBsZXQgY29sdW1ucyA9IFtdO1xyXG4gICAgICAgIGlmICgoaW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHMgJiYgaW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHNbcHJvcGVydHkubmFtZV0pIHx8ICh0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzICYmIHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHNbcHJvcGVydHkubmFtZV0pKSB7XHJcbiAgICAgICAgICAgIGxldCBwcm9wcyA9IFtdO1xyXG4gICAgICAgICAgICBpZiAoKGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzICYmIGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW3Byb3BlcnR5Lm5hbWVdKSlcclxuICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW3Byb3BlcnR5Lm5hbWVdLmZvckVhY2godCA9PiBwcm9wcy5wdXNoKHQpKVxyXG4gICAgICAgICAgICBpZiAodGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcyAmJiB0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW3Byb3BlcnR5Lm5hbWVdKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1twcm9wZXJ0eS5uYW1lXS5mb3JFYWNoKHQgPT4gcHJvcHMucHVzaCh0KSk7XHJcbiAgICAgICAgICAgIHZhbGlkYXRvcnMucHVzaChjb25kaXRpb25hbENoYW5nZVZhbGlkYXRvcihwcm9wcykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25kaXRpb25hbE9iamVjdFByb3BzLmxlbmd0aCA+IDAgfHwgdGhpcy5idWlsZGVyQ29uZmlndXJhdGlvbkNvbmRpdGlvbmFsT2JqZWN0UHJvcHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgcHJvcENvbmRpdGlvbnMgPSBbXTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxPYmplY3RQcm9wcylcclxuICAgICAgICAgICAgICAgIHByb3BDb25kaXRpb25zID0gdGhpcy5jb25kaXRpb25hbE9iamVjdFByb3BzLmZpbHRlcih0ID0+IHQucHJvcE5hbWUgPT0gcHJvcGVydHkubmFtZSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wcylcclxuICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzLmZpbHRlcih0ID0+IHQucHJvcE5hbWUgPT0gcHJvcGVydHkubmFtZSkuZm9yRWFjaCh0ID0+IHByb3BDb25kaXRpb25zLnB1c2godCkpO1xyXG4gICAgICAgICAgICBwcm9wQ29uZGl0aW9ucy5mb3JFYWNoKHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHQucmVmZXJlbmNlUHJvcE5hbWUgJiYgY29sdW1ucy5pbmRleE9mKHQucmVmZXJlbmNlUHJvcE5hbWUpID09IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbnMucHVzaCh0LnJlZmVyZW5jZVByb3BOYW1lKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgaWYgKGNvbHVtbnMubGVuZ3RoID4gMClcclxuICAgICAgICAgICAgICAgIHZhbGlkYXRvcnMucHVzaChjb25kaXRpb25hbENoYW5nZVZhbGlkYXRvcihjb2x1bW5zKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAobGV0IHByb3BlcnR5VmFsaWRhdG9yIG9mIHByb3BlcnR5VmFsaWRhdG9ycykge1xyXG4gICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goQVBQX1ZBTElEQVRPUlNbcHJvcGVydHlWYWxpZGF0b3IuYW5ub3RhdGlvblR5cGVdKHByb3BlcnR5VmFsaWRhdG9yLmNvbmZpZywgKSlcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHByb3BWYWxpZGF0aW9uQ29uZmlnKVxyXG4gICAgICAgICAgICB0aGlzLmFkZGl0aW9uYWxWYWxpZGF0aW9uKHZhbGlkYXRvcnMsIHByb3BWYWxpZGF0aW9uQ29uZmlnKTtcclxuICAgICAgICByZXR1cm4gdmFsaWRhdG9ycztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFkZGl0aW9uYWxWYWxpZGF0aW9uKHZhbGlkYXRpb25zOiBhbnlbXSwgcHJvcFZhbGlkYXRpb25Db25maWc6IFByb3BWYWxpZGF0aW9uQ29uZmlnKSB7XHJcbiAgICAgICAgZm9yICh2YXIgY29sIGluIEFubm90YXRpb25UeXBlcykge1xyXG4gICAgICAgICAgICBpZiAocHJvcFZhbGlkYXRpb25Db25maWdbQW5ub3RhdGlvblR5cGVzW2NvbF1dICYmIGNvbCAhPSBcImN1c3RvbVwiKSB7XHJcbiAgICAgICAgICAgICAgICB2YWxpZGF0aW9ucy5wdXNoKEFQUF9WQUxJREFUT1JTW0Fubm90YXRpb25UeXBlc1tjb2xdXShwcm9wVmFsaWRhdGlvbkNvbmZpZ1tBbm5vdGF0aW9uVHlwZXNbY29sXV0pKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChjb2wgPT0gQW5ub3RhdGlvblR5cGVzLmN1c3RvbSAmJiBwcm9wVmFsaWRhdGlvbkNvbmZpZ1tBbm5vdGF0aW9uVHlwZXNbY29sXV0pXHJcbiAgICAgICAgICAgICAgICB2YWxpZGF0aW9ucy5wdXNoKHByb3BWYWxpZGF0aW9uQ29uZmlnW2NvbF0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGNoZWNrT2JqZWN0UHJvcEFkZGl0aW9uYWxWYWxpZGF0aW9uPFQ+KGluc3RhbmNlQ29udGFpbmVyOiBJbnN0YW5jZUNvbnRhaW5lciwgb2JqZWN0OiBUKSB7XHJcbiAgICAgICAgdmFyIHByb3BzID0gaW5zdGFuY2VDb250YWluZXIucHJvcGVydGllcy5maWx0ZXIodCA9PiB0LnByb3BlcnR5VHlwZSA9PSBPQkpFQ1RfUFJPUEVSVFkgfHwgdC5wcm9wZXJ0eVR5cGUgPT0gQVJSQVlfUFJPUEVSVFkpXHJcbiAgICAgICAgcHJvcHMuZm9yRWFjaCh0ID0+IHtcclxuICAgICAgICAgICAgbGV0IGluc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZUNvbnRhaW5lcih0LmVudGl0eSk7XHJcbiAgICAgICAgICAgIGlmIChpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcykge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3AgPSBpbnN0YW5jZS5wcm9wZXJ0aWVzLmZpbHRlcih0ID0+IHQubmFtZSA9PSBrZXkpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcHJvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcCA9IGluc3RhbmNlQ29udGFpbmVyLnByb3BlcnRpZXMuZmlsdGVyKHQgPT4gdC5uYW1lID09IGtleSlbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3ApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VDb250YWluZXIuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHMgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW2tleV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW2tleV0gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1trZXldLmZvckVhY2goeCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodC5wcm9wZXJ0eVR5cGUgIT0gQVJSQVlfUFJPUEVSVFkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VDb250YWluZXIuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHNba2V5XS5wdXNoKFt0Lm5hbWUsIHhdLmpvaW4oJy4nKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1trZXldLnB1c2goW3QubmFtZSwgeF0uam9pbignW10nKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICBnZXRPYmplY3QobW9kZWw6IGFueSB8IHsgW2tleTogc3RyaW5nXTogYW55IH0sIGVudGl0eU9iamVjdD86IHsgW2tleTogc3RyaW5nXTogYW55IH0gfCBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24sIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbj86IEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbik6IHtba2V5OnN0cmluZ106YW55fSB7XHJcbiAgICAgICAgbGV0IGpzb246IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fTtcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiBtb2RlbCA9PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgICAgIGpzb24ubW9kZWwgPSBtb2RlbDtcclxuXHJcbiAgICAgICAgaWYgKGVudGl0eU9iamVjdCAmJiAhKGVudGl0eU9iamVjdCBpbnN0YW5jZW9mIEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbikpXHJcbiAgICAgICAgICAgIGpzb24uZW50aXR5T2JqZWN0ID0gZW50aXR5T2JqZWN0O1xyXG5cclxuICAgICAgICBpZiAoZW50aXR5T2JqZWN0IGluc3RhbmNlb2YgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uICYmICFmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pXHJcbiAgICAgICAgICAgIGpzb24uZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uID0gZW50aXR5T2JqZWN0O1xyXG4gICAgICAgIGVsc2UgaWYgKCEoZW50aXR5T2JqZWN0IGluc3RhbmNlb2YgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSAmJiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pXHJcbiAgICAgICAgICAgIGpzb24uZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uID0gZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICghZW50aXR5T2JqZWN0KSB7XHJcbiAgICAgICAgICAgIGpzb24uZW50aXR5T2JqZWN0ID0gbW9kZWw7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbW9kZWwgPT0gXCJvYmplY3RcIilcclxuICAgICAgICAgICAgICAgIGpzb24ubW9kZWwgPSBtb2RlbC5jb25zdHJ1Y3RvcjtcclxuICAgICAgICB9IGVsc2UgaWYgKG1vZGVsICYmIChlbnRpdHlPYmplY3QgaW5zdGFuY2VvZiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pICYmICh0eXBlb2YgbW9kZWwgPT0gXCJvYmplY3RcIikpIHtcclxuICAgICAgICAgICAganNvbltcImVudGl0eU9iamVjdFwiXSA9IG1vZGVsO1xyXG4gICAgICAgICAgICBqc29uW1wibW9kZWxcIl0gPSBtb2RlbC5jb25zdHJ1Y3RvcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGpzb247XHJcbiAgICB9XHJcblxyXG4gICAgZm9ybUdyb3VwPFQ+KG1vZGVsOiBUeXBlPFQ+IHwgeyBba2V5OiBzdHJpbmddOiBhbnkgfSwgZW50aXR5T2JqZWN0PzogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB8IEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiwgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uPzogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKTogRm9ybUdyb3VwIHtcclxuICAgICAgICBsZXQganNvbiA9IHRoaXMuZ2V0T2JqZWN0KG1vZGVsLCBlbnRpdHlPYmplY3QsIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbik7XHJcbiAgICAgICAgbW9kZWwgPSBqc29uLm1vZGVsO1xyXG4gICAgICAgIGVudGl0eU9iamVjdCA9IGpzb24uZW50aXR5T2JqZWN0O1xyXG4gICAgICAgIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiA9IGpzb24uZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uO1xyXG4gICAgICAgIGlmIChmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pXHJcbiAgICAgICAgICAgIHRoaXMuZXh0cmFjdEV4cHJlc3Npb25zKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbik7XHJcbiAgICAgICAgbGV0IGluc3RhbmNlQ29udGFpbmVyOiBJbnN0YW5jZUNvbnRhaW5lciA9IHRoaXMuZ2V0SW5zdGFuY2VDb250YWluZXIobW9kZWwpO1xyXG4gICAgICAgIHRoaXMuY2hlY2tPYmplY3RQcm9wQWRkaXRpb25hbFZhbGlkYXRpb24oaW5zdGFuY2VDb250YWluZXIsIGVudGl0eU9iamVjdCk7XHJcbiAgICAgICAgbGV0IGZvcm1Hcm91cE9iamVjdCA9IHt9O1xyXG4gICAgICAgIGxldCBmb3JtQ2hpbGRHcm91cCA9IHVuZGVmaW5lZDtcclxuICAgICAgICBsZXQgZm9ybUFycmF5R3JvdXAgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgdmFyIGFkZGl0aW9uYWxWYWxpZGF0aW9uczogeyBba2V5OiBzdHJpbmddOiBQcm9wVmFsaWRhdGlvbkNvbmZpZyB9ID0ge307XHJcbiAgICAgICAgaW5zdGFuY2VDb250YWluZXIucHJvcGVydGllcy5mb3JFYWNoKHByb3BlcnR5ID0+IHtcclxuICAgICAgICAgICAgbGV0IGlzSW5jbHVkZVByb3AgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZiAoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uICYmIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5leGNsdWRlUHJvcHMgJiYgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLmV4Y2x1ZGVQcm9wcy5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICAgICAgaXNJbmNsdWRlUHJvcCA9IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5leGNsdWRlUHJvcHMuaW5kZXhPZihwcm9wZXJ0eS5uYW1lKSA9PSAtMVxyXG4gICAgICAgICAgICBpZiAoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uICYmIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi52YWxpZGF0aW9ucylcclxuICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxWYWxpZGF0aW9ucyA9IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi52YWxpZGF0aW9ucztcclxuICAgICAgICAgICAgaWYgKGlzSW5jbHVkZVByb3ApIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAocHJvcGVydHkucHJvcGVydHlUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBQUk9QRVJUWTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BlcnR5VmFsaWRhdG9ycyA9IGluc3RhbmNlQ29udGFpbmVyLnByb3BlcnR5QW5ub3RhdGlvbnMuZmlsdGVyKHQgPT4gdC5wcm9wZXJ0eU5hbWUgPT0gcHJvcGVydHkubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Hcm91cE9iamVjdFtwcm9wZXJ0eS5uYW1lXSA9IFtlbnRpdHlPYmplY3RbcHJvcGVydHkubmFtZV0sIHRoaXMuYWRkRm9ybUNvbnRyb2wocHJvcGVydHksIHByb3BlcnR5VmFsaWRhdG9ycywgYWRkaXRpb25hbFZhbGlkYXRpb25zW3Byb3BlcnR5Lm5hbWVdLCBpbnN0YW5jZUNvbnRhaW5lcildO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgT0JKRUNUX1BST1BFUlRZOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW50aXR5T2JqZWN0W3Byb3BlcnR5Lm5hbWVdICYmIGVudGl0eU9iamVjdFtwcm9wZXJ0eS5uYW1lXSBpbnN0YW5jZW9mIE9iamVjdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc05lc3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB