angular2
Version:
Angular 2 - a web framework for modern web apps
411 lines • 57 kB
JavaScript
import { isPresent, isBlank, normalizeBool } from 'angular2/src/facade/lang';
import { EventEmitter, ObservableWrapper } from 'angular2/src/facade/async';
import { PromiseWrapper } from 'angular2/src/facade/promise';
import { StringMapWrapper, ListWrapper } from 'angular2/src/facade/collection';
/**
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
*/
export const VALID = "VALID";
/**
* Indicates that a Control is invalid, i.e. that an error exists in the input value.
*/
export const INVALID = "INVALID";
/**
* Indicates that a Control is pending, i.e. that async validation is occurring and
* errors are not yet available for the input value.
*/
export const PENDING = "PENDING";
export function isControl(control) {
return control instanceof AbstractControl;
}
function _find(control, path) {
if (isBlank(path))
return null;
if (!(path instanceof Array)) {
path = path.split("/");
}
if (path instanceof Array && ListWrapper.isEmpty(path))
return null;
return path
.reduce((v, name) => {
if (v instanceof ControlGroup) {
return isPresent(v.controls[name]) ? v.controls[name] : null;
}
else if (v instanceof ControlArray) {
var index = name;
return isPresent(v.at(index)) ? v.at(index) : null;
}
else {
return null;
}
}, control);
}
function toObservable(r) {
return PromiseWrapper.isPromise(r) ? ObservableWrapper.fromPromise(r) : r;
}
/**
*
*/
export class AbstractControl {
constructor(validator, asyncValidator) {
this.validator = validator;
this.asyncValidator = asyncValidator;
this._pristine = true;
this._touched = false;
}
get value() { return this._value; }
get status() { return this._status; }
get valid() { return this._status === VALID; }
/**
* Returns the errors of this control.
*/
get errors() { return this._errors; }
get pristine() { return this._pristine; }
get dirty() { return !this.pristine; }
get touched() { return this._touched; }
get untouched() { return !this._touched; }
get valueChanges() { return this._valueChanges; }
get statusChanges() { return this._statusChanges; }
get pending() { return this._status == PENDING; }
markAsTouched() { this._touched = true; }
markAsDirty({ onlySelf } = {}) {
onlySelf = normalizeBool(onlySelf);
this._pristine = false;
if (isPresent(this._parent) && !onlySelf) {
this._parent.markAsDirty({ onlySelf: onlySelf });
}
}
markAsPending({ onlySelf } = {}) {
onlySelf = normalizeBool(onlySelf);
this._status = PENDING;
if (isPresent(this._parent) && !onlySelf) {
this._parent.markAsPending({ onlySelf: onlySelf });
}
}
setParent(parent) { this._parent = parent; }
updateValueAndValidity({ onlySelf, emitEvent } = {}) {
onlySelf = normalizeBool(onlySelf);
emitEvent = isPresent(emitEvent) ? emitEvent : true;
this._updateValue();
this._errors = this._runValidator();
this._status = this._calculateStatus();
if (this._status == VALID || this._status == PENDING) {
this._runAsyncValidator(emitEvent);
}
if (emitEvent) {
ObservableWrapper.callEmit(this._valueChanges, this._value);
ObservableWrapper.callEmit(this._statusChanges, this._status);
}
if (isPresent(this._parent) && !onlySelf) {
this._parent.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent });
}
}
_runValidator() { return isPresent(this.validator) ? this.validator(this) : null; }
_runAsyncValidator(emitEvent) {
if (isPresent(this.asyncValidator)) {
this._status = PENDING;
this._cancelExistingSubscription();
var obs = toObservable(this.asyncValidator(this));
this._asyncValidationSubscription =
ObservableWrapper.subscribe(obs, res => this.setErrors(res, { emitEvent: emitEvent }));
}
}
_cancelExistingSubscription() {
if (isPresent(this._asyncValidationSubscription)) {
ObservableWrapper.dispose(this._asyncValidationSubscription);
}
}
/**
* Sets errors on a control.
*
* This is used when validations are run not automatically, but manually by the user.
*
* Calling `setErrors` will also update the validity of the parent control.
*
* ## Usage
*
* ```
* var login = new Control("someLogin");
* login.setErrors({
* "notUnique": true
* });
*
* expect(login.valid).toEqual(false);
* expect(login.errors).toEqual({"notUnique": true});
*
* login.updateValue("someOtherLogin");
*
* expect(login.valid).toEqual(true);
* ```
*/
setErrors(errors, { emitEvent } = {}) {
emitEvent = isPresent(emitEvent) ? emitEvent : true;
this._errors = errors;
this._status = this._calculateStatus();
if (emitEvent) {
ObservableWrapper.callEmit(this._statusChanges, this._status);
}
if (isPresent(this._parent)) {
this._parent._updateControlsErrors();
}
}
find(path) { return _find(this, path); }
getError(errorCode, path = null) {
var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this;
if (isPresent(control) && isPresent(control._errors)) {
return StringMapWrapper.get(control._errors, errorCode);
}
else {
return null;
}
}
hasError(errorCode, path = null) {
return isPresent(this.getError(errorCode, path));
}
get root() {
let x = this;
while (isPresent(x._parent)) {
x = x._parent;
}
return x;
}
/** @internal */
_updateControlsErrors() {
this._status = this._calculateStatus();
if (isPresent(this._parent)) {
this._parent._updateControlsErrors();
}
}
/** @internal */
_initObservables() {
this._valueChanges = new EventEmitter();
this._statusChanges = new EventEmitter();
}
_calculateStatus() {
if (isPresent(this._errors))
return INVALID;
if (this._anyControlsHaveStatus(PENDING))
return PENDING;
if (this._anyControlsHaveStatus(INVALID))
return INVALID;
return VALID;
}
}
/**
* Defines a part of a form that cannot be divided into other controls. `Control`s have values and
* validation state, which is determined by an optional validation function.
*
* `Control` is one of the three fundamental building blocks used to define forms in Angular, along
* with {@link ControlGroup} and {@link ControlArray}.
*
* ## Usage
*
* By default, a `Control` is created for every `<input>` or other form component.
* With {@link NgFormControl} or {@link NgFormModel} an existing {@link Control} can be
* bound to a DOM element instead. This `Control` can be configured with a custom
* validation function.
*
* ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
*/
export class Control extends AbstractControl {
constructor(value = null, validator = null, asyncValidator = null) {
super(validator, asyncValidator);
this._value = value;
this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
this._initObservables();
}
/**
* Set the value of the control to `value`.
*
* If `onlySelf` is `true`, this change will only affect the validation of this `Control`
* and not its parent component. If `emitEvent` is `true`, this change will cause a
* `valueChanges` event on the `Control` to be emitted. Both of these options default to
* `false`.
*
* If `emitModelToViewChange` is `true`, the view will be notified about the new value
* via an `onChange` event. This is the default behavior if `emitModelToViewChange` is not
* specified.
*/
updateValue(value, { onlySelf, emitEvent, emitModelToViewChange } = {}) {
emitModelToViewChange = isPresent(emitModelToViewChange) ? emitModelToViewChange : true;
this._value = value;
if (isPresent(this._onChange) && emitModelToViewChange)
this._onChange(this._value);
this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent });
}
/**
* @internal
*/
_updateValue() { }
/**
* @internal
*/
_anyControlsHaveStatus(status) { return false; }
/**
* Register a listener for change events.
*/
registerOnChange(fn) { this._onChange = fn; }
}
/**
* Defines a part of a form, of fixed length, that can contain other controls.
*
* A `ControlGroup` aggregates the values and errors of each {@link Control} in the group. Thus, if
* one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control
* changes its value, the entire group changes as well.
*
* `ControlGroup` is one of the three fundamental building blocks used to define forms in Angular,
* along with {@link Control} and {@link ControlArray}. {@link ControlArray} can also contain other
* controls, but is of variable length.
*
* ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
*/
export class ControlGroup extends AbstractControl {
constructor(controls, optionals = null, validator = null, asyncValidator = null) {
super(validator, asyncValidator);
this.controls = controls;
this._optionals = isPresent(optionals) ? optionals : {};
this._initObservables();
this._setParentForControls();
this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
}
/**
* Add a control to this group.
*/
addControl(name, control) {
this.controls[name] = control;
control.setParent(this);
}
/**
* Remove a control from this group.
*/
removeControl(name) { StringMapWrapper.delete(this.controls, name); }
/**
* Mark the named control as non-optional.
*/
include(controlName) {
StringMapWrapper.set(this._optionals, controlName, true);
this.updateValueAndValidity();
}
/**
* Mark the named control as optional.
*/
exclude(controlName) {
StringMapWrapper.set(this._optionals, controlName, false);
this.updateValueAndValidity();
}
/**
* Check whether there is a control with the given name in the group.
*/
contains(controlName) {
var c = StringMapWrapper.contains(this.controls, controlName);
return c && this._included(controlName);
}
/** @internal */
_setParentForControls() {
StringMapWrapper.forEach(this.controls, (control, name) => { control.setParent(this); });
}
/** @internal */
_updateValue() { this._value = this._reduceValue(); }
/** @internal */
_anyControlsHaveStatus(status) {
var res = false;
StringMapWrapper.forEach(this.controls, (control, name) => {
res = res || (this.contains(name) && control.status == status);
});
return res;
}
/** @internal */
_reduceValue() {
return this._reduceChildren({}, (acc, control, name) => {
acc[name] = control.value;
return acc;
});
}
/** @internal */
_reduceChildren(initValue, fn) {
var res = initValue;
StringMapWrapper.forEach(this.controls, (control, name) => {
if (this._included(name)) {
res = fn(res, control, name);
}
});
return res;
}
/** @internal */
_included(controlName) {
var isOptional = StringMapWrapper.contains(this._optionals, controlName);
return !isOptional || StringMapWrapper.get(this._optionals, controlName);
}
}
/**
* Defines a part of a form, of variable length, that can contain other controls.
*
* A `ControlArray` aggregates the values and errors of each {@link Control} in the group. Thus, if
* one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control
* changes its value, the entire group changes as well.
*
* `ControlArray` is one of the three fundamental building blocks used to define forms in Angular,
* along with {@link Control} and {@link ControlGroup}. {@link ControlGroup} can also contain
* other controls, but is of fixed length.
*
* ## Adding or removing controls
*
* To change the controls in the array, use the `push`, `insert`, or `removeAt` methods
* in `ControlArray` itself. These methods ensure the controls are properly tracked in the
* form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
* the `ControlArray` directly, as that will result in strange and unexpected behavior such
* as broken change detection.
*
* ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
*/
export class ControlArray extends AbstractControl {
constructor(controls, validator = null, asyncValidator = null) {
super(validator, asyncValidator);
this.controls = controls;
this._initObservables();
this._setParentForControls();
this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
}
/**
* Get the {@link AbstractControl} at the given `index` in the array.
*/
at(index) { return this.controls[index]; }
/**
* Insert a new {@link AbstractControl} at the end of the array.
*/
push(control) {
this.controls.push(control);
control.setParent(this);
this.updateValueAndValidity();
}
/**
* Insert a new {@link AbstractControl} at the given `index` in the array.
*/
insert(index, control) {
ListWrapper.insert(this.controls, index, control);
control.setParent(this);
this.updateValueAndValidity();
}
/**
* Remove the control at the given `index` in the array.
*/
removeAt(index) {
ListWrapper.removeAt(this.controls, index);
this.updateValueAndValidity();
}
/**
* Length of the control array.
*/
get length() { return this.controls.length; }
/** @internal */
_updateValue() { this._value = this.controls.map((control) => control.value); }
/** @internal */
_anyControlsHaveStatus(status) {
return this.controls.some(c => c.status == status);
}
/** @internal */
_setParentForControls() {
this.controls.forEach((control) => { control.setParent(this); });
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhbmd1bGFyMi9zcmMvY29tbW9uL2Zvcm1zL21vZGVsLnRzIl0sIm5hbWVzIjpbImlzQ29udHJvbCIsIl9maW5kIiwidG9PYnNlcnZhYmxlIiwiQWJzdHJhY3RDb250cm9sIiwiQWJzdHJhY3RDb250cm9sLmNvbnN0cnVjdG9yIiwiQWJzdHJhY3RDb250cm9sLnZhbHVlIiwiQWJzdHJhY3RDb250cm9sLnN0YXR1cyIsIkFic3RyYWN0Q29udHJvbC52YWxpZCIsIkFic3RyYWN0Q29udHJvbC5lcnJvcnMiLCJBYnN0cmFjdENvbnRyb2wucHJpc3RpbmUiLCJBYnN0cmFjdENvbnRyb2wuZGlydHkiLCJBYnN0cmFjdENvbnRyb2wudG91Y2hlZCIsIkFic3RyYWN0Q29udHJvbC51bnRvdWNoZWQiLCJBYnN0cmFjdENvbnRyb2wudmFsdWVDaGFuZ2VzIiwiQWJzdHJhY3RDb250cm9sLnN0YXR1c0NoYW5nZXMiLCJBYnN0cmFjdENvbnRyb2wucGVuZGluZyIsIkFic3RyYWN0Q29udHJvbC5tYXJrQXNUb3VjaGVkIiwiQWJzdHJhY3RDb250cm9sLm1hcmtBc0RpcnR5IiwiQWJzdHJhY3RDb250cm9sLm1hcmtBc1BlbmRpbmciLCJBYnN0cmFjdENvbnRyb2wuc2V0UGFyZW50IiwiQWJzdHJhY3RDb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkiLCJBYnN0cmFjdENvbnRyb2wuX3J1blZhbGlkYXRvciIsIkFic3RyYWN0Q29udHJvbC5fcnVuQXN5bmNWYWxpZGF0b3IiLCJBYnN0cmFjdENvbnRyb2wuX2NhbmNlbEV4aXN0aW5nU3Vic2NyaXB0aW9uIiwiQWJzdHJhY3RDb250cm9sLnNldEVycm9ycyIsIkFic3RyYWN0Q29udHJvbC5maW5kIiwiQWJzdHJhY3RDb250cm9sLmdldEVycm9yIiwiQWJzdHJhY3RDb250cm9sLmhhc0Vycm9yIiwiQWJzdHJhY3RDb250cm9sLnJvb3QiLCJBYnN0cmFjdENvbnRyb2wuX3VwZGF0ZUNvbnRyb2xzRXJyb3JzIiwiQWJzdHJhY3RDb250cm9sLl9pbml0T2JzZXJ2YWJsZXMiLCJBYnN0cmFjdENvbnRyb2wuX2NhbGN1bGF0ZVN0YXR1cyIsIkNvbnRyb2wiLCJDb250cm9sLmNvbnN0cnVjdG9yIiwiQ29udHJvbC51cGRhdGVWYWx1ZSIsIkNvbnRyb2wuX3VwZGF0ZVZhbHVlIiwiQ29udHJvbC5fYW55Q29udHJvbHNIYXZlU3RhdHVzIiwiQ29udHJvbC5yZWdpc3Rlck9uQ2hhbmdlIiwiQ29udHJvbEdyb3VwIiwiQ29udHJvbEdyb3VwLmNvbnN0cnVjdG9yIiwiQ29udHJvbEdyb3VwLmFkZENvbnRyb2wiLCJDb250cm9sR3JvdXAucmVtb3ZlQ29udHJvbCIsIkNvbnRyb2xHcm91cC5pbmNsdWRlIiwiQ29udHJvbEdyb3VwLmV4Y2x1ZGUiLCJDb250cm9sR3JvdXAuY29udGFpbnMiLCJDb250cm9sR3JvdXAuX3NldFBhcmVudEZvckNvbnRyb2xzIiwiQ29udHJvbEdyb3VwLl91cGRhdGVWYWx1ZSIsIkNvbnRyb2xHcm91cC5fYW55Q29udHJvbHNIYXZlU3RhdHVzIiwiQ29udHJvbEdyb3VwLl9yZWR1Y2VWYWx1ZSIsIkNvbnRyb2xHcm91cC5fcmVkdWNlQ2hpbGRyZW4iLCJDb250cm9sR3JvdXAuX2luY2x1ZGVkIiwiQ29udHJvbEFycmF5IiwiQ29udHJvbEFycmF5LmNvbnN0cnVjdG9yIiwiQ29udHJvbEFycmF5LmF0IiwiQ29udHJvbEFycmF5LnB1c2giLCJDb250cm9sQXJyYXkuaW5zZXJ0IiwiQ29udHJvbEFycmF5LnJlbW92ZUF0IiwiQ29udHJvbEFycmF5Lmxlbmd0aCIsIkNvbnRyb2xBcnJheS5fdXBkYXRlVmFsdWUiLCJDb250cm9sQXJyYXkuX2FueUNvbnRyb2xzSGF2ZVN0YXR1cyIsIkNvbnRyb2xBcnJheS5fc2V0UGFyZW50Rm9yQ29udHJvbHMiXSwibWFwcGluZ3MiOiJPQUFPLEVBQWdCLFNBQVMsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFDLE1BQU0sMEJB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QSxDQUFDQSxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxNQUFNQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUVyRE4sZ0JBQWdCQTtJQUNoQkEsWUFBWUEsS0FBV08sSUFBSUEsQ0FBQ0EsTUFBTUEsR0FBR0EsSUFBSUEsQ0FBQ0EsUUFBUUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0EsT0FBT0EsS0FBS0EsT0FBT0EsQ0FBQ0EsS0FBS0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7SUFFckZQLGdCQUFnQkE7SUFDaEJBLHNCQUFzQkEsQ0FBQ0EsTUFBY0E7UUFDbkNRLE1BQU1BLENBQUNBLElBQUlBLENBQUNBLFFBQVFBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLElBQUlBLENBQUNBLENBQUNBLE1BQU1BLElBQUlBLE1BQU1BLENBQUNBLENBQUNBO0lBQ3JEQSxDQUFDQTtJQUdEUixnQkFBZ0JBO0lBQ2hCQSxxQkFBcUJBO1FBQ25CUyxJQUFJQSxDQUFDQSxRQUFRQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxPQUFPQSxPQUFPQSxPQUFPQSxDQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtJQUNuRUEsQ0FBQ0E7QUFDSFQsQ0FBQ0E7QUFBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7U3RyaW5nV3JhcHBlciwgaXNQcmVzZW50LCBpc0JsYW5rLCBub3JtYWxpemVCb29sfSBmcm9tICdhbmd1bGFyMi9zcmMvZmFjYWRlL2xhbmcnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBFdmVudEVtaXR0ZXIsIE9ic2VydmFibGVXcmFwcGVyfSBmcm9tICdhbmd1bGFyMi9zcmMvZmFjYWRlL2FzeW5jJztcbmltcG9ydCB7UHJvbWlzZVdyYXBwZXJ9IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvcHJvbWlzZSc7XG5pbXBvcnQge1N0cmluZ01hcFdyYXBwZXIsIExpc3RXcmFwcGVyfSBmcm9tICdhbmd1bGFyMi9zcmMvZmFjYWRlL2NvbGxlY3Rpb24nO1xuXG4vKipcbiAqIEluZGljYXRlcyB0aGF0IGEgQ29udHJvbCBpcyB2YWxpZCwgaS5lLiB0aGF0IG5vIGVycm9ycyBleGlzdCBpbiB0aGUgaW5wdXQgdmFsdWUuXG4gKi9cbmV4cG9ydCBjb25zdCBWQUxJRCA9IFwiVkFMSURcIjtcblxuLyoqXG4gKiBJbmRpY2F0ZXMgdGhhdCBhIENvbnRyb2wgaXMgaW52YWxpZCwgaS5lLiB0aGF0IGFuIGVycm9yIGV4aXN0cyBpbiB0aGUgaW5wdXQgdmFsdWUuXG4gKi9cbmV4cG9ydCBjb25zdCBJTlZBTElEID0gXCJJTlZBTElEXCI7XG5cbi8qKlxuICogSW5kaWNhdGVzIHRoYXQgYSBDb250cm9sIGlzIHBlbmRpbmcsIGkuZS4gdGhhdCBhc3luYyB2YWxpZGF0aW9uIGlzIG9jY3VycmluZyBhbmRcbiAqIGVycm9ycyBhcmUgbm90IHlldCBhdmFpbGFibGUgZm9yIHRoZSBpbnB1dCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IFBFTkRJTkcgPSBcIlBFTkRJTkdcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ29udHJvbChjb250cm9sOiBPYmplY3QpOiBib29sZWFuIHtcbiAgcmV0dXJuIGNvbnRyb2wgaW5zdGFuY2VvZiBBYnN0cmFjdENvbnRyb2w7XG59XG5cbmZ1bmN0aW9uIF9maW5kKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgcGF0aDogQXJyYXk8c3RyaW5nIHwgbnVtYmVyPnwgc3RyaW5nKSB7XG4gIGlmIChpc0JsYW5rKHBhdGgpKSByZXR1cm4gbnVsbDtcblxuICBpZiAoIShwYXRoIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgcGF0aCA9ICg8c3RyaW5nPnBhdGgpLnNwbGl0KFwiL1wiKTtcbiAgfVxuICBpZiAocGF0aCBpbnN0YW5jZW9mIEFycmF5ICYmIExpc3RXcmFwcGVyLmlzRW1wdHkocGF0aCkpIHJldHVybiBudWxsO1xuXG4gIHJldHVybiAoPEFycmF5PHN0cmluZyB8IG51bWJlcj4+cGF0aClcbiAgICAgIC5yZWR1Y2UoKHYsIG5hbWUpID0+IHtcbiAgICAgICAgaWYgKHYgaW5zdGFuY2VvZiBDb250cm9sR3JvdXApIHtcbiAgICAgICAgICByZXR1cm4gaXNQcmVzZW50KHYuY29udHJvbHNbbmFtZV0pID8gdi5jb250cm9sc1tuYW1lXSA6IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAodiBpbnN0YW5jZW9mIENvbnRyb2xBcnJheSkge1xuICAgICAgICAgIHZhciBpbmRleCA9IDxudW1iZXI+bmFtZTtcbiAgICAgICAgICByZXR1cm4gaXNQcmVzZW50KHYuYXQoaW5kZXgpKSA/IHYuYXQoaW5kZXgpIDogbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSwgY29udHJvbCk7XG59XG5cbmZ1bmN0aW9uIHRvT2JzZXJ2YWJsZShyOiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xuICByZXR1cm4gUHJvbWlzZVdyYXBwZXIuaXNQcm9taXNlKHIpID8gT2JzZXJ2YWJsZVdyYXBwZXIuZnJvbVByb21pc2UocikgOiByO1xufVxuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdENvbnRyb2wge1xuICAvKiogQGludGVybmFsICovXG4gIF92YWx1ZTogYW55O1xuXG4gIHByaXZhdGUgX3ZhbHVlQ2hhbmdlczogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgX3N0YXR1c0NoYW5nZXM6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBwcml2YXRlIF9zdGF0dXM6IHN0cmluZztcbiAgcHJpdmF0ZSBfZXJyb3JzOiB7W2tleTogc3RyaW5nXTogYW55fTtcbiAgcHJpdmF0ZSBfcHJpc3RpbmU6IGJvb2xlYW4gPSB0cnVlO1xuICBwcml2YXRlIF90b3VjaGVkOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgX3BhcmVudDogQ29udHJvbEdyb3VwIHwgQ29udHJvbEFycmF5O1xuICBwcml2YXRlIF9hc3luY1ZhbGlkYXRpb25TdWJzY3JpcHRpb246IGFueTtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgdmFsaWRhdG9yOiBGdW5jdGlvbiwgcHVibGljIGFzeW5jVmFsaWRhdG9yOiBGdW5jdGlvbikge31cblxuICBnZXQgdmFsdWUoKTogYW55IHsgcmV0dXJuIHRoaXMuX3ZhbHVlOyB9XG5cbiAgZ2V0IHN0YXR1cygpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fc3RhdHVzOyB9XG5cbiAgZ2V0IHZhbGlkKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fc3RhdHVzID09PSBWQUxJRDsgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBlcnJvcnMgb2YgdGhpcyBjb250cm9sLlxuICAgKi9cbiAgZ2V0IGVycm9ycygpOiB7W2tleTogc3RyaW5nXTogYW55fSB7IHJldHVybiB0aGlzLl9lcnJvcnM7IH1cblxuICBnZXQgcHJpc3RpbmUoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl9wcmlzdGluZTsgfVxuXG4gIGdldCBkaXJ0eSgpOiBib29sZWFuIHsgcmV0dXJuICF0aGlzLnByaXN0aW5lOyB9XG5cbiAgZ2V0IHRvdWNoZWQoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl90b3VjaGVkOyB9XG5cbiAgZ2V0IHVudG91Y2hlZCgpOiBib29sZWFuIHsgcmV0dXJuICF0aGlzLl90b3VjaGVkOyB9XG5cbiAgZ2V0IHZhbHVlQ2hhbmdlcygpOiBPYnNlcnZhYmxlPGFueT4geyByZXR1cm4gdGhpcy5fdmFsdWVDaGFuZ2VzOyB9XG5cbiAgZ2V0IHN0YXR1c0NoYW5nZXMoKTogT2JzZXJ2YWJsZTxhbnk+IHsgcmV0dXJuIHRoaXMuX3N0YXR1c0NoYW5nZXM7IH1cblxuICBnZXQgcGVuZGluZygpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuX3N0YXR1cyA9PSBQRU5ESU5HOyB9XG5cbiAgbWFya0FzVG91Y2hlZCgpOiB2b2lkIHsgdGhpcy5fdG91Y2hlZCA9IHRydWU7IH1cblxuICBtYXJrQXNEaXJ0eSh7b25seVNlbGZ9OiB7b25seVNlbGY/OiBib29sZWFufSA9IHt9KTogdm9pZCB7XG4gICAgb25seVNlbGYgPSBub3JtYWxpemVCb29sKG9ubHlTZWxmKTtcbiAgICB0aGlzLl9wcmlzdGluZSA9IGZhbHNlO1xuXG4gICAgaWYgKGlzUHJlc2VudCh0aGlzLl9wYXJlbnQpICYmICFvbmx5U2VsZikge1xuICAgICAgdGhpcy5fcGFyZW50Lm1hcmtBc0RpcnR5KHtvbmx5U2VsZjogb25seVNlbGZ9KTtcbiAgICB9XG4gIH1cblxuICBtYXJrQXNQZW5kaW5nKHtvbmx5U2VsZn06IHtvbmx5U2VsZj86IGJvb2xlYW59ID0ge30pOiB2b2lkIHtcbiAgICBvbmx5U2VsZiA9IG5vcm1hbGl6ZUJvb2wob25seVNlbGYpO1xuICAgIHRoaXMuX3N0YXR1cyA9IFBFTkRJTkc7XG5cbiAgICBpZiAoaXNQcmVzZW50KHRoaXMuX3BhcmVudCkgJiYgIW9ubHlTZWxmKSB7XG4gICAgICB0aGlzLl9wYXJlbnQubWFya0FzUGVuZGluZyh7b25seVNlbGY6IG9ubHlTZWxmfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0UGFyZW50KHBhcmVudDogQ29udHJvbEdyb3VwIHwgQ29udHJvbEFycmF5KTogdm9pZCB7IHRoaXMuX3BhcmVudCA9IHBhcmVudDsgfVxuXG4gIHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoXG4gICAgICB7b25seVNlbGYsIGVtaXRFdmVudH06IHtvbmx5U2VsZj86IGJvb2xlYW4sIGVtaXRFdmVudD86IGJvb2xlYW59ID0ge30pOiB2b2lkIHtcbiAgICBvbmx5U2VsZiA9IG5vcm1hbGl6ZUJvb2wob25seVNlbGYpO1xuICAgIGVtaXRFdmVudCA9IGlzUHJlc2VudChlbWl0RXZlbnQpID8gZW1pdEV2ZW50IDogdHJ1ZTtcblxuICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG5cbiAgICB0aGlzLl9lcnJvcnMgPSB0aGlzLl9ydW5WYWxpZGF0b3IoKTtcbiAgICB0aGlzLl9zdGF0dXMgPSB0aGlzLl9jYWxjdWxhdGVTdGF0dXMoKTtcblxuICAgIGlmICh0aGlzLl9zdGF0dXMgPT0gVkFMSUQgfHwgdGhpcy5fc3RhdHVzID09IFBFTkRJTkcpIHtcbiAgICAgIHRoaXMuX3J1bkFzeW5jVmFsaWRhdG9yKGVtaXRFdmVudCk7XG4gICAgfVxuXG4gICAgaWYgKGVtaXRFdmVudCkge1xuICAgICAgT2JzZXJ2YWJsZVdyYXBwZXIuY2FsbEVtaXQodGhpcy5fdmFsdWVDaGFuZ2VzLCB0aGlzLl92YWx1ZSk7XG4gICAgICBPYnNlcnZhYmxlV3JhcHBlci5jYWxsRW1pdCh0aGlzLl9zdGF0dXNDaGFuZ2VzLCB0aGlzLl9zdGF0dXMpO1xuICAgIH1cblxuICAgIGlmIChpc1ByZXNlbnQodGhpcy5fcGFyZW50KSAmJiAhb25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHtvbmx5U2VsZjogb25seVNlbGYsIGVtaXRFdmVudDogZW1pdEV2ZW50fSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfcnVuVmFsaWRhdG9yKCkgeyByZXR1cm4gaXNQcmVzZW50KHRoaXMudmFsaWRhdG9yKSA/IHRoaXMudmFsaWRhdG9yKHRoaXMpIDogbnVsbDsgfVxuXG4gIHByaXZhdGUgX3J1bkFzeW5jVmFsaWRhdG9yKGVtaXRFdmVudDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChpc1ByZXNlbnQodGhpcy5hc3luY1ZhbGlkYXRvcikpIHtcbiAgICAgIHRoaXMuX3N0YXR1cyA9IFBFTkRJTkc7XG4gICAgICB0aGlzLl9jYW5jZWxFeGlzdGluZ1N1YnNjcmlwdGlvbigpO1xuICAgICAgdmFyIG9icyA9IHRvT2JzZXJ2YWJsZSh0aGlzLmFzeW5jVmFsaWRhdG9yKHRoaXMpKTtcbiAgICAgIHRoaXMuX2FzeW5jVmFsaWRhdGlvblN1YnNjcmlwdGlvbiA9XG4gICAgICAgICAgT2JzZXJ2YWJsZVdyYXBwZXIuc3Vic2NyaWJlKG9icywgcmVzID0+IHRoaXMuc2V0RXJyb3JzKHJlcywge2VtaXRFdmVudDogZW1pdEV2ZW50fSkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2NhbmNlbEV4aXN0aW5nU3Vic2NyaXB0aW9uKCk6IHZvaWQge1xuICAgIGlmIChpc1ByZXNlbnQodGhpcy5fYXN5bmNWYWxpZGF0aW9uU3Vic2NyaXB0aW9uKSkge1xuICAgICAgT2JzZXJ2YWJsZVdyYXBwZXIuZGlzcG9zZSh0aGlzLl9hc3luY1ZhbGlkYXRpb25TdWJzY3JpcHRpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGVycm9ycyBvbiBhIGNvbnRyb2wuXG4gICAqXG4gICAqIFRoaXMgaXMgdXNlZCB3aGVuIHZhbGlkYXRpb25zIGFyZSBydW4gbm90IGF1dG9tYXRpY2FsbHksIGJ1dCBtYW51YWxseSBieSB0aGUgdXNlci5cbiAgICpcbiAgICogQ2FsbGluZyBgc2V0RXJyb3JzYCB3aWxsIGFsc28gdXBkYXRlIHRoZSB2YWxpZGl0eSBvZiB0aGUgcGFyZW50IGNvbnRyb2wuXG4gICAqXG4gICAqICMjIFVzYWdlXG4gICAqXG4gICAqIGBgYFxuICAgKiB2YXIgbG9naW4gPSBuZXcgQ29udHJvbChcInNvbWVMb2dpblwiKTtcbiAgICogbG9naW4uc2V0RXJyb3JzKHtcbiAgICogICBcIm5vdFVuaXF1ZVwiOiB0cnVlXG4gICAqIH0pO1xuICAgKlxuICAgKiBleHBlY3QobG9naW4udmFsaWQpLnRvRXF1YWwoZmFsc2UpO1xuICAgKiBleHBlY3QobG9naW4uZXJyb3JzKS50b0VxdWFsKHtcIm5vdFVuaXF1ZVwiOiB0cnVlfSk7XG4gICAqXG4gICAqIGxvZ2luLnVwZGF0ZVZhbHVlKFwic29tZU90aGVyTG9naW5cIik7XG4gICAqXG4gICAqIGV4cGVjdChsb2dpbi52YWxpZCkudG9FcXVhbCh0cnVlKTtcbiAgICogYGBgXG4gICAqL1xuICBzZXRFcnJvcnMoZXJyb3JzOiB7W2tleTogc3RyaW5nXTogYW55fSwge2VtaXRFdmVudH06IHtlbWl0RXZlbnQ/OiBib29sZWFufSA9IHt9KTogdm9pZCB7XG4gICAgZW1pdEV2ZW50ID0gaXNQcmVzZW50KGVtaXRFdmVudCkgPyBlbWl0RXZlbnQgOiB0cnVlO1xuXG4gICAgdGhpcy5fZXJyb3JzID0gZXJyb3JzO1xuICAgIHRoaXMuX3N0YXR1cyA9IHRoaXMuX2NhbGN1bGF0ZVN0YXR1cygpO1xuXG4gICAgaWYgKGVtaXRFdmVudCkge1xuICAgICAgT2JzZXJ2YWJsZVdyYXBwZXIuY2FsbEVtaXQodGhpcy5fc3RhdHVzQ2hhbmdlcywgdGhpcy5fc3RhdHVzKTtcbiAgICB9XG5cbiAgICBpZiAoaXNQcmVzZW50KHRoaXMuX3BhcmVudCkpIHtcbiAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlQ29udHJvbHNFcnJvcnMoKTtcbiAgICB9XG4gIH1cblxuICBmaW5kKHBhdGg6IEFycmF5PHN0cmluZyB8IG51bWJlcj58IHN0cmluZyk6IEFic3RyYWN0Q29udHJvbCB7IHJldHVybiBfZmluZCh0aGlzLCBwYXRoKTsgfVxuXG4gIGdldEVycm9yKGVycm9yQ29kZTogc3RyaW5nLCBwYXRoOiBzdHJpbmdbXSA9IG51bGwpOiBhbnkge1xuICAgIHZhciBjb250cm9sID0gaXNQcmVzZW50KHBhdGgpICYmICFMaXN0V3JhcHBlci5pc0VtcHR5KHBhdGgpID8gdGhpcy5maW5kKHBhdGgpIDogdGhpcztcbiAgICBpZiAoaXNQcmVzZW50KGNvbnRyb2wpICYmIGlzUHJlc2VudChjb250cm9sLl9lcnJvcnMpKSB7XG4gICAgICByZXR1cm4gU3RyaW5nTWFwV3JhcHBlci5nZXQoY29udHJvbC5fZXJyb3JzLCBlcnJvckNvZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBoYXNFcnJvcihlcnJvckNvZGU6IHN0cmluZywgcGF0aDogc3RyaW5nW10gPSBudWxsKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzUHJlc2VudCh0aGlzLmdldEVycm9yKGVycm9yQ29kZSwgcGF0aCkpO1xuICB9XG5cbiAgZ2V0IHJvb3QoKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICBsZXQgeDogQWJzdHJhY3RDb250cm9sID0gdGhpcztcblxuICAgIHdoaWxlIChpc1ByZXNlbnQoeC5fcGFyZW50KSkge1xuICAgICAgeCA9IHguX3BhcmVudDtcbiAgICB9XG5cbiAgICByZXR1cm4geDtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3VwZGF0ZUNvbnRyb2xzRXJyb3JzKCk6IHZvaWQge1xuICAgIHRoaXMuX3N0YXR1cyA9IHRoaXMuX2NhbGN1bGF0ZVN0YXR1cygpO1xuXG4gICAgaWYgKGlzUHJlc2VudCh0aGlzLl9wYXJlbnQpKSB7XG4gICAgICB0aGlzLl9wYXJlbnQuX3VwZGF0ZUNvbnRyb2xzRXJyb3JzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfaW5pdE9ic2VydmFibGVzKCkge1xuICAgIHRoaXMuX3ZhbHVlQ2hhbmdlcyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICB0aGlzLl9zdGF0dXNDaGFuZ2VzID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICB9XG5cblxuICBwcml2YXRlIF9jYWxjdWxhdGVTdGF0dXMoKTogc3RyaW5nIHtcbiAgICBpZiAoaXNQcmVzZW50KHRoaXMuX2Vycm9ycykpIHJldHVybiBJTlZBTElEO1xuICAgIGlmICh0aGlzLl9hbnlDb250cm9sc0hhdmVTdGF0dXMoUEVORElORykpIHJldHVybiBQRU5ESU5HO1xuICAgIGlmICh0aGlzLl9hbnlDb250cm9sc0hhdmVTdGF0dXMoSU5WQUxJRCkpIHJldHVybiBJTlZBTElEO1xuICAgIHJldHVybiBWQUxJRDtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYWJzdHJhY3QgX3VwZGF0ZVZhbHVlKCk6IHZvaWQ7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBhYnN0cmFjdCBfYW55Q29udHJvbHNIYXZlU3RhdHVzKHN0YXR1czogc3RyaW5nKTogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIGEgcGFydCBvZiBhIGZvcm0gdGhhdCBjYW5ub3QgYmUgZGl2aWRlZCBpbnRvIG90aGVyIGNvbnRyb2xzLiBgQ29udHJvbGBzIGhhdmUgdmFsdWVzIGFuZFxuICogdmFsaWRhdGlvbiBzdGF0ZSwgd2hpY2ggaXMgZGV0ZXJtaW5lZCBieSBhbiBvcHRpb25hbCB2YWxpZGF0aW9uIGZ1bmN0aW9uLlxuICpcbiAqIGBDb250cm9sYCBpcyBvbmUgb2YgdGhlIHRocmVlIGZ1bmRhbWVudGFsIGJ1aWxkaW5nIGJsb2NrcyB1c2VkIHRvIGRlZmluZSBmb3JtcyBpbiBBbmd1bGFyLCBhbG9uZ1xuICogd2l0aCB7QGxpbmsgQ29udHJvbEdyb3VwfSBhbmQge0BsaW5rIENvbnRyb2xBcnJheX0uXG4gKlxuICogIyMgVXNhZ2VcbiAqXG4gKiBCeSBkZWZhdWx0LCBhIGBDb250cm9sYCBpcyBjcmVhdGVkIGZvciBldmVyeSBgPGlucHV0PmAgb3Igb3RoZXIgZm9ybSBjb21wb25lbnQuXG4gKiBXaXRoIHtAbGluayBOZ0Zvcm1Db250cm9sfSBvciB7QGxpbmsgTmdGb3JtTW9kZWx9IGFuIGV4aXN0aW5nIHtAbGluayBDb250cm9sfSBjYW4gYmVcbiAqIGJvdW5kIHRvIGEgRE9NIGVsZW1lbnQgaW5zdGVhZC4gVGhpcyBgQ29udHJvbGAgY2FuIGJlIGNvbmZpZ3VyZWQgd2l0aCBhIGN1c3RvbVxuICogdmFsaWRhdGlvbiBmdW5jdGlvbi5cbiAqXG4gKiAjIyMgRXhhbXBsZSAoW2xpdmUgZGVtb10oaHR0cDovL3BsbmtyLmNvL2VkaXQvMjNERVNPcGJObkJwQkhadDFCUjQ/cD1wcmV2aWV3KSlcbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRyb2wgZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2wge1xuICAvKiogQGludGVybmFsICovXG4gIF9vbkNoYW5nZTogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3IodmFsdWU6IGFueSA9IG51bGwsIHZhbGlkYXRvcjogRnVuY3Rpb24gPSBudWxsLCBhc3luY1ZhbGlkYXRvcjogRnVuY3Rpb24gPSBudWxsKSB7XG4gICAgc3VwZXIodmFsaWRhdG9yLCBhc3luY1ZhbGlkYXRvcik7XG4gICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoe29ubHlTZWxmOiB0cnVlLCBlbWl0RXZlbnQ6IGZhbHNlfSk7XG4gICAgdGhpcy5faW5pdE9ic2VydmFibGVzKCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSB2YWx1ZSBvZiB0aGUgY29udHJvbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiBJZiBgb25seVNlbGZgIGlzIGB0cnVlYCwgdGhpcyBjaGFuZ2Ugd2lsbCBvbmx5IGFmZmVjdCB0aGUgdmFsaWRhdGlvbiBvZiB0aGlzIGBDb250cm9sYFxuICAgKiBhbmQgbm90IGl0cyBwYXJlbnQgY29tcG9uZW50LiBJZiBgZW1pdEV2ZW50YCBpcyBgdHJ1ZWAsIHRoaXMgY2hhbmdlIHdpbGwgY2F1c2UgYVxuICAgKiBgdmFsdWVDaGFuZ2VzYCBldmVudCBvbiB0aGUgYENvbnRyb2xgIHRvIGJlIGVtaXR0ZWQuIEJvdGggb2YgdGhlc2Ugb3B0aW9ucyBkZWZhdWx0IHRvXG4gICAqIGBmYWxzZWAuXG4gICAqXG4gICAqIElmIGBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2VgIGlzIGB0cnVlYCwgdGhlIHZpZXcgd2lsbCBiZSBub3RpZmllZCBhYm91dCB0aGUgbmV3IHZhbHVlXG4gICAqIHZpYSBhbiBgb25DaGFuZ2VgIGV2ZW50LiBUaGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIGlmIGBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2VgIGlzIG5vdFxuICAgKiBzcGVjaWZpZWQuXG4gICAqL1xuICB1cGRhdGVWYWx1ZSh2YWx1ZTogYW55LCB7b25seVNlbGYsIGVtaXRFdmVudCwgZW1pdE1vZGVsVG9WaWV3Q2hhbmdlfToge1xuICAgIG9ubHlTZWxmPzogYm9vbGVhbixcbiAgICBlbWl0RXZlbnQ/OiBib29sZWFuLFxuICAgIGVtaXRNb2RlbFRvVmlld0NoYW5nZT86IGJvb2xlYW5cbiAgfSA9IHt9KTogdm9pZCB7XG4gICAgZW1pdE1vZGVsVG9WaWV3Q2hhbmdlID0gaXNQcmVzZW50KGVtaXRNb2RlbFRvVmlld0NoYW5nZSkgPyBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2UgOiB0cnVlO1xuICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XG4gICAgaWYgKGlzUHJlc2VudCh0aGlzLl9vbkNoYW5nZSkgJiYgZW1pdE1vZGVsVG9WaWV3Q2hhbmdlKSB0aGlzLl9vbkNoYW5nZSh0aGlzLl92YWx1ZSk7XG4gICAgdGhpcy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHtvbmx5U2VsZjogb25seVNlbGYsIGVtaXRFdmVudDogZW1pdEV2ZW50fSk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfdXBkYXRlVmFsdWUoKSB7fVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF9hbnlDb250cm9sc0hhdmVTdGF0dXMoc3RhdHVzOiBzdHJpbmcpOiBib29sZWFuIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgbGlzdGVuZXIgZm9yIGNoYW5nZSBldmVudHMuXG4gICAqL1xuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBGdW5jdGlvbik6IHZvaWQgeyB0aGlzLl9vbkNoYW5nZSA9IGZuOyB9XG59XG5cbi8qKlxuICogRGVmaW5lcyBhIHBhcnQgb2YgYSBmb3JtLCBvZiBmaXhlZCBsZW5ndGgsIHRoYXQgY2FuIGNvbnRhaW4gb3RoZXIgY29udHJvbHMuXG4gKlxuICogQSBgQ29udHJvbEdyb3VwYCBhZ2dyZWdhdGVzIHRoZSB2YWx1ZXMgYW5kIGVycm9ycyBvZiBlYWNoIHtAbGluayBDb250cm9sfSBpbiB0aGUgZ3JvdXAuIFRodXMsIGlmXG4gKiBvbmUgb2YgdGhlIGNvbnRyb2xzIGluIGEgZ3JvdXAgaXMgaW52YWxpZCwgdGhlIGVudGlyZSBncm91cCBpcyBpbnZhbGlkLiBTaW1pbGFybHksIGlmIGEgY29udHJvbFxuICogY2hhbmdlcyBpdHMgdmFsdWUsIHRoZSBlbnRpcmUgZ3JvdXAgY2hhbmdlcyBhcyB3ZWxsLlxuICpcbiAqIGBDb250cm9sR3JvdXBgIGlzIG9uZSBvZiB0aGUgdGhyZWUgZnVuZGFtZW50YWwgYnVpbGRpbmcgYmxvY2tzIHVzZWQgdG8gZGVmaW5lIGZvcm1zIGluIEFuZ3VsYXIsXG4gKiBhbG9uZyB3aXRoIHtAbGluayBDb250cm9sfSBhbmQge0BsaW5rIENvbnRyb2xBcnJheX0uIHtAbGluayBDb250cm9sQXJyYXl9IGNhbiBhbHNvIGNvbnRhaW4gb3RoZXJcbiAqIGNvbnRyb2xzLCBidXQgaXMgb2YgdmFyaWFibGUgbGVuZ3RoLlxuICpcbiAqICMjIyBFeGFtcGxlIChbbGl2ZSBkZW1vXShodHRwOi8vcGxua3IuY28vZWRpdC8yM0RFU09wYk5uQnBCSFp0MUJSND9wPXByZXZpZXcpKVxuICovXG5leHBvcnQgY2xhc3MgQ29udHJvbEdyb3VwIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sIHtcbiAgcHJpdmF0ZSBfb3B0aW9uYWxzOiB7W2tleTogc3RyaW5nXTogYm9vbGVhbn07XG5cbiAgY29uc3RydWN0b3IocHVibGljIGNvbnRyb2xzOiB7W2tleTogc3RyaW5nXTogQWJzdHJhY3RDb250cm9sfSxcbiAgICAgICAgICAgICAgb3B0aW9uYWxzOiB7W2tleTogc3RyaW5nXTogYm9vbGVhbn0gPSBudWxsLCB2YWxpZGF0b3I6IEZ1bmN0aW9uID0gbnVsbCxcbiAgICAgICAgICAgICAgYXN5bmNWYWxpZGF0b3I6IEZ1bmN0aW9uID0gbnVsbCkge1xuICAgIHN1cGVyKHZhbGlkYXRvciwgYXN5bmNWYWxpZGF0b3IpO1xuICAgIHRoaXMuX29wdGlvbmFscyA9IGlzUHJlc2VudChvcHRpb25hbHMpID8gb3B0aW9uYWxzIDoge307XG4gICAgdGhpcy5faW5pdE9ic2VydmFibGVzKCk7XG4gICAgdGhpcy5fc2V0UGFyZW50Rm9yQ29udHJvbHMoKTtcbiAgICB0aGlzLnVwZGF0ZVZh