UNPKG

@ng-stack/forms

Version:

> provides wrapped Angular's Reactive Forms to write its more strongly typed.

327 lines (319 loc) 32.6 kB
import { UntypedFormGroup as NativeFormGroup } from '@angular/forms'; export class FormGroup extends NativeFormGroup { /** * Creates a new `FormGroup` instance. * * @param controls A collection of child controls. The key for each child is the name * under which it is registered. * * @param validatorOrOpts A synchronous validator function, or an array of * such functions, or an `AbstractControlOptions` object that contains validation functions * and a validation trigger. * * @param asyncValidator A single async validator or array of async validator functions * * @todo Chechout how to respect optional and require properties modifyers for the controls. */ constructor(controls, validatorOrOpts, asyncValidator) { super(controls, validatorOrOpts, asyncValidator); this.controls = controls; } /** * Registers a control with the group's list of controls. * * This method does not update the value or validity of the control. * Use [addControl](https://angular.io/api/forms/FormGroup#addControl) instead. * * @param name The control name to register in the collection * @param control Provides the control for the given name */ registerControl(name, control) { return super.registerControl(name, control); } /** * Add a control to this group. * * This method also updates the value and validity of the control. * * @param name The control name to add to the collection * @param control Provides the control for the given name */ addControl(name, control) { return super.addControl(name, control); } /** * Remove a control from this group. * * @param name The control name to remove from the collection */ removeControl(name) { return super.removeControl(name); } /** * Replace an existing control. * * @param name The control name to replace in the collection * @param control Provides the control for the given name */ setControl(name, control) { return super.setControl(name, control); } /** * Check whether there is an enabled control with the given name in the group. * * Reports false for disabled controls. If you'd like to check for existence in the group * only, use [get](https://angular.io/api/forms/AbstractControl#get) instead. * * @param name The control name to check for existence in the collection * * @returns false for disabled controls, true otherwise. */ contains(name) { return super.contains(name); } /** * Sets the value of the `FormGroup`. It accepts an object that matches * the structure of the group, with control names as keys. * * ### Set the complete value for the form group * ```ts const form = new FormGroup({ first: new FormControl(), last: new FormControl() }); console.log(form.value); // {first: null, last: null} form.setValue({first: 'Nancy', last: 'Drew'}); console.log(form.value); // {first: 'Nancy', last: 'Drew'} ``` * * @throws When strict checks fail, such as setting the value of a control * that doesn't exist or if you excluding the value of a control. * * @param value The new value for the control that matches the structure of the group. * @param options Configuration options that determine how the control propagates changes * and emits events after the value changes. * The configuration options are passed to the * [updateValueAndValidity](https://angular.io/api/forms/AbstractControl#updateValueAndValidity) method. * * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is * false. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` * observables emit events with the latest status and value when the control value is updated. * When false, no events are emitted. */ setValue(value, options = {}) { return super.setValue(value, options); } /** * Patches the value of the `FormGroup`. It accepts an object with control * names as keys, and does its best to match the values to the correct controls * in the group. * * It accepts both super-sets and sub-sets of the group without throwing an error. * * ### Patch the value for a form group * ```ts const form = new FormGroup({ first: new FormControl(), last: new FormControl() }); console.log(form.value); // {first: null, last: null} form.patchValue({first: 'Nancy'}); console.log(form.value); // {first: 'Nancy', last: null} ``` * * @param value The object that matches the structure of the group. * @param options Configuration options that determine how the control propagates changes and * emits events after the value is patched. * * `onlySelf`: When true, each change only affects this control and not its parent. Default is * true. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` * observables emit events with the latest status and value when the control value is updated. * When false, no events are emitted. * The configuration options are passed to the * [updateValueAndValidity](https://angular.io/api/forms/AbstractControl#updateValueAndValidity) method. */ patchValue(value, options = {}) { return super.patchValue(value, options); } /** * Resets the `FormGroup`, marks all descendants are marked `pristine` and `untouched`, and * the value of all descendants to null. * * You reset to a specific form state by passing in a map of states * that matches the structure of your form, with control names as keys. The state * is a standalone value or a form state object with both a value and a disabled * status. * * @param formState Resets the control with an initial value, * or an object that defines the initial value and disabled state. * * @param options Configuration options that determine how the control propagates changes * and emits events when the group is reset. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is * false. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` * observables emit events with the latest status and value when the control is reset. * When false, no events are emitted. * The configuration options are passed to the * [updateValueAndValidity](https://angular.io/api/forms/AbstractControl#updateValueAndValidity) method. * * * ### Reset the form group values * ```ts const form = new FormGroup({ first: new FormControl('first name'), last: new FormControl('last name') }); console.log(form.value); // {first: 'first name', last: 'last name'} form.reset({ first: 'name', last: 'last name' }); console.log(form.value); // {first: 'name', last: 'last name'} ``` * * ### Reset the form group values and disabled status * ```ts const form = new FormGroup({ first: new FormControl('first name'), last: new FormControl('last name') }); form.reset({ first: {value: 'name', disabled: true}, last: 'last' }); console.log(this.form.value); // {first: 'name', last: 'last name'} console.log(this.form.get('first').status); // 'DISABLED' ``` */ reset(value = {}, options = {}) { return super.reset(value, options); } /** * The aggregate value of the `FormGroup`, including any disabled controls. * * Retrieves all values regardless of disabled status. * The `value` property is the best way to get the value of the group, because * it excludes disabled controls in the `FormGroup`. */ getRawValue() { return super.getRawValue(); } /** * Retrieves a child control given the control's name. * * ### Retrieve a nested control * * For example, to get a `name` control nested within a `person` sub-group: ```ts this.form.get('person').get('name'); ``` */ get(controlName) { return super.get(controlName); } /** * Sets the synchronous validators that are active on this control. Calling * this overwrites any existing sync validators. */ setValidators(newValidator) { return super.setValidators(newValidator); } /** * Sets the async validators that are active on this control. Calling this * overwrites any existing async validators. */ setAsyncValidators(newValidator) { return super.setAsyncValidators(newValidator); } /** * Sets errors on a form control when running validations manually, rather than automatically. * * Calling `setErrors` also updates the validity of the parent control. * * ### Manually set the errors for a control * * ```ts * const login = new FormControl('someLogin'); * login.setErrors({ * notUnique: true * }); * * expect(login.valid).toEqual(false); * expect(login.errors).toEqual({ notUnique: true }); * * login.setValue('someOtherLogin'); * * expect(login.valid).toEqual(true); * ``` */ setErrors(errors, opts = {}) { return super.setErrors(errors, opts); } /** * Reports error data for the control with the given controlName. * * @param errorCode The code of the error to check * @param controlName A control name that designates how to move from the current control * to the control that should be queried for errors. * * For example, for the following `FormGroup`: * ```ts form = new FormGroup({ address: new FormGroup({ street: new FormControl() }) }); ``` * * The controlName to the 'street' control from the root form would be 'address' -> 'street'. * * It can be provided to this method in combination with `get()` method: * ```ts form.get('address').getError('someErrorCode', 'street'); ``` * * @returns error data for that particular error. If the control or error is not present, * null is returned. */ getError(errorCode, controlName) { return super.getError(errorCode, controlName); } /** * Reports whether the control with the given controlName has the error specified. * * @param errorCode The code of the error to check * @param controlName A control name that designates how to move from the current control * to the control that should be queried for errors. * * For example, for the following `FormGroup`: * ```ts form = new FormGroup({ address: new FormGroup({ street: new FormControl() }) }); ``` * * The controlName to the 'street' control from the root form would be 'address' -> 'street'. * * It can be provided to this method in combination with `get()` method: ```ts form.get('address').hasError('someErrorCode', 'street'); ``` * * If no controlName is given, this method checks for the error on the current control. * * @returns whether the given error is present in the control at the given controlName. * * If the control is not present, false is returned. */ hasError(errorCode, controlName) { return super.hasError(errorCode, controlName); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1ncm91cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Zvcm1zL3NyYy9saWIvZm9ybS1ncm91cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLElBQUksZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFnQnJFLE1BQU0sT0FBTyxTQUdYLFNBQVEsZUFBZTtJQU92Qjs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsWUFDa0IsUUFBa0QsRUFDbEUsZUFJUSxFQUNSLGNBQTZEO1FBRTdELEtBQUssQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBUmpDLGFBQVEsR0FBUixRQUFRLENBQTBDO0lBU3BFLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNNLGVBQWUsQ0FHdEIsSUFBTyxFQUFFLE9BQThCO1FBQ3ZDLE9BQU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUEwQixDQUFDO0lBQ3ZFLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ00sVUFBVSxDQUdqQixJQUFPLEVBQUUsT0FBOEI7UUFDdkMsT0FBTyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNNLGFBQWEsQ0FBMEIsSUFBTztRQUNyRCxPQUFPLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ00sVUFBVSxDQUdqQixJQUFPLEVBQUUsT0FBOEI7UUFDdkMsT0FBTyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ00sUUFBUSxDQUEwQixJQUFPO1FBQ2hELE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWlDRztJQUNNLFFBQVEsQ0FDZixLQUEyQixFQUMzQixVQUF1RCxFQUFFO1FBRXpELE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BK0JHO0lBQ00sVUFBVSxDQUNqQixLQUFvQyxFQUNwQyxVQUF1RCxFQUFFO1FBRXpELE9BQU8sS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BdURHO0lBQ00sS0FBSyxDQUNaLFFBQThCLEVBQVMsRUFDdkMsVUFBdUQsRUFBRTtRQUV6RCxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDTSxXQUFXO1FBQ2xCLE9BQU8sS0FBSyxDQUFDLFdBQVcsRUFBMEIsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ00sR0FBRyxDQUNWLFdBQWM7UUFFZCxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFpQyxDQUFDO0lBQ2hFLENBQUM7SUFFRDs7O09BR0c7SUFDTSxhQUFhLENBQUMsWUFBZ0Q7UUFDckUsT0FBTyxLQUFLLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7O09BR0c7SUFDTSxrQkFBa0IsQ0FDekIsWUFBMEQ7UUFFMUQsT0FBTyxLQUFLLENBQUMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQW9CRztJQUNNLFNBQVMsQ0FDaEIsTUFBK0IsRUFDL0IsT0FBZ0MsRUFBRTtRQUVsQyxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXlCRztJQUNNLFFBQVEsQ0FDZixTQUFZLEVBQ1osV0FBZTtRQUVmLE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFnQixDQUFDO0lBQy9ELENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMkJHO0lBQ00sUUFBUSxDQUNmLFNBQVksRUFDWixXQUFlO1FBRWYsT0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNoRCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBVbnR5cGVkRm9ybUdyb3VwIGFzIE5hdGl2ZUZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1xuICBTdGF0dXMsXG4gIFN0cmluZ0tleXMsXG4gIFZhbGlkYXRvckZuLFxuICBBc3luY1ZhbGlkYXRvckZuLFxuICBWYWxpZGF0b3JzTW9kZWwsXG4gIFZhbGlkYXRpb25FcnJvcnMsXG4gIEFic3RyYWN0Q29udHJvbE9wdGlvbnMsXG4gIENvbnRyb2xUeXBlLFxuICBFeHRyYWN0R3JvdXBWYWx1ZSxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBGb3JtR3JvdXA8XG4gIFQgZXh0ZW5kcyBvYmplY3QgPSBhbnksXG4gIFYgZXh0ZW5kcyBvYmplY3QgPSBWYWxpZGF0b3JzTW9kZWxcbj4gZXh0ZW5kcyBOYXRpdmVGb3JtR3JvdXAge1xuICBvdmVycmlkZSByZWFkb25seSB2YWx1ZTogRXh0cmFjdEdyb3VwVmFsdWU8VD47XG4gIG92ZXJyaWRlIHJlYWRvbmx5IHZhbHVlQ2hhbmdlczogT2JzZXJ2YWJsZTxFeHRyYWN0R3JvdXBWYWx1ZTxUPj47XG4gIG92ZXJyaWRlIHJlYWRvbmx5IHN0YXR1czogU3RhdHVzO1xuICBvdmVycmlkZSByZWFkb25seSBzdGF0dXNDaGFuZ2VzOiBPYnNlcnZhYmxlPFN0YXR1cz47XG4gIG92ZXJyaWRlIHJlYWRvbmx5IGVycm9yczogVmFsaWRhdGlvbkVycm9yczxWPiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYEZvcm1Hcm91cGAgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBjb250cm9scyBBIGNvbGxlY3Rpb24gb2YgY2hpbGQgY29udHJvbHMuIFRoZSBrZXkgZm9yIGVhY2ggY2hpbGQgaXMgdGhlIG5hbWVcbiAgICogdW5kZXIgd2hpY2ggaXQgaXMgcmVnaXN0ZXJlZC5cbiAgICpcbiAgICogQHBhcmFtIHZhbGlkYXRvck9yT3B0cyBBIHN5bmNocm9ub3VzIHZhbGlkYXRvciBmdW5jdGlvbiwgb3IgYW4gYXJyYXkgb2ZcbiAgICogc3VjaCBmdW5jdGlvbnMsIG9yIGFuIGBBYnN0cmFjdENvbnRyb2xPcHRpb25zYCBvYmplY3QgdGhhdCBjb250YWlucyB2YWxpZGF0aW9uIGZ1bmN0aW9uc1xuICAgKiBhbmQgYSB2YWxpZGF0aW9uIHRyaWdnZXIuXG4gICAqXG4gICAqIEBwYXJhbSBhc3luY1ZhbGlkYXRvciBBIHNpbmdsZSBhc3luYyB2YWxpZGF0b3Igb3IgYXJyYXkgb2YgYXN5bmMgdmFsaWRhdG9yIGZ1bmN0aW9uc1xuICAgKlxuICAgKiBAdG9kbyBDaGVjaG91dCBob3cgdG8gcmVzcGVjdCBvcHRpb25hbCBhbmQgcmVxdWlyZSBwcm9wZXJ0aWVzIG1vZGlmeWVycyBmb3IgdGhlIGNvbnRyb2xzLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG92ZXJyaWRlIGNvbnRyb2xzOiB7IFtQIGluIGtleW9mIFRdOiBDb250cm9sVHlwZTxUW1BdLCBWPiB9LFxuICAgIHZhbGlkYXRvck9yT3B0cz86XG4gICAgICB8IFZhbGlkYXRvckZuXG4gICAgICB8IFZhbGlkYXRvckZuW11cbiAgICAgIHwgQWJzdHJhY3RDb250cm9sT3B0aW9uc1xuICAgICAgfCBudWxsLFxuICAgIGFzeW5jVmFsaWRhdG9yPzogQXN5bmNWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm5bXSB8IG51bGxcbiAgKSB7XG4gICAgc3VwZXIoY29udHJvbHMsIHZhbGlkYXRvck9yT3B0cywgYXN5bmNWYWxpZGF0b3IpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIGNvbnRyb2wgd2l0aCB0aGUgZ3JvdXAncyBsaXN0IG9mIGNvbnRyb2xzLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1cGRhdGUgdGhlIHZhbHVlIG9yIHZhbGlkaXR5IG9mIHRoZSBjb250cm9sLlxuICAgKiBVc2UgW2FkZENvbnRyb2xdKGh0dHBzOi8vYW5ndWxhci5pby9hcGkvZm9ybXMvRm9ybUdyb3VwI2FkZENvbnRyb2wpIGluc3RlYWQuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIFRoZSBjb250cm9sIG5hbWUgdG8gcmVnaXN0ZXIgaW4gdGhlIGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIGNvbnRyb2wgUHJvdmlkZXMgdGhlIGNvbnRyb2wgZm9yIHRoZSBnaXZlbiBuYW1lXG4gICAqL1xuICBvdmVycmlkZSByZWdpc3RlckNvbnRyb2w8XG4gICAgSyBleHRlbmRzIFN0cmluZ0tleXM8VD4sXG4gICAgQ1YgZXh0ZW5kcyBvYmplY3QgPSBWYWxpZGF0b3JzTW9kZWxcbiAgPihuYW1lOiBLLCBjb250cm9sOiBDb250cm9sVHlwZTxUW0tdLCBDVj4pIHtcbiAgICByZXR1cm4gc3VwZXIucmVnaXN0ZXJDb250cm9sKG5hbWUsIGNvbnRyb2wpIGFzIENvbnRyb2xUeXBlPFRbS10sIENWPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBjb250cm9sIHRvIHRoaXMgZ3JvdXAuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGFsc28gdXBkYXRlcyB0aGUgdmFsdWUgYW5kIHZhbGlkaXR5IG9mIHRoZSBjb250cm9sLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgY29udHJvbCBuYW1lIHRvIGFkZCB0byB0aGUgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gY29udHJvbCBQcm92aWRlcyB0aGUgY29udHJvbCBmb3IgdGhlIGdpdmVuIG5hbWVcbiAgICovXG4gIG92ZXJyaWRlIGFkZENvbnRyb2w8XG4gICAgSyBleHRlbmRzIFN0cmluZ0tleXM8VD4sXG4gICAgQ1YgZXh0ZW5kcyBvYmplY3QgPSBWYWxpZGF0b3JzTW9kZWxcbiAgPihuYW1lOiBLLCBjb250cm9sOiBDb250cm9sVHlwZTxUW0tdLCBDVj4pIHtcbiAgICByZXR1cm4gc3VwZXIuYWRkQ29udHJvbChuYW1lLCBjb250cm9sKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSBjb250cm9sIGZyb20gdGhpcyBncm91cC5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgVGhlIGNvbnRyb2wgbmFtZSB0byByZW1vdmUgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgKi9cbiAgb3ZlcnJpZGUgcmVtb3ZlQ29udHJvbDxLIGV4dGVuZHMgU3RyaW5nS2V5czxUPj4obmFtZTogSykge1xuICAgIHJldHVybiBzdXBlci5yZW1vdmVDb250cm9sKG5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgYW4gZXhpc3RpbmcgY29udHJvbC5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgVGhlIGNvbnRyb2wgbmFtZSB0byByZXBsYWNlIGluIHRoZSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBjb250cm9sIFByb3ZpZGVzIHRoZSBjb250cm9sIGZvciB0aGUgZ2l2ZW4gbmFtZVxuICAgKi9cbiAgb3ZlcnJpZGUgc2V0Q29udHJvbDxcbiAgICBLIGV4dGVuZHMgU3RyaW5nS2V5czxUPixcbiAgICBDViBleHRlbmRzIG9iamVjdCA9IFZhbGlkYXRvcnNNb2RlbFxuICA+KG5hbWU6IEssIGNvbnRyb2w6IENvbnRyb2xUeXBlPFRbS10sIENWPikge1xuICAgIHJldHVybiBzdXBlci5zZXRDb250cm9sKG5hbWUsIGNvbnRyb2wpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYW4gZW5hYmxlZCBjb250cm9sIHdpdGggdGhlIGdpdmVuIG5hbWUgaW4gdGhlIGdyb3VwLlxuICAgKlxuICAgKiBSZXBvcnRzIGZhbHNlIGZvciBkaXNhYmxlZCBjb250cm9scy4gSWYgeW91J2QgbGlrZSB0byBjaGVjayBmb3IgZXhpc3RlbmNlIGluIHRoZSBncm91cFxuICAgKiBvbmx5LCB1c2UgW2dldF0oaHR0cHM6Ly9hbmd1bGFyLmlvL2FwaS9mb3Jtcy9BYnN0cmFjdENvbnRyb2wjZ2V0KSBpbnN0ZWFkLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgY29udHJvbCBuYW1lIHRvIGNoZWNrIGZvciBleGlzdGVuY2UgaW4gdGhlIGNvbGxlY3Rpb25cbiAgICpcbiAgICogQHJldHVybnMgZmFsc2UgZm9yIGRpc2FibGVkIGNvbnRyb2xzLCB0cnVlIG90aGVyd2lzZS5cbiAgICovXG4gIG92ZXJyaWRlIGNvbnRhaW5zPEsgZXh0ZW5kcyBTdHJpbmdLZXlzPFQ+PihuYW1lOiBLKSB7XG4gICAgcmV0dXJuIHN1cGVyLmNvbnRhaW5zKG5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBgRm9ybUdyb3VwYC4gSXQgYWNjZXB0cyBhbiBvYmplY3QgdGhhdCBtYXRjaGVzXG4gICAqIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGdyb3VwLCB3aXRoIGNvbnRyb2wgbmFtZXMgYXMga2V5cy5cbiAgICpcbiAgICogIyMjIFNldCB0aGUgY29tcGxldGUgdmFsdWUgZm9yIHRoZSBmb3JtIGdyb3VwXG4gICAqXG5gYGB0c1xuY29uc3QgZm9ybSA9IG5ldyBGb3JtR3JvdXAoe1xuICBmaXJzdDogbmV3IEZvcm1Db250cm9sKCksXG4gIGxhc3Q6IG5ldyBGb3JtQ29udHJvbCgpXG59KTtcblxuY29uc29sZS5sb2coZm9ybS52YWx1ZSk7ICAgLy8ge2ZpcnN0OiBudWxsLCBsYXN0OiBudWxsfVxuXG5mb3JtLnNldFZhbHVlKHtmaXJzdDogJ05hbmN5JywgbGFzdDogJ0RyZXcnfSk7XG5jb25zb2xlLmxvZyhmb3JtLnZhbHVlKTsgICAvLyB7Zmlyc3Q6ICdOYW5jeScsIGxhc3Q6ICdEcmV3J31cbmBgYFxuICAgKlxuICAgKiBAdGhyb3dzIFdoZW4gc3RyaWN0IGNoZWNrcyBmYWlsLCBzdWNoIGFzIHNldHRpbmcgdGhlIHZhbHVlIG9mIGEgY29udHJvbFxuICAgKiB0aGF0IGRvZXNuJ3QgZXhpc3Qgb3IgaWYgeW91IGV4Y2x1ZGluZyB0aGUgdmFsdWUgb2YgYSBjb250cm9sLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5ldyB2YWx1ZSBmb3IgdGhlIGNvbnRyb2wgdGhhdCBtYXRjaGVzIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGdyb3VwLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBDb25maWd1cmF0aW9uIG9wdGlvbnMgdGhhdCBkZXRlcm1pbmUgaG93IHRoZSBjb250cm9sIHByb3BhZ2F0ZXMgY2hhbmdlc1xuICAgKiBhbmQgZW1pdHMgZXZlbnRzIGFmdGVyIHRoZSB2YWx1ZSBjaGFuZ2VzLlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIGFyZSBwYXNzZWQgdG8gdGhlXG4gICAqIFt1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5XShodHRwczovL2FuZ3VsYXIuaW8vYXBpL2Zvcm1zL0Fic3RyYWN0Q29udHJvbCN1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KSBtZXRob2QuXG4gICAqXG4gICAqICogYG9ubHlTZWxmYDogV2hlbiB0cnVlLCBlYWNoIGNoYW5nZSBvbmx5IGFmZmVjdHMgdGhpcyBjb250cm9sLCBhbmQgbm90IGl0cyBwYXJlbnQuIERlZmF1bHQgaXNcbiAgICogZmFsc2UuXG4gICAqICogYGVtaXRFdmVudGA6IFdoZW4gdHJ1ZSBvciBub3Qgc3VwcGxpZWQgKHRoZSBkZWZhdWx0KSwgYm90aCB0aGUgYHN0YXR1c0NoYW5nZXNgIGFuZFxuICAgKiBgdmFsdWVDaGFuZ2VzYFxuICAgKiBvYnNlcnZhYmxlcyBlbWl0IGV2ZW50cyB3aXRoIHRoZSBsYXRlc3Qgc3RhdHVzIGFuZCB2YWx1ZSB3aGVuIHRoZSBjb250cm9sIHZhbHVlIGlzIHVwZGF0ZWQuXG4gICAqIFdoZW4gZmFsc2UsIG5vIGV2ZW50cyBhcmUgZW1pdHRlZC5cbiAgICovXG4gIG92ZXJyaWRlIHNldFZhbHVlKFxuICAgIHZhbHVlOiBFeHRyYWN0R3JvdXBWYWx1ZTxUPixcbiAgICBvcHRpb25zOiB7IG9ubHlTZWxmPzogYm9vbGVhbjsgZW1pdEV2ZW50PzogYm9vbGVhbiB9ID0ge31cbiAgKSB7XG4gICAgcmV0dXJuIHN1cGVyLnNldFZhbHVlKHZhbHVlLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXRjaGVzIHRoZSB2YWx1ZSBvZiB0aGUgYEZvcm1Hcm91cGAuIEl0IGFjY2VwdHMgYW4gb2JqZWN0IHdpdGggY29udHJvbFxuICAgKiBuYW1lcyBhcyBrZXlzLCBhbmQgZG9lcyBpdHMgYmVzdCB0byBtYXRjaCB0aGUgdmFsdWVzIHRvIHRoZSBjb3JyZWN0IGNvbnRyb2xzXG4gICAqIGluIHRoZSBncm91cC5cbiAgICpcbiAgICogSXQgYWNjZXB0cyBib3RoIHN1cGVyLXNldHMgYW5kIHN1Yi1zZXRzIG9mIHRoZSBncm91cCB3aXRob3V0IHRocm93aW5nIGFuIGVycm9yLlxuICAgKlxuICAgKiAjIyMgUGF0Y2ggdGhlIHZhbHVlIGZvciBhIGZvcm0gZ3JvdXBcbiAgICpcbmBgYHRzXG5jb25zdCBmb3JtID0gbmV3IEZvcm1Hcm91cCh7XG4gICBmaXJzdDogbmV3IEZvcm1Db250cm9sKCksXG4gICBsYXN0OiBuZXcgRm9ybUNvbnRyb2woKVxufSk7XG5jb25zb2xlLmxvZyhmb3JtLnZhbHVlKTsgICAvLyB7Zmlyc3Q6IG51bGwsIGxhc3Q6IG51bGx9XG5cbmZvcm0ucGF0Y2hWYWx1ZSh7Zmlyc3Q6ICdOYW5jeSd9KTtcbmNvbnNvbGUubG9nKGZvcm0udmFsdWUpOyAgIC8vIHtmaXJzdDogJ05hbmN5JywgbGFzdDogbnVsbH1cbmBgYFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9iamVjdCB0aGF0IG1hdGNoZXMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgZ3JvdXAuXG4gICAqIEBwYXJhbSBvcHRpb25zIENvbmZpZ3VyYXRpb24gb3B0aW9ucyB0aGF0IGRldGVybWluZSBob3cgdGhlIGNvbnRyb2wgcHJvcGFnYXRlcyBjaGFuZ2VzIGFuZFxuICAgKiBlbWl0cyBldmVudHMgYWZ0ZXIgdGhlIHZhbHVlIGlzIHBhdGNoZWQuXG4gICAqICogYG9ubHlTZWxmYDogV2hlbiB0cnVlLCBlYWNoIGNoYW5nZSBvbmx5IGFmZmVjdHMgdGhpcyBjb250cm9sIGFuZCBub3QgaXRzIHBhcmVudC4gRGVmYXVsdCBpc1xuICAgKiB0cnVlLlxuICAgKiAqIGBlbWl0RXZlbnRgOiBXaGVuIHRydWUgb3Igbm90IHN1cHBsaWVkICh0aGUgZGVmYXVsdCksIGJvdGggdGhlIGBzdGF0dXNDaGFuZ2VzYCBhbmRcbiAgICogYHZhbHVlQ2hhbmdlc2BcbiAgICogb2JzZXJ2YWJsZXMgZW1pdCBldmVudHMgd2l0aCB0aGUgbGF0ZXN0IHN0YXR1cyBhbmQgdmFsdWUgd2hlbiB0aGUgY29udHJvbCB2YWx1ZSBpcyB1cGRhdGVkLlxuICAgKiBXaGVuIGZhbHNlLCBubyBldmVudHMgYXJlIGVtaXR0ZWQuXG4gICAqIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgYXJlIHBhc3NlZCB0byB0aGVcbiAgICogW3VwZGF0ZVZhbHVlQW5kVmFsaWRpdHldKGh0dHBzOi8vYW5ndWxhci5pby9hcGkvZm9ybXMvQWJzdHJhY3RDb250cm9sI3VwZGF0ZVZhbHVlQW5kVmFsaWRpdHkpIG1ldGhvZC5cbiAgICovXG4gIG92ZXJyaWRlIHBhdGNoVmFsdWUoXG4gICAgdmFsdWU6IFBhcnRpYWw8RXh0cmFjdEdyb3VwVmFsdWU8VD4+LFxuICAgIG9wdGlvbnM6IHsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0gPSB7fVxuICApIHtcbiAgICByZXR1cm4gc3VwZXIucGF0Y2hWYWx1ZSh2YWx1ZSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBgRm9ybUdyb3VwYCwgbWFya3MgYWxsIGRlc2NlbmRhbnRzIGFyZSBtYXJrZWQgYHByaXN0aW5lYCBhbmQgYHVudG91Y2hlZGAsIGFuZFxuICAgKiB0aGUgdmFsdWUgb2YgYWxsIGRlc2NlbmRhbnRzIHRvIG51bGwuXG4gICAqXG4gICAqIFlvdSByZXNldCB0byBhIHNwZWNpZmljIGZvcm0gc3RhdGUgYnkgcGFzc2luZyBpbiBhIG1hcCBvZiBzdGF0ZXNcbiAgICogdGhhdCBtYXRjaGVzIHRoZSBzdHJ1Y3R1cmUgb2YgeW91ciBmb3JtLCB3aXRoIGNvbnRyb2wgbmFtZXMgYXMga2V5cy4gVGhlIHN0YXRlXG4gICAqIGlzIGEgc3RhbmRhbG9uZSB2YWx1ZSBvciBhIGZvcm0gc3RhdGUgb2JqZWN0IHdpdGggYm90aCBhIHZhbHVlIGFuZCBhIGRpc2FibGVkXG4gICAqIHN0YXR1cy5cbiAgICpcbiAgICogQHBhcmFtIGZvcm1TdGF0ZSBSZXNldHMgdGhlIGNvbnRyb2wgd2l0aCBhbiBpbml0aWFsIHZhbHVlLFxuICAgKiBvciBhbiBvYmplY3QgdGhhdCBkZWZpbmVzIHRoZSBpbml0aWFsIHZhbHVlIGFuZCBkaXNhYmxlZCBzdGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzIGNoYW5nZXNcbiAgICogYW5kIGVtaXRzIGV2ZW50cyB3aGVuIHRoZSBncm91cCBpcyByZXNldC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIGVhY2ggY2hhbmdlIG9ubHkgYWZmZWN0cyB0aGlzIGNvbnRyb2wsIGFuZCBub3QgaXRzIHBhcmVudC4gRGVmYXVsdCBpc1xuICAgKiBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCBib3RoIHRoZSBgc3RhdHVzQ2hhbmdlc2AgYW5kXG4gICAqIGB2YWx1ZUNoYW5nZXNgXG4gICAqIG9ic2VydmFibGVzIGVtaXQgZXZlbnRzIHdpdGggdGhlIGxhdGVzdCBzdGF0dXMgYW5kIHZhbHVlIHdoZW4gdGhlIGNvbnRyb2wgaXMgcmVzZXQuXG4gICAqIFdoZW4gZmFsc2UsIG5vIGV2ZW50cyBhcmUgZW1pdHRlZC5cbiAgICogVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBhcmUgcGFzc2VkIHRvIHRoZVxuICAgKiBbdXBkYXRlVmFsdWVBbmRWYWxpZGl0eV0oaHR0cHM6Ly9hbmd1bGFyLmlvL2FwaS9mb3Jtcy9BYnN0cmFjdENvbnRyb2wjdXBkYXRlVmFsdWVBbmRWYWxpZGl0eSkgbWV0aG9kLlxuICAgKlxuICAgKlxuICAgKiAjIyMgUmVzZXQgdGhlIGZvcm0gZ3JvdXAgdmFsdWVzXG4gICAqXG5gYGB0c1xuY29uc3QgZm9ybSA9IG5ldyBGb3JtR3JvdXAoe1xuICBmaXJzdDogbmV3IEZvcm1Db250cm9sKCdmaXJzdCBuYW1lJyksXG4gIGxhc3Q6IG5ldyBGb3JtQ29udHJvbCgnbGFzdCBuYW1lJylcbn0pO1xuXG5jb25zb2xlLmxvZyhmb3JtLnZhbHVlKTsgIC8vIHtmaXJzdDogJ2ZpcnN0IG5hbWUnLCBsYXN0OiAnbGFzdCBuYW1lJ31cblxuZm9ybS5yZXNldCh7IGZpcnN0OiAnbmFtZScsIGxhc3Q6ICdsYXN0IG5hbWUnIH0pO1xuXG5jb25zb2xlLmxvZyhmb3JtLnZhbHVlKTsgIC8vIHtmaXJzdDogJ25hbWUnLCBsYXN0OiAnbGFzdCBuYW1lJ31cbmBgYFxuICAgKlxuICAgKiAjIyMgUmVzZXQgdGhlIGZvcm0gZ3JvdXAgdmFsdWVzIGFuZCBkaXNhYmxlZCBzdGF0dXNcbiAgICpcbmBgYHRzXG5jb25zdCBmb3JtID0gbmV3IEZvcm1Hcm91cCh7XG4gIGZpcnN0OiBuZXcgRm9ybUNvbnRyb2woJ2ZpcnN0IG5hbWUnKSxcbiAgbGFzdDogbmV3IEZvcm1Db250cm9sKCdsYXN0IG5hbWUnKVxufSk7XG5cbmZvcm0ucmVzZXQoe1xuICBmaXJzdDoge3ZhbHVlOiAnbmFtZScsIGRpc2FibGVkOiB0cnVlfSxcbiAgbGFzdDogJ2xhc3QnXG59KTtcblxuY29uc29sZS5sb2codGhpcy5mb3JtLnZhbHVlKTsgIC8vIHtmaXJzdDogJ25hbWUnLCBsYXN0OiAnbGFzdCBuYW1lJ31cbmNvbnNvbGUubG9nKHRoaXMuZm9ybS5nZXQoJ2ZpcnN0Jykuc3RhdHVzKTsgIC8vICdESVNBQkxFRCdcbmBgYFxuICAgKi9cbiAgb3ZlcnJpZGUgcmVzZXQoXG4gICAgdmFsdWU6IEV4dHJhY3RHcm91cFZhbHVlPFQ+ID0ge30gYXMgYW55LFxuICAgIG9wdGlvbnM6IHsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0gPSB7fVxuICApIHtcbiAgICByZXR1cm4gc3VwZXIucmVzZXQodmFsdWUsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBhZ2dyZWdhdGUgdmFsdWUgb2YgdGhlIGBGb3JtR3JvdXBgLCBpbmNsdWRpbmcgYW55IGRpc2FibGVkIGNvbnRyb2xzLlxuICAgKlxuICAgKiBSZXRyaWV2ZXMgYWxsIHZhbHVlcyByZWdhcmRsZXNzIG9mIGRpc2FibGVkIHN0YXR1cy5cbiAgICogVGhlIGB2YWx1ZWAgcHJvcGVydHkgaXMgdGhlIGJlc3Qgd2F5IHRvIGdldCB0aGUgdmFsdWUgb2YgdGhlIGdyb3VwLCBiZWNhdXNlXG4gICAqIGl0IGV4Y2x1ZGVzIGRpc2FibGVkIGNvbnRyb2xzIGluIHRoZSBgRm9ybUdyb3VwYC5cbiAgICovXG4gIG92ZXJyaWRlIGdldFJhd1ZhbHVlKCkge1xuICAgIHJldHVybiBzdXBlci5nZXRSYXdWYWx1ZSgpIGFzIEV4dHJhY3RHcm91cFZhbHVlPFQ+O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIGNoaWxkIGNvbnRyb2wgZ2l2ZW4gdGhlIGNvbnRyb2wncyBuYW1lLlxuICAgKlxuICAgKiAjIyMgUmV0cmlldmUgYSBuZXN0ZWQgY29udHJvbFxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYG5hbWVgIGNvbnRyb2wgbmVzdGVkIHdpdGhpbiBhIGBwZXJzb25gIHN1Yi1ncm91cDpcbmBgYHRzXG50aGlzLmZvcm0uZ2V0KCdwZXJzb24nKS5nZXQoJ25hbWUnKTtcbmBgYFxuICAgKi9cbiAgb3ZlcnJpZGUgZ2V0PEsgZXh0ZW5kcyBTdHJpbmdLZXlzPFQ+LCBDViBleHRlbmRzIG9iamVjdCA9IFZhbGlkYXRvcnNNb2RlbD4oXG4gICAgY29udHJvbE5hbWU6IEtcbiAgKTogQ29udHJvbFR5cGU8VFtLXSwgQ1Y+IHwgbnVsbCB7XG4gICAgcmV0dXJuIHN1cGVyLmdldChjb250cm9sTmFtZSkgYXMgQ29udHJvbFR5cGU8VFtLXSwgQ1Y+IHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBzeW5jaHJvbm91cyB2YWxpZGF0b3JzIHRoYXQgYXJlIGFjdGl2ZSBvbiB0aGlzIGNvbnRyb2wuIENhbGxpbmdcbiAgICogdGhpcyBvdmVyd3JpdGVzIGFueSBleGlzdGluZyBzeW5jIHZhbGlkYXRvcnMuXG4gICAqL1xuICBvdmVycmlkZSBzZXRWYWxpZGF0b3JzKG5ld1ZhbGlkYXRvcjogVmFsaWRhdG9yRm4gfCBWYWxpZGF0b3JGbltdIHwgbnVsbCkge1xuICAgIHJldHVybiBzdXBlci5zZXRWYWxpZGF0b3JzKG5ld1ZhbGlkYXRvcik7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgYXN5bmMgdmFsaWRhdG9ycyB0aGF0IGFyZSBhY3RpdmUgb24gdGhpcyBjb250cm9sLiBDYWxsaW5nIHRoaXNcbiAgICogb3ZlcndyaXRlcyBhbnkgZXhpc3RpbmcgYXN5bmMgdmFsaWRhdG9ycy5cbiAgICovXG4gIG92ZXJyaWRlIHNldEFzeW5jVmFsaWRhdG9ycyhcbiAgICBuZXdWYWxpZGF0b3I6IEFzeW5jVmFsaWRhdG9yRm4gfCBBc3luY1ZhbGlkYXRvckZuW10gfCBudWxsXG4gICkge1xuICAgIHJldHVybiBzdXBlci5zZXRBc3luY1ZhbGlkYXRvcnMobmV3VmFsaWRhdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGVycm9ycyBvbiBhIGZvcm0gY29udHJvbCB3aGVuIHJ1bm5pbmcgdmFsaWRhdGlvbnMgbWFudWFsbHksIHJhdGhlciB0aGFuIGF1dG9tYXRpY2FsbHkuXG4gICAqXG4gICAqIENhbGxpbmcgYHNldEVycm9yc2AgYWxzbyB1cGRhdGVzIHRoZSB2YWxpZGl0eSBvZiB0aGUgcGFyZW50IGNvbnRyb2wuXG4gICAqXG4gICAqICMjIyBNYW51YWxseSBzZXQgdGhlIGVycm9ycyBmb3IgYSBjb250cm9sXG4gICAqXG4gICAqIGBgYHRzXG4gICAqIGNvbnN0IGxvZ2luID0gbmV3IEZvcm1Db250cm9sKCdzb21lTG9naW4nKTtcbiAgICogbG9naW4uc2V0RXJyb3JzKHtcbiAgICogICBub3RVbmlxdWU6IHRydWVcbiAgICogfSk7XG4gICAqXG4gICAqIGV4cGVjdChsb2dpbi52YWxpZCkudG9FcXVhbChmYWxzZSk7XG4gICAqIGV4cGVjdChsb2dpbi5lcnJvcnMpLnRvRXF1YWwoeyBub3RVbmlxdWU6IHRydWUgfSk7XG4gICAqXG4gICAqIGxvZ2luLnNldFZhbHVlKCdzb21lT3RoZXJMb2dpbicpO1xuICAgKlxuICAgKiBleHBlY3QobG9naW4udmFsaWQpLnRvRXF1YWwodHJ1ZSk7XG4gICAqIGBgYFxuICAgKi9cbiAgb3ZlcnJpZGUgc2V0RXJyb3JzKFxuICAgIGVycm9yczogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwsXG4gICAgb3B0czogeyBlbWl0RXZlbnQ/OiBib29sZWFuIH0gPSB7fVxuICApIHtcbiAgICByZXR1cm4gc3VwZXIuc2V0RXJyb3JzKGVycm9ycywgb3B0cyk7XG4gIH1cblxuICAvKipcbiAgICogUmVwb3J0cyBlcnJvciBkYXRhIGZvciB0aGUgY29udHJvbCB3aXRoIHRoZSBnaXZlbiBjb250cm9sTmFtZS5cbiAgICpcbiAgICogQHBhcmFtIGVycm9yQ29kZSBUaGUgY29kZSBvZiB0aGUgZXJyb3IgdG8gY2hlY2tcbiAgICogQHBhcmFtIGNvbnRyb2xOYW1lIEEgY29udHJvbCBuYW1lIHRoYXQgZGVzaWduYXRlcyBob3cgdG8gbW92ZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRyb2xcbiAgICogdG8gdGhlIGNvbnRyb2wgdGhhdCBzaG91bGQgYmUgcXVlcmllZCBmb3IgZXJyb3JzLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSwgZm9yIHRoZSBmb2xsb3dpbmcgYEZvcm1Hcm91cGA6XG4gICAqXG5gYGB0c1xuZm9ybSA9IG5ldyBGb3JtR3JvdXAoe1xuICBhZGRyZXNzOiBuZXcgRm9ybUdyb3VwKHsgc3RyZWV0OiBuZXcgRm9ybUNvbnRyb2woKSB9KVxufSk7XG5gYGBcbiAgICpcbiAgICogVGhlIGNvbnRyb2xOYW1lIHRvIHRoZSAnc3RyZWV0JyBjb250cm9sIGZyb20gdGhlIHJvb3QgZm9ybSB3b3VsZCBiZSAnYWRkcmVzcycgLT4gJ3N0cmVldCcuXG4gICAqXG4gICAqIEl0IGNhbiBiZSBwcm92aWRlZCB0byB0aGlzIG1ldGhvZCBpbiBjb21iaW5hdGlvbiB3aXRoIGBnZXQoKWAgbWV0aG9kOlxuICAgKlxuYGBgdHNcbmZvcm0uZ2V0KCdhZGRyZXNzJykuZ2V0RXJyb3IoJ3NvbWVFcnJvckNvZGUnLCAnc3RyZWV0Jyk7XG5gYGBcbiAgICpcbiAgICogQHJldHVybnMgZXJyb3IgZGF0YSBmb3IgdGhhdCBwYXJ0aWN1bGFyIGVycm9yLiBJZiB0aGUgY29udHJvbCBvciBlcnJvciBpcyBub3QgcHJlc2VudCxcbiAgICogbnVsbCBpcyByZXR1cm5lZC5cbiAgICovXG4gIG92ZXJyaWRlIGdldEVycm9yPFAgZXh0ZW5kcyBTdHJpbmdLZXlzPFY+LCBLIGV4dGVuZHMgU3RyaW5nS2V5czxUPj4oXG4gICAgZXJyb3JDb2RlOiBQLFxuICAgIGNvbnRyb2xOYW1lPzogS1xuICApIHtcbiAgICByZXR1cm4gc3VwZXIuZ2V0RXJyb3IoZXJyb3JDb2RlLCBjb250cm9sTmFtZSkgYXMgVltQXSB8IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmVwb3J0cyB3aGV0aGVyIHRoZSBjb250cm9sIHdpdGggdGhlIGdpdmVuIGNvbnRyb2xOYW1lIGhhcyB0aGUgZXJyb3Igc3BlY2lmaWVkLlxuICAgKlxuICAgKiBAcGFyYW0gZXJyb3JDb2RlIFRoZSBjb2RlIG9mIHRoZSBlcnJvciB0byBjaGVja1xuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgQSBjb250cm9sIG5hbWUgdGhhdCBkZXNpZ25hdGVzIGhvdyB0byBtb3ZlIGZyb20gdGhlIGN1cnJlbnQgY29udHJvbFxuICAgKiB0byB0aGUgY29udHJvbCB0aGF0IHNob3VsZCBiZSBxdWVyaWVkIGZvciBlcnJvcnMuXG4gICAqXG4gICAqIEZvciBleGFtcGxlLCBmb3IgdGhlIGZvbGxvd2luZyBgRm9ybUdyb3VwYDpcbiAgICpcbmBgYHRzXG5mb3JtID0gbmV3IEZvcm1Hcm91cCh7XG4gIGFkZHJlc3M6IG5ldyBGb3JtR3JvdXAoeyBzdHJlZXQ6IG5ldyBGb3JtQ29udHJvbCgpIH0pXG59KTtcbmBgYFxuICAgKlxuICAgKiBUaGUgY29udHJvbE5hbWUgdG8gdGhlICdzdHJlZXQnIGNvbnRyb2wgZnJvbSB0aGUgcm9vdCBmb3JtIHdvdWxkIGJlICdhZGRyZXNzJyAtPiAnc3RyZWV0Jy5cbiAgICpcbiAgICogSXQgY2FuIGJlIHByb3ZpZGVkIHRvIHRoaXMgbWV0aG9kIGluIGNvbWJpbmF0aW9uIHdpdGggYGdldCgpYCBtZXRob2Q6XG5gYGB0c1xuZm9ybS5nZXQoJ2FkZHJlc3MnKS5oYXNFcnJvcignc29tZUVycm9yQ29kZScsICdzdHJlZXQnKTtcbmBgYFxuICAgKlxuICAgKiBJZiBubyBjb250cm9sTmFtZSBpcyBnaXZlbiwgdGhpcyBtZXRob2QgY2hlY2tzIGZvciB0aGUgZXJyb3Igb24gdGhlIGN1cnJlbnQgY29udHJvbC5cbiAgICpcbiAgICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gZXJyb3IgaXMgcHJlc2VudCBpbiB0aGUgY29udHJvbCBhdCB0aGUgZ2l2ZW4gY29udHJvbE5hbWUuXG4gICAqXG4gICAqIElmIHRoZSBjb250cm9sIGlzIG5vdCBwcmVzZW50LCBmYWxzZSBpcyByZXR1cm5lZC5cbiAgICovXG4gIG92ZXJyaWRlIGhhc0Vycm9yPFAgZXh0ZW5kcyBTdHJpbmdLZXlzPFY+LCBLIGV4dGVuZHMgU3RyaW5nS2V5czxUPj4oXG4gICAgZXJyb3JDb2RlOiBQLFxuICAgIGNvbnRyb2xOYW1lPzogS1xuICApIHtcbiAgICByZXR1cm4gc3VwZXIuaGFzRXJyb3IoZXJyb3JDb2RlLCBjb250cm9sTmFtZSk7XG4gIH1cbn1cbiJdfQ==