UNPKG

@jsbailey/reactive-form-validators

Version:

[![npm version](https://badge.fury.io/js/%40rxweb%2Freactive-form-validators.svg)](https://badge.fury.io/js/%40rxweb%2Freactive-form-validators) [![Gitter](https://badges.gitter.im/rx-web/Lobby.svg)](https://gitter.im/rxweb-project/rxweb?utm_source=badge

388 lines (387 loc) 53.8 kB
/** * @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