ngx-bean-validation
Version:
> Idea was taken from [Bean Validation](https://beanvalidation.org/)
261 lines (243 loc) • 26.9 kB
JavaScript
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
import 'proxy-polyfil';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const setName = (name) => {
return `__${name}__`;
};
/** @type {?} */
const getName = (name) => {
return name.replace(/^__(.+?)__$/, (substring, arg) => arg);
};
/** @type {?} */
const setSyncValidator = (target, key, validator) => {
/** @type {?} */
let metadata = /** @type {?} */ (Reflect.get(target, setName(key)));
checkAnnotationConflicts(metadata, 'Validator');
metadata = metadata || { annotated: true };
metadata.syncValidators = metadata.syncValidators || [];
metadata.syncValidators.push(validator);
Reflect.set(target, setName(key), metadata);
};
/** @type {?} */
const checkAnnotationConflicts = (metadata, annotation) => {
if (metadata && metadata.nested) {
throw new Error(`${annotation} has conflicts with Nested`);
}
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @template T
*/
class BeanFormGroup extends FormGroup {
/**
* @param {?} annotatedInstance
*/
constructor(annotatedInstance) {
super(BeanFormGroup.generateAbstractControls(annotatedInstance));
}
/**
* @template T
* @param {?} annotatedInstance
* @return {?}
*/
static generateAbstractControls(annotatedInstance) {
/** @type {?} */
const controls = new Proxy(annotatedInstance, {
get: (target, name) => {
return name in target ? Reflect.get(target, name) : undefined;
}
});
/** @type {?} */
const newControls = {};
for (const prop in controls) {
if (controls[prop] instanceof Object && controls[prop].annotated) {
/** @type {?} */
const metadata = controls[prop];
/** @type {?} */
const controlName = getName(prop);
if (metadata.nested) {
newControls[controlName] = new FormGroup(this.generateAbstractControls(controls[controlName]));
continue;
}
/** @type {?} */
const syncValidators = exposeSyncValidators(metadata);
/** @type {?} */
const asyncValidators = exposeAsyncValidators(metadata);
if (metadata.nestedArray) {
/** @type {?} */
const arrayForm = controls[controlName].map((control) => new FormGroup((this.generateAbstractControls(control))));
newControls[controlName] = new FormArray(arrayForm, syncValidators, asyncValidators);
continue;
}
newControls[controlName] = new FormControl({
value: controls[controlName],
disabled: metadata.disabled
}, syncValidators, asyncValidators);
}
}
return newControls;
}
}
/**
* @param {?} metadata
* @return {?}
*/
function exposeSyncValidators(metadata) {
if (metadata.syncValidators) {
return Validators.compose(metadata.syncValidators);
}
}
/**
* @param {?} metadata
* @return {?}
*/
function exposeAsyncValidators(metadata) {
if (metadata.asyncValidators) {
return Validators.composeAsync(metadata.asyncValidators);
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const Disabled = () => (target, key) => {
/** @type {?} */
let metadata = /** @type {?} */ (Reflect.get(target, setName(key)));
checkAnnotationConflicts(metadata, 'Disabled');
metadata = metadata || { annotated: true };
metadata.disabled = true;
Reflect.set(target, setName(key), metadata);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** *
* If you don`t need to validate field, just use this annotation, otherwise you will not get formControl in the ControlConfig
@type {?} */
const EmptyControl = () => (target, key) => {
/** @type {?} */
let metadata = /** @type {?} */ (Reflect.get(target, setName(key)));
checkAnnotationConflicts(metadata, 'EmptyControl');
metadata = metadata || { annotated: true };
Reflect.set(target, setName(key), metadata);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const Max = (max) => (target, key) => {
setSyncValidator(target, key, Validators.max(max));
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const Email = () => (target, key) => {
setSyncValidator(target, key, Validators.email);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const MaxLength = (maxLength) => (target, key) => {
setSyncValidator(target, key, Validators.maxLength(maxLength));
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const Min = (min) => (target, key) => {
setSyncValidator(target, key, Validators.min(min));
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const MinLength = (minLength) => (target, key) => {
setSyncValidator(target, key, Validators.minLength(minLength));
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** *
* Define nested groupControl
*
* Important notice:
* should be only one nested annotation per class property
*
@type {?} */
const Nested = () => (target, key) => {
/** @type {?} */
let metadata = /** @type {?} */ (Reflect.get(target, setName(key)));
if (metadata) {
throw new Error('Annotation Nested has conflicts, please remove other annotations');
}
metadata = { annotated: true, nested: true };
Reflect.set(target, setName(key), metadata);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** *
* Define nested ArrayControl
*
@type {?} */
const NestedArray = () => (target, key) => {
/** @type {?} */
let metadata = /** @type {?} */ (Reflect.get(target, setName(key)));
if (metadata && metadata.nested) {
throw new Error('Annotation NestedArray has conflict with Nested Annotation, please remove one of them');
}
metadata = { annotated: true, nestedArray: true };
Reflect.set(target, setName(key), metadata);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const Required = () => (target, key) => {
setSyncValidator(target, key, Validators.required);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const RequiredTrue = () => (target, key) => {
setSyncValidator(target, key, Validators.requiredTrue);
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const Pattern = (pattern) => (target, key) => {
setSyncValidator(target, key, Validators.pattern(pattern));
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { setSyncValidator, BeanFormGroup, Disabled, EmptyControl, Max, Email, MaxLength, Min, MinLength, Nested, NestedArray, Required, RequiredTrue, Pattern };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWJlYW4tdmFsaWRhdGlvbi5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmd4LWJlYW4tdmFsaWRhdGlvbi9saWIvYW5ub3RhdGlvbnMvY29tbW9uLnRzIiwibmc6Ly9uZ3gtYmVhbi12YWxpZGF0aW9uL2xpYi9iZWFuLWZvcm0tZ3JvdXAudHMiLCJuZzovL25neC1iZWFuLXZhbGlkYXRpb24vbGliL2Fubm90YXRpb25zL2Rpc2FibGVkLnRzIiwibmc6Ly9uZ3gtYmVhbi12YWxpZGF0aW9uL2xpYi9hbm5vdGF0aW9ucy9lbXB0eS1jb250cm9sLnRzIiwibmc6Ly9uZ3gtYmVhbi12YWxpZGF0aW9uL2xpYi9hbm5vdGF0aW9ucy9tYXgudHMiLCJuZzovL25neC1iZWFuLXZhbGlkYXRpb24vbGliL2Fubm90YXRpb25zL2VtYWlsLnRzIiwibmc6Ly9uZ3gtYmVhbi12YWxpZGF0aW9uL2xpYi9hbm5vdGF0aW9ucy9tYXgtbGVuZ3RoLnRzIiwibmc6Ly9uZ3gtYmVhbi12YWxpZGF0aW9uL2xpYi9hbm5vdGF0aW9ucy9taW4udHMiLCJuZzovL25neC1iZWFuLXZhbGlkYXRpb24vbGliL2Fubm90YXRpb25zL21pbi1sZW5ndGgudHMiLCJuZzovL25neC1iZWFuLXZhbGlkYXRpb24vbGliL2Fubm90YXRpb25zL25lc3RlZC50cyIsIm5nOi8vbmd4LWJlYW4tdmFsaWRhdGlvbi9saWIvYW5ub3RhdGlvbnMvbmVzdGVkLWFycmF5LnRzIiwibmc6Ly9uZ3gtYmVhbi12YWxpZGF0aW9uL2xpYi9hbm5vdGF0aW9ucy9yZXF1aXJlZC50cyIsIm5nOi8vbmd4LWJlYW4tdmFsaWRhdGlvbi9saWIvYW5ub3RhdGlvbnMvcmVxdWlyZWQtdHJ1ZS50cyIsIm5nOi8vbmd4LWJlYW4tdmFsaWRhdGlvbi9saWIvYW5ub3RhdGlvbnMvcGF0dGVybi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FzeW5jVmFsaWRhdG9yRm4sIFZhbGlkYXRvckZufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmV4cG9ydCB0eXBlIEFubm90YXRpb25GdW5jdGlvbiA9ICh0YXJnZXQ6IG9iamVjdCwga2V5OiBzdHJpbmcpID0+IHZvaWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9ybU1ldGFkYXRhIHtcbiAgYW5ub3RhdGVkOiBib29sZWFuO1xuICBkaXNhYmxlZD86IGJvb2xlYW47XG4gIHN5bmNWYWxpZGF0b3JzPzogVmFsaWRhdG9yRm5bXTtcbiAgYXN5bmNWYWxpZGF0b3JzPzogQXN5bmNWYWxpZGF0b3JGbltdO1xuICBuZXN0ZWRBcnJheT86IGJvb2xlYW47XG4gIG5lc3RlZD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBzZXROYW1lID0gKG5hbWU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIHJldHVybiBgX18ke25hbWV9X19gO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldE5hbWUgPSAobmFtZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIG5hbWUucmVwbGFjZSgvXl9fKC4rPylfXyQvLCAoc3Vic3RyaW5nLCBhcmcpID0+IGFyZyk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2V0U3luY1ZhbGlkYXRvciA9ICh0YXJnZXQ6IGFueSwga2V5OiBzdHJpbmcsIHZhbGlkYXRvcjogVmFsaWRhdG9yRm4pOiB2b2lkID0+IHtcbiAgbGV0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBzZXROYW1lKGtleSkpIGFzIEZvcm1NZXRhZGF0YTtcblxuICBjaGVja0Fubm90YXRpb25Db25mbGljdHMobWV0YWRhdGEsICdWYWxpZGF0b3InKTtcblxuICBtZXRhZGF0YSA9IG1ldGFkYXRhIHx8IHthbm5vdGF0ZWQ6IHRydWV9O1xuICBtZXRhZGF0YS5zeW5jVmFsaWRhdG9ycyA9IG1ldGFkYXRhLnN5bmNWYWxpZGF0b3JzIHx8IFtdO1xuICBtZXRhZGF0YS5zeW5jVmFsaWRhdG9ycy5wdXNoKHZhbGlkYXRvcik7XG5cbiAgUmVmbGVjdC5zZXQodGFyZ2V0LCBzZXROYW1lKGtleSksIG1ldGFkYXRhKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzZXRBc3luY1ZhbGlkYXRvciA9ICh0YXJnZXQ6IGFueSwga2V5OiBzdHJpbmcsIHZhbGlkYXRvcjogQXN5bmNWYWxpZGF0b3JGbik6IHZvaWQgPT4ge1xuICBsZXQgbWV0YWRhdGEgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHNldE5hbWUoa2V5KSkgYXMgRm9ybU1ldGFkYXRhO1xuXG4gIGNoZWNrQW5ub3RhdGlvbkNvbmZsaWN0cyhtZXRhZGF0YSwgJ1ZhbGlkYXRvcicpO1xuXG4gIG1ldGFkYXRhID0gbWV0YWRhdGEgfHwge2Fubm90YXRlZDogdHJ1ZX07XG4gIG1ldGFkYXRhLmFzeW5jVmFsaWRhdG9ycyA9IG1ldGFkYXRhLmFzeW5jVmFsaWRhdG9ycyB8fCBbXTtcbiAgbWV0YWRhdGEuYXN5bmNWYWxpZGF0b3JzLnB1c2godmFsaWRhdG9yKTtcblxuICBSZWZsZWN0LnNldCh0YXJnZXQsIHNldE5hbWUoa2V5KSwgbWV0YWRhdGEpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNoZWNrQW5ub3RhdGlvbkNvbmZsaWN0cyA9IChtZXRhZGF0YTogRm9ybU1ldGFkYXRhLCBhbm5vdGF0aW9uOiBzdHJpbmcpID0+IHtcbiAgaWYgKG1ldGFkYXRhICYmIG1ldGFkYXRhLm5lc3RlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHthbm5vdGF0aW9ufSBoYXMgY29uZmxpY3RzIHdpdGggTmVzdGVkYCk7XG4gIH1cbn07XG4iLCJpbXBvcnQge0Fic3RyYWN0Q29udHJvbCwgQXN5bmNWYWxpZGF0b3JGbiwgRm9ybUFycmF5LCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBWYWxpZGF0b3JGbiwgVmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtnZXROYW1lfSBmcm9tICcuL2Fubm90YXRpb25zL2NvbW1vbic7XG5pbXBvcnQgJ3Byb3h5LXBvbHlmaWwnO1xuXG5leHBvcnQgY2xhc3MgQmVhbkZvcm1Hcm91cDxUPiBleHRlbmRzIEZvcm1Hcm91cCB7XG4gIGNvbnN0cnVjdG9yKGFubm90YXRlZEluc3RhbmNlOiBUKSB7XG4gICAgc3VwZXIoQmVhbkZvcm1Hcm91cC5nZW5lcmF0ZUFic3RyYWN0Q29udHJvbHM8VD4oYW5ub3RhdGVkSW5zdGFuY2UpKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgZ2VuZXJhdGVBYnN0cmFjdENvbnRyb2xzPFQ+KGFubm90YXRlZEluc3RhbmNlOiBUKTogQ29udHJvbENvbmZpZyB7XG4gICAgY29uc3QgY29udHJvbHMgPSBuZXcgUHJveHkoYW5ub3RhdGVkSW5zdGFuY2UsIHtcbiAgICAgIGdldDogKHRhcmdldDogYW55LCBuYW1lOiBhbnkpOiBhbnkgPT4ge1xuICAgICAgICByZXR1cm4gbmFtZSBpbiB0YXJnZXQgPyBSZWZsZWN0LmdldCh0YXJnZXQsIG5hbWUpIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgbmV3Q29udHJvbHM6IHsgW2tleTogc3RyaW5nXTogQWJzdHJhY3RDb250cm9sIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IHByb3AgaW4gY29udHJvbHMpIHtcbiAgICAgIGlmIChjb250cm9sc1twcm9wXSBpbnN0YW5jZW9mIE9iamVjdCAmJiBjb250cm9sc1twcm9wXS5hbm5vdGF0ZWQpIHtcbiAgICAgICAgY29uc3QgbWV0YWRhdGEgPSBjb250cm9sc1twcm9wXTtcbiAgICAgICAgY29uc3QgY29udHJvbE5hbWUgPSBnZXROYW1lKHByb3ApO1xuXG4gICAgICAgIGlmIChtZXRhZGF0YS5uZXN0ZWQpIHtcbiAgICAgICAgICBuZXdDb250cm9sc1tjb250cm9sTmFtZV0gPSBuZXcgRm9ybUdyb3VwKHRoaXMuZ2VuZXJhdGVBYnN0cmFjdENvbnRyb2xzKGNvbnRyb2xzW2NvbnRyb2xOYW1lXSkpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3luY1ZhbGlkYXRvcnM6IFZhbGlkYXRvckZuID0gZXhwb3NlU3luY1ZhbGlkYXRvcnMobWV0YWRhdGEpO1xuICAgICAgICBjb25zdCBhc3luY1ZhbGlkYXRvcnM6IEFzeW5jVmFsaWRhdG9yRm4gPSBleHBvc2VBc3luY1ZhbGlkYXRvcnMobWV0YWRhdGEpO1xuXG4gICAgICAgIGlmIChtZXRhZGF0YS5uZXN0ZWRBcnJheSkge1xuICAgICAgICAgIGNvbnN0IGFycmF5Rm9ybSA9IGNvbnRyb2xzW2NvbnRyb2xOYW1lXS5tYXAoKGNvbnRyb2w6IGFueSkgPT4gbmV3IEZvcm1Hcm91cCgodGhpcy5nZW5lcmF0ZUFic3RyYWN0Q29udHJvbHMoY29udHJvbCkpKSk7XG5cbiAgICAgICAgICBuZXdDb250cm9sc1tjb250cm9sTmFtZV0gPSBuZXcgRm9ybUFycmF5KGFycmF5Rm9ybSwgc3luY1ZhbGlkYXRvcnMsIGFzeW5jVmFsaWRhdG9ycyk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdDb250cm9sc1tjb250cm9sTmFtZV0gPSBuZXcgRm9ybUNvbnRyb2woe1xuICAgICAgICAgIHZhbHVlOiBjb250cm9sc1tjb250cm9sTmFtZV0sXG4gICAgICAgICAgZGlzYWJsZWQ6IG1ldGFkYXRhLmRpc2FibGVkXG4gICAgICAgIH0sIHN5bmNWYWxpZGF0b3JzLCBhc3luY1ZhbGlkYXRvcnMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuZXdDb250cm9scztcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnRyb2xDb25maWcge1xuICBba2V5OiBzdHJpbmddOiBhbnk7XG59XG5cbmZ1bmN0aW9uIGV4cG9zZVN5bmNWYWxpZGF0b3JzKG1ldGFkYXRhKTogVmFsaWRhdG9yRm4ge1xuICBpZiAobWV0YWRhdGEuc3luY1ZhbGlkYXRvcnMpIHtcbiAgICByZXR1cm4gVmFsaWRhdG9ycy5jb21wb3NlKG1ldGFkYXRhLnN5bmNWYWxpZGF0b3JzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBleHBvc2VBc3luY1ZhbGlkYXRvcnMobWV0YWRhdGEpOiBBc3luY1ZhbGlkYXRvckZuIHtcbiAgaWYgKG1ldGFkYXRhLmFzeW5jVmFsaWRhdG9ycykge1xuICAgIHJldHVybiBWYWxpZGF0b3JzLmNvbXBvc2VBc3luYyhtZXRhZGF0YS5hc3luY1ZhbGlkYXRvcnMpO1xuICB9XG59XG4iLCIvKiB0c2xpbnQ6ZGlzYWJsZTp2YXJpYWJsZS1uYW1lICovXG5pbXBvcnQge2NoZWNrQW5ub3RhdGlvbkNvbmZsaWN0cywgRm9ybU1ldGFkYXRhLCBzZXROYW1lfSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBjb25zdCBEaXNhYmxlZCA9ICgpOiBhbnkgPT4gKHRhcmdldDogYW55LCBrZXk6IHN0cmluZykgPT4ge1xuICBsZXQgbWV0YWRhdGEgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHNldE5hbWUoa2V5KSkgYXMgRm9ybU1ldGFkYXRhO1xuXG4gIGNoZWNrQW5ub3RhdGlvbkNvbmZsaWN0cyhtZXRhZGF0YSwgJ0Rpc2FibGVkJyk7XG5cbiAgbWV0YWRhdGEgPSBtZXRhZGF0YSB8fCB7YW5ub3RhdGVkOiB0cnVlfTtcbiAgbWV0YWRhdGEuZGlzYWJsZWQgPSB0cnVlO1xuXG4gIFJlZmxlY3Quc2V0KHRhcmdldCwgc2V0TmFtZShrZXkpLCBtZXRhZGF0YSk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtBbm5vdGF0aW9uRnVuY3Rpb24sIGNoZWNrQW5ub3RhdGlvbkNvbmZsaWN0cywgRm9ybU1ldGFkYXRhLCBzZXROYW1lfSBmcm9tICcuL2NvbW1vbic7XG5cbi8qKlxuICogSWYgeW91IGRvbmB0IG5lZWQgdG8gdmFsaWRhdGUgZmllbGQsIGp1c3QgdXNlIHRoaXMgYW5ub3RhdGlvbiwgb3RoZXJ3aXNlIHlvdSB3aWxsIG5vdCBnZXQgZm9ybUNvbnRyb2wgaW4gdGhlIENvbnRyb2xDb25maWdcbiAqL1xuZXhwb3J0IGNvbnN0IEVtcHR5Q29udHJvbCA9ICgpOiBBbm5vdGF0aW9uRnVuY3Rpb24gPT4gKHRhcmdldDogYW55LCBrZXk6IHN0cmluZykgPT4ge1xuICBsZXQgbWV0YWRhdGEgPSBSZWZsZWN0LmdldCh0YXJnZXQsIHNldE5hbWUoa2V5KSkgYXMgRm9ybU1ldGFkYXRhO1xuXG4gIGNoZWNrQW5ub3RhdGlvbkNvbmZsaWN0cyhtZXRhZGF0YSwgJ0VtcHR5Q29udHJvbCcpO1xuXG4gIG1ldGFkYXRhID0gbWV0YWRhdGEgfHwge2Fubm90YXRlZDogdHJ1ZX07XG4gIFJlZmxlY3Quc2V0KHRhcmdldCwgc2V0TmFtZShrZXkpLCBtZXRhZGF0YSk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtBbm5vdGF0aW9uRnVuY3Rpb24sIHNldFN5bmNWYWxpZGF0b3J9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7VmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgY29uc3QgTWF4ID0gKG1heDogbnVtYmVyKTogQW5ub3RhdGlvbkZ1bmN0aW9uID0+ICh0YXJnZXQ6IG9iamVjdCwga2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgc2V0U3luY1ZhbGlkYXRvcih0YXJnZXQsIGtleSwgVmFsaWRhdG9ycy5tYXgobWF4KSk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtBbm5vdGF0aW9uRnVuY3Rpb24sIHNldFN5bmNWYWxpZGF0b3J9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7VmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgY29uc3QgRW1haWwgPSAoKTogQW5ub3RhdGlvbkZ1bmN0aW9uID0+ICh0YXJnZXQ6IG9iamVjdCwga2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgc2V0U3luY1ZhbGlkYXRvcih0YXJnZXQsIGtleSwgVmFsaWRhdG9ycy5lbWFpbCk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtBbm5vdGF0aW9uRnVuY3Rpb24sIHNldFN5bmNWYWxpZGF0b3J9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7VmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgY29uc3QgTWF4TGVuZ3RoID0gKG1heExlbmd0aDogbnVtYmVyKTogQW5ub3RhdGlvbkZ1bmN0aW9uID0+ICh0YXJnZXQ6IG9iamVjdCwga2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgc2V0U3luY1ZhbGlkYXRvcih0YXJnZXQsIGtleSwgVmFsaWRhdG9ycy5tYXhMZW5ndGgobWF4TGVuZ3RoKSk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtBbm5vdGF0aW9uRnVuY3Rpb24sIHNldFN5bmNWYWxpZGF0b3J9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7VmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgY29uc3QgTWluID0gKG1pbjogbnVtYmVyKTogQW5ub3RhdGlvbkZ1bmN0aW9uID0+ICh0YXJnZXQ6IG9iamVjdCwga2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgc2V0U3luY1ZhbGlkYXRvcih0YXJnZXQsIGtleSwgVmFsaWRhdG9ycy5taW4obWluKSk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtzZXRTeW5jVmFsaWRhdG9yfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQge1ZhbGlkYXRvcnN9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuZXhwb3J0IGNvbnN0IE1pbkxlbmd0aCA9IChtaW5MZW5ndGg6IG51bWJlcik6IGFueSA9PiAodGFyZ2V0OiBhbnksIGtleTogc3RyaW5nKSA9PiB7XG4gIHNldFN5bmNWYWxpZGF0b3IodGFyZ2V0LCBrZXksIFZhbGlkYXRvcnMubWluTGVuZ3RoKG1pbkxlbmd0aCkpO1xufTtcbiIsIi8qIHRzbGludDpkaXNhYmxlOnZhcmlhYmxlLW5hbWUgKi9cbmltcG9ydCB7Rm9ybU1ldGFkYXRhLCBzZXROYW1lfSBmcm9tICcuL2NvbW1vbic7XG5cbi8qKlxuICogRGVmaW5lIG5lc3RlZCBncm91cENvbnRyb2xcbiAqXG4gKiBJbXBvcnRhbnQgbm90aWNlOlxuICogc2hvdWxkIGJlIG9ubHkgb25lIG5lc3RlZCBhbm5vdGF0aW9uIHBlciBjbGFzcyBwcm9wZXJ0eVxuICpcbiAqL1xuZXhwb3J0IGNvbnN0IE5lc3RlZCA9ICgpID0+ICh0YXJnZXQ6IG9iamVjdCwga2V5OiBzdHJpbmcpID0+IHtcbiAgbGV0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBzZXROYW1lKGtleSkpIGFzIEZvcm1NZXRhZGF0YTtcblxuICBpZiAobWV0YWRhdGEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Fubm90YXRpb24gTmVzdGVkIGhhcyBjb25mbGljdHMsIHBsZWFzZSByZW1vdmUgb3RoZXIgYW5ub3RhdGlvbnMnKTtcbiAgfVxuXG4gIG1ldGFkYXRhID0ge2Fubm90YXRlZDogdHJ1ZSwgbmVzdGVkOiB0cnVlfTtcbiAgUmVmbGVjdC5zZXQodGFyZ2V0LCBzZXROYW1lKGtleSksIG1ldGFkYXRhKTtcbn07XG4iLCIvKiB0c2xpbnQ6ZGlzYWJsZTp2YXJpYWJsZS1uYW1lICovXG5pbXBvcnQge0Zvcm1NZXRhZGF0YSwgc2V0TmFtZX0gZnJvbSAnLi9jb21tb24nO1xuXG4vKipcbiAqIERlZmluZSBuZXN0ZWQgQXJyYXlDb250cm9sXG4gKlxuICovXG5leHBvcnQgY29uc3QgTmVzdGVkQXJyYXkgPSAoKSA9PiAodGFyZ2V0OiBhbnksIGtleTogc3RyaW5nKSA9PiB7XG4gIGxldCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgc2V0TmFtZShrZXkpKSBhcyBGb3JtTWV0YWRhdGE7XG5cbiAgaWYgKG1ldGFkYXRhICYmIG1ldGFkYXRhLm5lc3RlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQW5ub3RhdGlvbiBOZXN0ZWRBcnJheSBoYXMgY29uZmxpY3Qgd2l0aCBOZXN0ZWQgQW5ub3RhdGlvbiwgcGxlYXNlIHJlbW92ZSBvbmUgb2YgdGhlbScpO1xuICB9XG5cbiAgbWV0YWRhdGEgPSB7YW5ub3RhdGVkOiB0cnVlLCBuZXN0ZWRBcnJheTogdHJ1ZX07XG4gIFJlZmxlY3Quc2V0KHRhcmdldCwgc2V0TmFtZShrZXkpLCBtZXRhZGF0YSk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtBbm5vdGF0aW9uRnVuY3Rpb24sIHNldFN5bmNWYWxpZGF0b3J9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7VmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgY29uc3QgUmVxdWlyZWQgPSAoKTogQW5ub3RhdGlvbkZ1bmN0aW9uID0+ICh0YXJnZXQ6IG9iamVjdCwga2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgc2V0U3luY1ZhbGlkYXRvcih0YXJnZXQsIGtleSwgVmFsaWRhdG9ycy5yZXF1aXJlZCk7XG59O1xuIiwiLyogdHNsaW50OmRpc2FibGU6dmFyaWFibGUtbmFtZSAqL1xuaW1wb3J0IHtBbm5vdGF0aW9uRnVuY3Rpb24sIHNldFN5bmNWYWxpZGF0b3J9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7VmFsaWRhdG9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgY29uc3QgUmVxdWlyZWRUcnVlID0gKCk6IEFubm90YXRpb25GdW5jdGlvbiA9PiAodGFyZ2V0OiBvYmplY3QsIGtleTogc3RyaW5nKTogdm9pZCA9PiB7XG4gIHNldFN5bmNWYWxpZGF0b3IodGFyZ2V0LCBrZXksIFZhbGlkYXRvcnMucmVxdWlyZWRUcnVlKTtcbn07XG4iLCIvKiB0c2xpbnQ6ZGlzYWJsZTp2YXJpYWJsZS1uYW1lICovXG5pbXBvcnQge0Fubm90YXRpb25GdW5jdGlvbiwgc2V0U3luY1ZhbGlkYXRvcn0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHtWYWxpZGF0b3JzfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmV4cG9ydCBjb25zdCBQYXR0ZXJuID0gKHBhdHRlcm46IHN0cmluZyB8IFJlZ0V4cCk6IEFubm90YXRpb25GdW5jdGlvbiA9PiAodGFyZ2V0OiBvYmplY3QsIGtleTogc3RyaW5nKTogdm9pZCA9PiB7XG4gIHNldFN5bmNWYWxpZGF0b3IodGFyZ2V0LCBrZXksIFZhbGlkYXRvcnMucGF0dGVybihwYXR0ZXJuKSk7XG59O1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBYUEsTUFBYSxPQUFPLEdBQUcsQ0FBQyxJQUFZO0lBQ2xDLE9BQU8sS0FBSyxJQUFJLElBQUksQ0FBQztDQUN0QixDQUFDOztBQUVGLE1BQWEsT0FBTyxHQUFHLENBQUMsSUFBWTtJQUNsQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUMsU0FBUyxFQUFFLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztDQUM3RCxDQUFDOztBQUVGLE1BQWEsZ0JBQWdCLEdBQUcsQ0FBQyxNQUFXLEVBQUUsR0FBVyxFQUFFLFNBQXNCOztJQUMvRSxJQUFJLFFBQVEscUJBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFpQixFQUFDO0lBRWpFLHdCQUF3QixDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUVoRCxRQUFRLEdBQUcsUUFBUSxJQUFJLEVBQUMsU0FBUyxFQUFFLElBQUksRUFBQyxDQUFDO0lBQ3pDLFFBQVEsQ0FBQyxjQUFjLEdBQUcsUUFBUSxDQUFDLGNBQWMsSUFBSSxFQUFFLENBQUM7SUFDeEQsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFeEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0NBQzdDLENBQUM7O0FBY0YsTUFBYSx3QkFBd0IsR0FBRyxD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