UNPKG

@netgrif/components-core

Version:

Netgrif Application engine frontend core Angular library

554 lines 60.8 kB
import { BehaviorSubject, Subject } from 'rxjs';
import { Validators } from '@angular/forms';
import { distinctUntilChanged, filter, take } from 'rxjs/operators';
import { DEFAULT } from './component';
import { UpdateStrategy } from "./update-strategy";
/**
 * Holds the logic common to all data field Model objects.
 * @typeparam T - type of the `value` property of the data field
 */
export class DataField {
    _stringId;
    _title;
    _behavior;
    _placeholder;
    _description;
    _layout;
    validations;
    _component;
    _parentTaskId;
    _parentCaseId;
    /**
     * @ignore
     * Current value of the data field
     */
    _value;
    /**
     * @ignore
     * Previous value of the data field
     */
    _previousValue;
    /**
     * @ignore
     * Whether the data field Model object was initialized, we push that info into stream
     *
     * See [registerFormControl()]{@link DataField#registerFormControl} for more information.
     */
    _initialized$;
    /**
     * @ignore
     * Whether the field fulfills all of it's validators.
     */
    _valid;
    /**
     * @ignore
     * Whether the `value` of the field changed recently. The flag is cleared when changes are send to backend.
     */
    _changed;
    /**
     * @ignore
     * Data field subscribes this stream.
     * The data field updates it's Validators, validity and enabled/disabled according to it's behavior.
     */
    _update;
    /**
     * @ignore
     * Data field subscribes this stream. When a `true` value is received the data field disables itself.
     * When a `false`value is received data field disables/enables itself based on it's behavior.
     */
    _block;
    /**
     * @ignore
     * When a `true` value is there, the data field is disabled.
     * When a `false` value is received, data field is disabled/enabled based on it's behavior.
     */
    _blocked;
    /**
     * @ignore
     * Data field subscribes this stream. Sets the state of the data field to "touched" or "untouched" (`true`/`false`).
     * Validity of the data field is not checked in an "untouched" state.
     * All fields are touched before a task is finished to check their validity.
     */
    _touch;
    _updateSubscription;
    _blockSubscription;
    _touchSubscription;
    _formControlValueSubscription;
    _myValueSubscription;
    /**
     * @ignore
     * Appearance of dataFields, possible values - outline, standard, fill, legacy
     */
    materialAppearance;
    /**
     * @ignore
     * Whether the field fulfills required validator.
     */
    _validRequired;
    /**
     * Whether invalid field values should be sent to backend.
     */
    _sendInvalidValues = true;
    /**
     * Flag that is set during reverting
     */
    _reverting = false;
    /**
     * Validators resolved from field validations
     */
    _validators;
    /**
     * Stores the last subscription to the [_initialized$]{@link AbstractDataField#_initialized$} Stream, to prevent multiple block events
     * from executing at the same time
     */
    _initializedSubscription;
    /**
     * @ignore
     * Whether the changes from has been requested. The flag is cleared when changes are received from backend.
     */
    _waitingForResponse;
    /**
     * Stores a copy of the fields layout, that can be modified by the layouting algorithm as needed
     * without affecting the base configuration.
     */
    _localLayout;
    /**
     * Listens for layout changes
     */
    layoutSubject;
    /**
     * Reference to rendered element
     * */
    _input;
    /**
     * Reference to form control
     * */
    _formControlRef;
    /**
     * change of component
     * */
    _componentChange$;
    /**
     * @param _stringId - ID of the data field from backend
     * @param _title - displayed title of the data field from backend
     * @param initialValue - initial value of the data field
     * @param _behavior - data field behavior
     * @param _placeholder - placeholder displayed in the datafield
     * @param _description - tooltip of the datafield
     * @param _layout - information regarding the component rendering
     * @param validations
     * @param _component - component data of datafield
     * @param _parentTaskId - stringId of parent task, only defined if field is loaded using {@link TaskRefField}
     * @param _parentCaseId - stringId of parent case, only defined if field is loaded using {@link TaskRefField}
     */
    constructor(_stringId, _title, initialValue, _behavior, _placeholder, _description, _layout, validations, _component, _parentTaskId, _parentCaseId) {
        this._stringId = _stringId;
        this._title = _title;
        this._behavior = _behavior;
        this._placeholder = _placeholder;
        this._description = _description;
        this._layout = _layout;
        this.validations = validations;
        this._component = _component;
        this._parentTaskId = _parentTaskId;
        this._parentCaseId = _parentCaseId;
        this._value = new BehaviorSubject(initialValue);
        this._previousValue = new BehaviorSubject(initialValue);
        this._initialized$ = new BehaviorSubject(false);
        this._valid = true;
        this._changed = false;
        this._waitingForResponse = false;
        this._update = new Subject();
        this._block = new Subject();
        this._touch = new Subject();
        this._componentChange$ = new Subject();
        this._validRequired = true;
        this.layoutSubject = new BehaviorSubject(_layout);
        this.resetLocalLayout();
    }
    get stringId() {
        return this._stringId;
    }
    set title(title) {
        this._title = title;
    }
    get title() {
        return this._title;
    }
    set placeholder(placeholder) {
        this._placeholder = placeholder;
    }
    get placeholder() {
        return this._placeholder;
    }
    set description(desc) {
        this._description = desc;
    }
    get description() {
        return this._description;
    }
    set behavior(behavior) {
        this._behavior = behavior;
    }
    get behavior() {
        return this._behavior;
    }
    get value() {
        return this._value.getValue();
    }
    set value(value) {
        if (!this.valueEquality(this._value.getValue(), value) && !this._reverting) {
            this._changed = true;
            this._waitingForResponse = true;
            this.resolvePrevValue(value);
        }
        this._value.next(value);
        this._reverting = false;
    }
    get parentTaskId() {
        return this._parentTaskId;
    }
    get parentCaseId() {
        return this._parentCaseId;
    }
    get previousValue() {
        return this._previousValue.getValue();
    }
    set previousValue(value) {
        this._previousValue.next(value);
    }
    valueWithoutChange(value) {
        this._changed = false;
        this._value.next(value);
    }
    set layout(layout) {
        this._layout = layout;
        this.layoutSubject.next(layout);
    }
    get layout() {
        return this._layout;
    }
    get localLayout() {
        return this._localLayout;
    }
    get disabled() {
        return !!this._behavior.visible && !this._behavior.editable;
    }
    get initialized() {
        return this._initialized$.value;
    }
    get initialized$() {
        return this._initialized$.asObservable();
    }
    set valid(set) {
        this._valid = set;
    }
    get valid() {
        return this._valid;
    }
    set changed(set) {
        this._changed = set;
    }
    get changed() {
        return this._changed;
    }
    set block(set) {
        if (this._initializedSubscription !== undefined && !this._initializedSubscription.closed) {
            this._initializedSubscription.unsubscribe();
        }
        this._initializedSubscription = this.initialized$.pipe(filter(i => i), take(1)).subscribe(() => {
            this._block.next(set);
        });
    }
    set touch(set) {
        this._touch.next(set);
    }
    get touch$() {
        return this._touch.asObservable();
    }
    get component() {
        return this._component;
    }
    set component(component) {
        this._component = component;
        this._componentChange$.next(component);
    }
    componentChange$() {
        return this._componentChange$.asObservable();
    }
    revertToPreviousValue() {
        this.changed = false;
        this._reverting = true;
        this.value = this.previousValue;
    }
    set validRequired(set) {
        this._validRequired = set;
    }
    get validRequired() {
        return this._validRequired;
    }
    get sendInvalidValues() {
        return this._sendInvalidValues;
    }
    set sendInvalidValues(value) {
        this._sendInvalidValues = value === null || value;
    }
    get waitingForResponse() {
        return this._waitingForResponse;
    }
    set waitingForResponse(value) {
        this._waitingForResponse = value;
    }
    update() {
        this._update.next();
    }
    valueChanges() {
        return this._value.asObservable();
    }
    set reverting(set) {
        this._reverting = set;
    }
    get reverting() {
        return this._reverting;
    }
    focus() {
        if (!!this._input) {
            this._input.nativeElement.focus();
        }
    }
    get input() {
        return this._input;
    }
    set input(value) {
        this._input = value;
    }
    get formControlRef() {
        return this._formControlRef;
    }
    set formControlRef(formControl) {
        this._formControlRef = formControl;
    }
    getUpdateOnStrategy() {
        return UpdateStrategy.BLUR;
    }
    /**
     * This function resolve type of component for HTML
     * @returns type of component in string
     */
    getComponentType() {
        return this.component?.name ?? DEFAULT;
    }
    destroy() {
        this._value.complete();
        this._previousValue.complete();
        this._update.complete();
        this._touch.complete();
        this._block.complete();
        this._initialized$.complete();
        this.layoutSubject.complete();
    }
    registerFormControl(formControl) {
        if (this.initialized) {
            throw new Error('Data field can be initialized only once!'
                + ' Disconnect the previous form control before initializing the data field again!');
        }
        this.formControlRef = formControl;
        formControl.setValidators(this.resolveFormControlValidators());
        this._formControlValueSubscription = formControl.valueChanges.pipe(distinctUntilChanged(this.valueEquality)).subscribe(newValue => {
            this._valid = this._determineFormControlValidity(formControl);
            this.value = newValue;
        });
        this._myValueSubscription = this._value.pipe(distinctUntilChanged(this.valueEquality)).subscribe(newValue => {
            this._valid = this._determineFormControlValidity(formControl);
            formControl.setValue(newValue);
            this.update();
        });
        this.updateFormControlState(formControl);
        this._initialized$.next(true);
        this._changed = false;
        this._waitingForResponse = false;
    }
    disconnectFormControl() {
        if (!this.initialized) {
            return;
        }
        this._initialized$.next(false);
        const subs = [
            this._updateSubscription,
            this._blockSubscription,
            this._touchSubscription,
            this._formControlValueSubscription,
            this._myValueSubscription
        ];
        for (const sub of subs) {
            if (sub) {
                sub.unsubscribe();
            }
        }
    }
    updateFormControlState(formControl) {
        formControl.setValue(this.value);
        this.subscribeToInnerSubjects(formControl);
        this.update();
    }
    subscribeToInnerSubjects(formControl) {
        this._updateSubscription = this._update.subscribe(() => {
            this.validRequired = this.calculateValidity(true, formControl);
            this.valid = this.calculateValidity(false, formControl);
            if (!this._blocked) {
                this.disabled ? formControl.disable() : formControl.enable();
            }
        });
        this._blockSubscription = this._block.subscribe(bool => {
            if (bool) {
                this._blocked = true;
                formControl.disable();
            }
            else {
                this._blocked = false;
                this.disabled ? formControl.disable() : formControl.enable();
            }
        });
        this._touchSubscription = this._touch.subscribe(bool => {
            if (bool) {
                formControl.markAsTouched();
            }
            else {
                formControl.markAsUntouched();
            }
        });
    }
    /**
     * Computes whether the FormControl si valid.
     * @param formControl check form control
     */
    _determineFormControlValidity(formControl) {
        // disabled form controls are marked as invalid as per W3C standard, this solves that problem
        return formControl.disabled || formControl.valid;
    }
    /**
     * Creates Validator objects based on field `behavior`. Only the `required` behavior is resolved by default.
     * Required is resolved as `Validators.required`.
     * If you need to resolve additional Validators or need a different resolution for the `required` Validator override this method.
     *
     * See {@link Behavior} for information about data field behavior.
     *
     * See {@link ValidatorFn} and {@link Validators} for information about Validators.
     *
     * Alternatively see [Form Validation guide]{@link https://angular.io/guide/form-validation#reactive-form-validation} from Angular.
     */
    resolveFormControlValidators() {
        const result = [];
        if (this.behavior.required) {
            result.push(Validators.required);
        }
        if (this.validations) {
            if (this._validators) {
                result.push(...this._validators);
            }
            else {
                this._validators = this.resolveValidations();
                result.push(...this._validators);
            }
        }
        return result;
    }
    replaceValidations(validations) {
        this.clearValidators();
        this.validations = validations;
    }
    clearValidators() {
        this._validators = null;
    }
    resolveValidations() {
        return [];
    }
    /**
     * Determines if two values of the data field are equal.
     *
     * `a === b` equality is used by default. If you want different behavior override this method.
     * @param a - first compared value
     * @param b - second compared value
     */
    valueEquality(a, b) {
        return a === b || (Number.isNaN(a) && Number.isNaN(b));
    }
    /**
     * Updates the state of this data field model object.
     * @param change - object describing the changes - returned from backend
     *
     * Also see {@link ChangedFields}.
     */
    applyChange(change) {
        Object.keys(change).forEach(changedAttribute => {
            switch (changedAttribute) {
                case 'value':
                    this.value = change[changedAttribute];
                    break;
                case 'behavior':
                    Object.assign(this.behavior, change[changedAttribute]);
                    this.update();
                    break;
                default:
                    throw new Error(`Unknown attribute '${changedAttribute}' in change object`);
            }
        });
    }
    resolveAppearance(config) {
        let appearance = 'outline';
        if (this.layout && this.layout.appearance) {
            appearance = this.layout.appearance;
        }
        else {
            const datafieldConfiguration = config.getDatafieldConfiguration();
            if (datafieldConfiguration && datafieldConfiguration.appearance) {
                appearance = datafieldConfiguration.appearance;
            }
        }
        this.materialAppearance = appearance;
        /* Listen for changes of layout in future */
        this.layoutSubject.subscribe(layout => {
            if (this.layout && this.layout.appearance) {
                this.materialAppearance = this.layout.appearance;
            }
        });
    }
    resolvePrevValue(value) {
        if (this._value.getValue() !== undefined
            && this._value.getValue() !== value) {
            this._previousValue.next(this._value.getValue());
        }
    }
    calculateValidity(forValidRequired, formControl) {
        const isDisabled = formControl.disabled;
        if (forValidRequired) {
            formControl.enable();
        }
        formControl.clearValidators();
        if (forValidRequired) {
            formControl.setValidators(this.behavior.required ? [Validators.required] : []);
        }
        else {
            formControl.setValidators(this.resolveFormControlValidators());
        }
        formControl.updateValueAndValidity();
        const validity = this._determineFormControlValidity(formControl);
        isDisabled ? formControl.disable() : formControl.enable();
        return validity;
    }
    isInvalid(formControl) {
        return !formControl.disabled && !formControl.valid && formControl.touched;
    }
    /**
     * Copies the layout settings into the local layout.
     */
    resetLocalLayout() {
        if (this._layout !== undefined) {
            this._localLayout = { ...this._layout };
        }
        else {
            this._localLayout = undefined;
        }
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3QtZGF0YS1maWVsZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy1jb3JlL3NyYy9saWIvZGF0YS1maWVsZHMvbW9kZWxzL2Fic3RyYWN0LWRhdGEtZmllbGQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLGVBQWUsRUFBYyxPQUFPLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFDeEUsT0FBTyxFQUEyQixVQUFVLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUVwRSxPQUFPLEVBQUMsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBR2xFLE9BQU8sRUFBWSxPQUFPLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFHL0MsT0FBTyxFQUFtQixjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUVuRTs7O0dBR0c7QUFDSCxNQUFNLE9BQWdCLFNBQVM7SUFxSUc7SUFBMkI7SUFDM0I7SUFBNkI7SUFDN0I7SUFBK0I7SUFBeUI7SUFDeEQ7SUFBZ0M7SUFBZ0M7SUF2STlGOzs7T0FHRztJQUNPLE1BQU0sQ0FBcUI7SUFDckM7OztPQUdHO0lBQ08sY0FBYyxDQUFxQjtJQUM3Qzs7Ozs7T0FLRztJQUNPLGFBQWEsQ0FBMkI7SUFDbEQ7OztPQUdHO0lBQ0ssTUFBTSxDQUFVO0lBQ3hCOzs7T0FHRztJQUNLLFFBQVEsQ0FBVTtJQUMxQjs7OztPQUlHO0lBQ08sT0FBTyxDQUFnQjtJQUNqQzs7OztPQUlHO0lBQ08sTUFBTSxDQUFtQjtJQUNuQzs7OztPQUlHO0lBQ08sUUFBUSxDQUFVO0lBQzVCOzs7OztPQUtHO0lBQ08sTUFBTSxDQUFtQjtJQUN6QixtQkFBbUIsQ0FBZTtJQUNsQyxrQkFBa0IsQ0FBZTtJQUNqQyxrQkFBa0IsQ0FBZTtJQUNqQyw2QkFBNkIsQ0FBZTtJQUM1QyxvQkFBb0IsQ0FBZTtJQUM3Qzs7O09BR0c7SUFDSSxrQkFBa0IsQ0FBUztJQUNsQzs7O09BR0c7SUFDSyxjQUFjLENBQVU7SUFDaEM7O09BRUc7SUFDSyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7SUFDbEM7O09BRUc7SUFDSyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBRTNCOztPQUVHO0lBQ08sV0FBVyxDQUFxQjtJQUUxQzs7O09BR0c7SUFDTyx3QkFBd0IsQ0FBZTtJQUVqRDs7O09BR0c7SUFDSyxtQkFBbUIsQ0FBVTtJQUVyQzs7O09BR0c7SUFDTyxZQUFZLENBQVM7SUFFL0I7O09BRUc7SUFDTyxhQUFhLENBQTBCO0lBRWpEOztTQUVLO0lBQ0csTUFBTSxDQUFhO0lBRTNCOztTQUVLO0lBQ0csZUFBZSxDQUFjO0lBRXJDOztTQUVLO0lBQ0csaUJBQWlCLENBQXFCO0lBRTlDOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILFlBQThCLFNBQWlCLEVBQVUsTUFBYyxFQUFFLFlBQWUsRUFDMUQsU0FBbUIsRUFBVSxZQUFxQixFQUNsRCxZQUFxQixFQUFVLE9BQWdCLEVBQVMsV0FBK0IsRUFDdkYsVUFBc0IsRUFBVSxhQUFzQixFQUFVLGFBQXNCO1FBSHRGLGNBQVMsR0FBVCxTQUFTLENBQVE7UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ3pDLGNBQVMsR0FBVCxTQUFTLENBQVU7UUFBVSxpQkFBWSxHQUFaLFlBQVksQ0FBUztRQUNsRCxpQkFBWSxHQUFaLFlBQVksQ0FBUztRQUFVLFlBQU8sR0FBUCxPQUFPLENBQVM7UUFBUyxnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFDdkYsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUFVLGtCQUFhLEdBQWIsYUFBYSxDQUFTO1FBQVUsa0JBQWEsR0FBYixhQUFhLENBQVM7UUFDaEgsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLGVBQWUsQ0FBSSxZQUFZLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksZUFBZSxDQUFJLFlBQVksQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQztRQUNqQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUNyQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxPQUFPLEVBQWEsQ0FBQztRQUNsRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksZUFBZSxDQUFTLE9BQU8sQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDUixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLEtBQWE7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksS0FBSztRQUNMLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQsSUFBSSxXQUFXLENBQUMsV0FBbUI7UUFDL0IsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7SUFDcEMsQ0FBQztJQUVELElBQUksV0FBVztRQUNYLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBSSxXQUFXLENBQUMsSUFBWTtRQUN4QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ1gsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzdCLENBQUM7SUFFRCxJQUFJLFFBQVEsQ0FBQyxRQUFrQjtRQUMzQixJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQztJQUM5QixDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzFCLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDTCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLEtBQVE7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUN4RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNoQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDWixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDOUIsQ0FBQztJQUVELElBQUksWUFBWTtRQUNaLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM5QixDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzFDLENBQUM7SUFFRCxJQUFJLGFBQWEsQ0FBQyxLQUFRO1FBQ3RCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTSxrQkFBa0IsQ0FBQyxLQUFRO1FBQzlCLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFJLE1BQU0sQ0FBQyxNQUFjO1FBQ3JCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxJQUFJLE1BQU07UUFDTixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksV0FBVztRQUNYLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1IsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQztJQUNoRSxDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ1gsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztJQUNwQyxDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ1osT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFRCxJQUFJLEtBQUssQ0FBQyxHQUFZO1FBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDTCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVELElBQUksT0FBTyxDQUFDLEdBQVk7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksT0FBTztRQUNQLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN6QixDQUFDO0lBRUQsSUFBSSxLQUFLLENBQUMsR0FBWTtRQUNsQixJQUFJLElBQUksQ0FBQyx3QkFBd0IsS0FBSyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsTUFBTSxFQUFFO1lBQ3RGLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUMvQztRQUNELElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQzNGLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLEdBQVk7UUFDbEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQUksTUFBTTtRQUNOLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzNCLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxTQUFvQjtRQUM5QixJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQztRQUM1QixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFTSxnQkFBZ0I7UUFDbkIsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDakQsQ0FBQztJQUVNLHFCQUFxQjtRQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDcEMsQ0FBQztJQUVELElBQUksYUFBYSxDQUFDLEdBQVk7UUFDMUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxHQUFHLENBQUM7SUFDOUIsQ0FBQztJQUVELElBQUksYUFBYTtRQUNiLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUMvQixDQUFDO0lBRUQsSUFBSSxpQkFBaUI7UUFDakIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUM7SUFDbkMsQ0FBQztJQUVELElBQUksaUJBQWlCLENBQUMsS0FBcUI7UUFDdkMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDO0lBQ3RELENBQUM7SUFFRCxJQUFJLGtCQUFrQjtRQUNsQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztJQUNwQyxDQUFDO0lBRUQsSUFBSSxrQkFBa0IsQ0FBQyxLQUFjO1FBQ2pDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7SUFDckMsQ0FBQztJQUVNLE1BQU07UUFDVCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFTSxZQUFZO1FBQ2YsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3RDLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxHQUFZO1FBQ3RCLElBQUksQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDO0lBQzFCLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDVCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQUVNLEtBQUs7UUFDUixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDckM7SUFDTCxDQUFDO0lBRUQsSUFBSSxLQUFLO1FBQ0wsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxJQUFJLEtBQUssQ0FBQyxLQUFpQjtRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsSUFBSSxjQUFjO1FBQ2QsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxJQUFJLGNBQWMsQ0FBQyxXQUF3QjtRQUN2QyxJQUFJLENBQUMsZUFBZSxHQUFHLFdBQVcsQ0FBQztJQUN2QyxDQUFDO0lBRU0sbUJBQW1CO1FBQ3RCLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQztJQUMvQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksZ0JBQWdCO1FBQ25CLE9BQU8sSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLElBQUksT0FBTyxDQUFDO0lBQzNDLENBQUM7SUFJTSxPQUFPO1FBQ1YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRU0sbUJBQW1CLENBQUMsV0FBd0I7UUFDL0MsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDO2tCQUNwRCxpRkFBaUYsQ0FBQyxDQUFDO1NBQzVGO1FBRUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxXQUFXLENBQUM7UUFDbEMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxDQUFDO1FBRS9ELElBQUksQ0FBQyw2QkFBNkIsR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDOUQsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUMzQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM5RCxJQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDeEMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUMzQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM5RCxXQUFXLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNsQixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0lBQ3JDLENBQUM7SUFFTSxxQkFBcUI7UUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDbkIsT0FBTztTQUNWO1FBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsTUFBTSxJQUFJLEdBQUc7WUFDVCxJQUFJLENBQUMsbUJBQW1CO1lBQ3hCLElBQUksQ0FBQyxrQkFBa0I7WUFDdkIsSUFBSSxDQUFDLGtCQUFrQjtZQUN2QixJQUFJLENBQUMsNkJBQTZCO1lBQ2xDLElBQUksQ0FBQyxvQkFBb0I7U0FDNUIsQ0FBQztRQUNGLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFO1lBQ3BCLElBQUksR0FBRyxFQUFFO2dCQUNMLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQzthQUNyQjtTQUNKO0lBQ0wsQ0FBQztJQUVTLHNCQUFzQixDQUFDLFdBQXdCO1FBQ3JELFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUVTLHdCQUF3QixDQUFDLFdBQXdCO1FBQ3ZELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDbkQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQy9ELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDaEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDaEU7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNuRCxJQUFJLElBQUksRUFBRTtnQkFDTixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztnQkFDckIsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO2FBQ3pCO2lCQUFNO2dCQUNILElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO2dCQUN0QixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUNoRTtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ25ELElBQUksSUFBSSxFQUFFO2dCQUNOLFdBQVcsQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUMvQjtpQkFBTTtnQkFDSCxXQUFXLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDakM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDs7O09BR0c7SUFDTyw2QkFBNkIsQ0FBQyxXQUF3QjtRQUM1RCw2RkFBNkY7UUFDN0YsT0FBTyxXQUFXLENBQUMsUUFBUSxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDTyw0QkFBNEI7UUFDbEMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBRWxCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUU7WUFDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDcEM7UUFFRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDbEIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQ3BDO2lCQUFNO2dCQUNILElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBQzdDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDcEM7U0FDSjtRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFTSxrQkFBa0IsQ0FBQyxXQUE4QjtRQUNwRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDbkMsQ0FBQztJQUVNLGVBQWU7UUFDbEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDNUIsQ0FBQztJQUVTLGtCQUFrQjtRQUN4QixPQUFPLEVBQUUsQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDTyxhQUFhLENBQUMsQ0FBSSxFQUFFLENBQUk7UUFDOUIsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksV0FBVyxDQUFDLE1BQWM7UUFDN0IsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtZQUMzQyxRQUFRLGdCQUFnQixFQUFFO2dCQUN0QixLQUFLLE9BQU87b0JBQ1IsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztvQkFDdEMsTUFBTTtnQkFDVixLQUFLLFVBQVU7b0JBQ1gsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDZCxNQUFNO2dCQUNWO29CQUNJLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLGdCQUFnQixvQkFBb0IsQ0FBQyxDQUFDO2FBQ25GO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0saUJBQWlCLENBQUMsTUFBNEI7UUFDakQsSUFBSSxVQUFVLEdBQUcsU0FBUyxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRTtZQUN2QyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7U0FDdkM7YUFBTTtZQUNILE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLHlCQUF5QixFQUFFLENBQUM7WUFDbEUsSUFBSSxzQkFBc0IsSUFBSSxzQkFBc0IsQ0FBQyxVQUFVLEVBQUU7Z0JBQzdELFVBQVUsR0FBRyxzQkFBc0IsQ0FBQyxVQUFVLENBQUM7YUFDbEQ7U0FDSjtRQUNELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxVQUFVLENBQUM7UUFFckMsNENBQTRDO1FBQzVDLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ2xDLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRTtnQkFDdkMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO2FBQ3BEO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsS0FBUTtRQUM1QixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssU0FBUztlQUNqQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxLQUFLLEtBQUssRUFBRTtZQUNyQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7U0FDcEQ7SUFDTCxDQUFDO0lBRVMsaUJBQWlCLENBQUMsZ0JBQXlCLEVBQUUsV0FBd0I7UUFDM0UsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQztRQUN4QyxJQUFJLGdCQUFnQixFQUFFO1lBQ2xCLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztTQUN4QjtRQUNELFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM5QixJQUFJLGdCQUFnQixFQUFFO1lBQ2xCLFdBQVcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUNsRjthQUFNO1lBQ0gsV0FBVyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxDQUFDO1NBQ2xFO1FBQ0QsV0FBVyxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDckMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pFLFVBQVUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDMUQsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQztJQUVNLFNBQVMsQ0FBQyxXQUF3QjtRQUNyQyxPQUFPLENBQUMsV0FBVyxDQUFDLFFBQVEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQztJQUM5RSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxnQkFBZ0I7UUFDbkIsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRTtZQUM1QixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFDLENBQUM7U0FDekM7YUFBTTtZQUNILElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO1NBQ2pDO0lBQ0wsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtCZWhhdmlvcn0gZnJvbSAnLi9iZWhhdmlvcic7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7Rm9ybUNvbnRyb2wsIFZhbGlkYXRvckZuLCBWYWxpZGF0b3JzfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge0NoYW5nZX0gZnJvbSAnLi9jaGFuZ2VkLWZpZWxkcyc7XG5pbXBvcnQge2Rpc3RpbmN0VW50aWxDaGFuZ2VkLCBmaWx0ZXIsIHRha2V9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7TGF5b3V0fSBmcm9tICcuL2xheW91dCc7XG5pbXBvcnQge0NvbmZpZ3VyYXRpb25TZXJ2aWNlfSBmcm9tICcuLi8uLi9jb25maWd1cmF0aW9uL2NvbmZpZ3VyYXRpb24uc2VydmljZSc7XG5pbXBvcnQge0NvbXBvbmVudCwgREVGQVVMVH0gZnJvbSAnLi9jb21wb25lbnQnO1xuaW1wb3J0IHtWYWxpZGF0aW9ufSBmcm9tICcuL3ZhbGlkYXRpb24nO1xuaW1wb3J0IHtFbGVtZW50UmVmfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtVcGRhdGVPblN0cmF0ZWd5LCBVcGRhdGVTdHJhdGVneX0gZnJvbSBcIi4vdXBkYXRlLXN0cmF0ZWd5XCI7XG5cbi8qKlxuICogSG9sZHMgdGhlIGxvZ2ljIGNvbW1vbiB0byBhbGwgZGF0YSBmaWVsZCBNb2RlbCBvYmplY3RzLlxuICogQHR5cGVwYXJhbSBUIC0gdHlwZSBvZiB0aGUgYHZhbHVlYCBwcm9wZXJ0eSBvZiB0aGUgZGF0YSBmaWVsZFxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRGF0YUZpZWxkPFQ+IHtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogQ3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0YSBmaWVsZFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBfdmFsdWU6IEJlaGF2aW9yU3ViamVjdDxUPjtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIGRhdGEgZmllbGRcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX3ByZXZpb3VzVmFsdWU6IEJlaGF2aW9yU3ViamVjdDxUPjtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogV2hldGhlciB0aGUgZGF0YSBmaWVsZCBNb2RlbCBvYmplY3Qgd2FzIGluaXRpYWxpemVkLCB3ZSBwdXNoIHRoYXQgaW5mbyBpbnRvIHN0cmVhbVxuICAgICAqXG4gICAgICogU2VlIFtyZWdpc3RlckZvcm1Db250cm9sKClde0BsaW5rIERhdGFGaWVsZCNyZWdpc3RlckZvcm1Db250cm9sfSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2luaXRpYWxpemVkJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+O1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBXaGV0aGVyIHRoZSBmaWVsZCBmdWxmaWxscyBhbGwgb2YgaXQncyB2YWxpZGF0b3JzLlxuICAgICAqL1xuICAgIHByaXZhdGUgX3ZhbGlkOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBXaGV0aGVyIHRoZSBgdmFsdWVgIG9mIHRoZSBmaWVsZCBjaGFuZ2VkIHJlY2VudGx5LiBUaGUgZmxhZyBpcyBjbGVhcmVkIHdoZW4gY2hhbmdlcyBhcmUgc2VuZCB0byBiYWNrZW5kLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2NoYW5nZWQ6IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIERhdGEgZmllbGQgc3Vic2NyaWJlcyB0aGlzIHN0cmVhbS5cbiAgICAgKiBUaGUgZGF0YSBmaWVsZCB1cGRhdGVzIGl0J3MgVmFsaWRhdG9ycywgdmFsaWRpdHkgYW5kIGVuYWJsZWQvZGlzYWJsZWQgYWNjb3JkaW5nIHRvIGl0J3MgYmVoYXZpb3IuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF91cGRhdGU6IFN1YmplY3Q8dm9pZD47XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIERhdGEgZmllbGQgc3Vic2NyaWJlcyB0aGlzIHN0cmVhbS4gV2hlbiBhIGB0cnVlYCB2YWx1ZSBpcyByZWNlaXZlZCB0aGUgZGF0YSBmaWVsZCBkaXNhYmxlcyBpdHNlbGYuXG4gICAgICogV2hlbiBhIGBmYWxzZWB2YWx1ZSBpcyByZWNlaXZlZCBkYXRhIGZpZWxkIGRpc2FibGVzL2VuYWJsZXMgaXRzZWxmIGJhc2VkIG9uIGl0J3MgYmVoYXZpb3IuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF9ibG9jazogU3ViamVjdDxib29sZWFuPjtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogV2hlbiBhIGB0cnVlYCB2YWx1ZSBpcyB0aGVyZSwgdGhlIGRhdGEgZmllbGQgaXMgZGlzYWJsZWQuXG4gICAgICogV2hlbiBhIGBmYWxzZWAgdmFsdWUgaXMgcmVjZWl2ZWQsIGRhdGEgZmllbGQgaXMgZGlzYWJsZWQvZW5hYmxlZCBiYXNlZCBvbiBpdCdzIGJlaGF2aW9yLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBfYmxvY2tlZDogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogRGF0YSBmaWVsZCBzdWJzY3JpYmVzIHRoaXMgc3RyZWFtLiBTZXRzIHRoZSBzdGF0ZSBvZiB0aGUgZGF0YSBmaWVsZCB0byBcInRvdWNoZWRcIiBvciBcInVudG91Y2hlZFwiIChgdHJ1ZWAvYGZhbHNlYCkuXG4gICAgICogVmFsaWRpdHkgb2YgdGhlIGRhdGEgZmllbGQgaXMgbm90IGNoZWNrZWQgaW4gYW4gXCJ1bnRvdWNoZWRcIiBzdGF0ZS5cbiAgICAgKiBBbGwgZmllbGRzIGFyZSB0b3VjaGVkIGJlZm9yZSBhIHRhc2sgaXMgZmluaXNoZWQgdG8gY2hlY2sgdGhlaXIgdmFsaWRpdHkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF90b3VjaDogU3ViamVjdDxib29sZWFuPjtcbiAgICBwcm90ZWN0ZWQgX3VwZGF0ZVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICAgIHByb3RlY3RlZCBfYmxvY2tTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgICBwcm90ZWN0ZWQgX3RvdWNoU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gICAgcHJvdGVjdGVkIF9mb3JtQ29udHJvbFZhbHVlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gICAgcHJvdGVjdGVkIF9teVZhbHVlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIEFwcGVhcmFuY2Ugb2YgZGF0YUZpZWxkcywgcG9zc2libGUgdmFsdWVzIC0gb3V0bGluZSwgc3RhbmRhcmQsIGZpbGwsIGxlZ2FjeVxuICAgICAqL1xuICAgIHB1YmxpYyBtYXRlcmlhbEFwcGVhcmFuY2U6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogV2hldGhlciB0aGUgZmllbGQgZnVsZmlsbHMgcmVxdWlyZWQgdmFsaWRhdG9yLlxuICAgICAqL1xuICAgIHByaXZhdGUgX3ZhbGlkUmVxdWlyZWQ6IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciBpbnZhbGlkIGZpZWxkIHZhbHVlcyBzaG91bGQgYmUgc2VudCB0byBiYWNrZW5kLlxuICAgICAqL1xuICAgIHByaXZhdGUgX3NlbmRJbnZhbGlkVmFsdWVzID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBGbGFnIHRoYXQgaXMgc2V0IGR1cmluZyByZXZlcnRpbmdcbiAgICAgKi9cbiAgICBwcml2YXRlIF9yZXZlcnRpbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFZhbGlkYXRvcnMgcmVzb2x2ZWQgZnJvbSBmaWVsZCB2YWxpZGF0aW9uc1xuICAgICAqL1xuICAgIHByb3RlY3RlZCBfdmFsaWRhdG9yczogQXJyYXk8VmFsaWRhdG9yRm4+O1xuXG4gICAgLyoqXG4gICAgICogU3RvcmVzIHRoZSBsYXN0IHN1YnNjcmlwdGlvbiB0byB0aGUgW19pbml0aWFsaXplZCRde0BsaW5rIEFic3RyYWN0RGF0YUZpZWxkI19pbml0aWFsaXplZCR9IFN0cmVhbSwgdG8gcHJldmVudCBtdWx0aXBsZSBibG9jayBldmVudHNcbiAgICAgKiBmcm9tIGV4ZWN1dGluZyBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICovXG4gICAgcHJvdGVjdGVkIF9pbml0aWFsaXplZFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIFdoZXRoZXIgdGhlIGNoYW5nZXMgZnJvbSBoYXMgYmVlbiByZXF1ZXN0ZWQuIFRoZSBmbGFnIGlzIGNsZWFyZWQgd2hlbiBjaGFuZ2VzIGFyZSByZWNlaXZlZCBmcm9tIGJhY2tlbmQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBfd2FpdGluZ0ZvclJlc3BvbnNlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogU3RvcmVzIGEgY29weSBvZiB0aGUgZmllbGRzIGxheW91dCwgdGhhdCBjYW4gYmUgbW9kaWZpZWQgYnkgdGhlIGxheW91dGluZyBhbGdvcml0aG0gYXMgbmVlZGVkXG4gICAgICogd2l0aG91dCBhZmZlY3RpbmcgdGhlIGJhc2UgY29uZmlndXJhdGlvbi5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2xvY2FsTGF5b3V0OiBMYXlvdXQ7XG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW5zIGZvciBsYXlvdXQgY2hhbmdlc1xuICAgICAqL1xuICAgIHByb3RlY3RlZCBsYXlvdXRTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8TGF5b3V0PjtcblxuICAgIC8qKlxuICAgICAqIFJlZmVyZW5jZSB0byByZW5kZXJlZCBlbGVtZW50XG4gICAgICogKi9cbiAgICBwcml2YXRlIF9pbnB1dDogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIFJlZmVyZW5jZSB0byBmb3JtIGNvbnRyb2xcbiAgICAgKiAqL1xuICAgIHByaXZhdGUgX2Zvcm1Db250cm9sUmVmOiBGb3JtQ29udHJvbDtcblxuICAgIC8qKlxuICAgICAqIGNoYW5nZSBvZiBjb21wb25lbnRcbiAgICAgKiAqL1xuICAgIHByaXZhdGUgX2NvbXBvbmVudENoYW5nZSQ6IFN1YmplY3Q8Q29tcG9uZW50PjtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBfc3RyaW5nSWQgLSBJRCBvZiB0aGUgZGF0YSBmaWVsZCBmcm9tIGJhY2tlbmRcbiAgICAgKiBAcGFyYW0gX3RpdGxlIC0gZGlzcGxheWVkIHRpdGxlIG9mIHRoZSBkYXRhIGZpZWxkIGZyb20gYmFja2VuZFxuICAgICAqIEBwYXJhbSBpbml0aWFsVmFsdWUgLSBpbml0aWFsIHZhbHVlIG9mIHRoZSBkYXRhIGZpZWxkXG4gICAgICogQHBhcmFtIF9iZWhhdmlvciAtIGRhdGEgZmllbGQgYmVoYXZpb3JcbiAgICAgKiBAcGFyYW0gX3BsYWNlaG9sZGVyIC0gcGxhY2Vob2xkZXIgZGlzcGxheWVkIGluIHRoZSBkYXRhZmllbGRcbiAgICAgKiBAcGFyYW0gX2Rlc2NyaXB0aW9uIC0gdG9vbHRpcCBvZiB0aGUgZGF0YWZpZWxkXG4gICAgICogQHBhcmFtIF9sYXlvdXQgLSBpbmZvcm1hdGlvbiByZWdhcmRpbmcgdGhlIGNvbXBvbmVudCByZW5kZXJpbmdcbiAgICAgKiBAcGFyYW0gdmFsaWRhdGlvbnNcbiAgICAgKiBAcGFyYW0gX2NvbXBvbmVudCAtIGNvbXBvbmVudCBkYXRhIG9mIGRhdGFmaWVsZFxuICAgICAqIEBwYXJhbSBfcGFyZW50VGFza0lkIC0gc3RyaW5nSWQgb2YgcGFyZW50IHRhc2ssIG9ubHkgZGVmaW5lZCBpZiBmaWVsZCBpcyBsb2FkZWQgdXNpbmcge0BsaW5rIFRhc2tSZWZGaWVsZH1cbiAgICAgKiBAcGFyYW0gX3BhcmVudENhc2VJZCAtIHN0cmluZ0lkIG9mIHBhcmVudCBjYXNlLCBvbmx5IGRlZmluZWQgaWYgZmllbGQgaXMgbG9hZGVkIHVzaW5nIHtAbGluayBUYXNrUmVmRmllbGR9XG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByaXZhdGUgX3N0cmluZ0lkOiBzdHJpbmcsIHByaXZhdGUgX3RpdGxlOiBzdHJpbmcsIGluaXRpYWxWYWx1ZTogVCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSBfYmVoYXZpb3I6IEJlaGF2aW9yLCBwcml2YXRlIF9wbGFjZWhvbGRlcj86IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSBfZGVzY3JpcHRpb24/OiBzdHJpbmcsIHByaXZhdGUgX2xheW91dD86IExheW91dCwgcHVibGljIHZhbGlkYXRpb25zPzogQXJyYXk8VmFsaWRhdGlvbj4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgX2NvbXBvbmVudD86IENvbXBvbmVudCwgcHJpdmF0ZSBfcGFyZW50VGFza0lkPzogc3RyaW5nLCBwcml2YXRlIF9wYXJlbnRDYXNlSWQ/OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fdmFsdWUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFQ+KGluaXRpYWxWYWx1ZSk7XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzVmFsdWUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFQ+KGluaXRpYWxWYWx1ZSk7XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICAgICAgICB0aGlzLl92YWxpZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX2NoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fd2FpdGluZ0ZvclJlc3BvbnNlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3VwZGF0ZSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gICAgICAgIHRoaXMuX2Jsb2NrID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgICAgICAgdGhpcy5fdG91Y2ggPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgICAgICB0aGlzLl9jb21wb25lbnRDaGFuZ2UkID0gbmV3IFN1YmplY3Q8Q29tcG9uZW50PigpO1xuICAgICAgICB0aGlzLl92YWxpZFJlcXVpcmVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5sYXlvdXRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxMYXlvdXQ+KF9sYXlvdXQpO1xuICAgICAgICB0aGlzLnJlc2V0TG9jYWxMYXlvdXQoKTtcbiAgICB9XG5cbiAgICBnZXQgc3RyaW5nSWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0cmluZ0lkO1xuICAgIH1cblxuICAgIHNldCB0aXRsZSh0aXRsZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX3RpdGxlID0gdGl0bGU7XG4gICAgfVxuXG4gICAgZ2V0IHRpdGxlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aXRsZTtcbiAgICB9XG5cbiAgICBzZXQgcGxhY2Vob2xkZXIocGxhY2Vob2xkZXI6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9wbGFjZWhvbGRlciA9IHBsYWNlaG9sZGVyO1xuICAgIH1cblxuICAgIGdldCBwbGFjZWhvbGRlcigpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxhY2Vob2xkZXI7XG4gICAgfVxuXG4gICAgc2V0IGRlc2NyaXB0aW9uKGRlc2M6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9kZXNjcmlwdGlvbiA9IGRlc2M7XG4gICAgfVxuXG4gICAgZ2V0IGRlc2NyaXB0aW9uKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZXNjcmlwdGlvbjtcbiAgICB9XG5cbiAgICBzZXQgYmVoYXZpb3IoYmVoYXZpb3I6IEJlaGF2aW9yKSB7XG4gICAgICAgIHRoaXMuX2JlaGF2aW9yID0gYmVoYXZpb3I7XG4gICAgfVxuXG4gICAgZ2V0IGJlaGF2aW9yKCk6IEJlaGF2aW9yIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JlaGF2aW9yO1xuICAgIH1cblxuICAgIGdldCB2YWx1ZSgpOiBUIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLmdldFZhbHVlKCk7XG4gICAgfVxuXG4gICAgc2V0IHZhbHVlKHZhbHVlOiBUKSB7XG4gICAgICAgIGlmICghdGhpcy52YWx1ZUVxdWFsaXR5KHRoaXMuX3ZhbHVlLmdldFZhbHVlKCksIHZhbHVlKSAmJiAhdGhpcy5fcmV2ZXJ0aW5nKSB7XG4gICAgICAgICAgICB0aGlzLl9jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3dhaXRpbmdGb3JSZXNwb25zZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnJlc29sdmVQcmV2VmFsdWUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3ZhbHVlLm5leHQodmFsdWUpO1xuICAgICAgICB0aGlzLl9yZXZlcnRpbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXQgcGFyZW50VGFza0lkKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJlbnRUYXNrSWQ7XG4gICAgfVxuXG4gICAgZ2V0IHBhcmVudENhc2VJZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyZW50Q2FzZUlkO1xuICAgIH1cblxuICAgIGdldCBwcmV2aW91c1ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJldmlvdXNWYWx1ZS5nZXRWYWx1ZSgpO1xuICAgIH1cblxuICAgIHNldCBwcmV2aW91c1ZhbHVlKHZhbHVlOiBUKSB7XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzVmFsdWUubmV4dCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIHZhbHVlV2l0aG91dENoYW5nZSh2YWx1ZTogVCkge1xuICAgICAgICB0aGlzLl9jaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3ZhbHVlLm5leHQodmFsdWUpO1xuICAgIH1cblxuICAgIHNldCBsYXlvdXQobGF5b3V0OiBMYXlvdXQpIHtcbiAgICAgICAgdGhpcy5fbGF5b3V0ID0gbGF5b3V0O1xuICAgICAgICB0aGlzLmxheW91dFN1YmplY3QubmV4dChsYXlvdXQpO1xuICAgIH1cblxuICAgIGdldCBsYXlvdXQoKTogTGF5b3V0IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xheW91dDtcbiAgICB9XG5cbiAgICBnZXQgbG9jYWxMYXlvdXQoKTogTGF5b3V0IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvY2FsTGF5b3V0O1xuICAgIH1cblxuICAgIGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fYmVoYXZpb3IudmlzaWJsZSAmJiAhdGhpcy5fYmVoYXZpb3IuZWRpdGFibGU7XG4gICAgfVxuXG4gICAgZ2V0IGluaXRpYWxpemVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbGl6ZWQkLnZhbHVlO1xuICAgIH1cblxuICAgIGdldCBpbml0aWFsaXplZCQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pbml0aWFsaXplZCQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgc2V0IHZhbGlkKHNldDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl92YWxpZCA9IHNldDtcbiAgICB9XG5cbiAgICBnZXQgdmFsaWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZDtcbiAgICB9XG5cbiAgICBzZXQgY2hhbmdlZChzZXQ6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fY2hhbmdlZCA9IHNldDtcbiAgICB9XG5cbiAgICBnZXQgY2hhbmdlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NoYW5nZWQ7XG4gICAgfVxuXG4gICAgc2V0IGJsb2NrKHNldDogYm9vbGVhbikge1xuICAgICAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWRTdWJzY3JpcHRpb24gIT09IHVuZGVmaW5lZCAmJiAhdGhpcy5faW5pdGlhbGl6ZWRTdWJzY3JpcHRpb24uY2xvc2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkU3Vic2NyaXB0aW9uID0gdGhpcy5pbml0aWFsaXplZCQucGlwZShmaWx0ZXIoaSA9PiBpKSwgdGFrZSgxKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2Jsb2NrLm5leHQoc2V0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2V0IHRvdWNoKHNldDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl90b3VjaC5uZXh0KHNldCk7XG4gICAgfVxuXG4gICAgZ2V0IHRvdWNoJCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvdWNoLmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIGdldCBjb21wb25lbnQoKTogQ29tcG9uZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXBvbmVudDtcbiAgICB9XG5cbiAgICBzZXQgY29tcG9uZW50KGNvbXBvbmVudDogQ29tcG9uZW50KSB7XG4gICAgICAgIHRoaXMuX2NvbXBvbmVudCA9IGNvbXBvbmVudDtcbiAgICAgICAgdGhpcy5fY29tcG9uZW50Q2hhbmdlJC5uZXh0KGNvbXBvbmVudCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudENoYW5nZSQoKTogT2JzZXJ2YWJsZTxDb21wb25lbnQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXBvbmVudENoYW5nZSQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHJldmVydFRvUHJldmlvdXNWYWx1ZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3JldmVydGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnByZXZpb3VzVmFsdWU7XG4gICAgfVxuXG4gICAgc2V0IHZhbGlkUmVxdWlyZWQoc2V0OiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX3ZhbGlkUmVxdWlyZWQgPSBzZXQ7XG4gICAgfVxuXG4gICAgZ2V0IHZhbGlkUmVxdWlyZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZFJlcXVpcmVkO1xuICAgIH1cblxuICAgIGdldCBzZW5kSW52YWxpZFZhbHVlcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbmRJbnZhbGlkVmFsdWVzO1xuICAgIH1cblxuICAgIHNldCBzZW5kSW52YWxpZFZhbHVlcyh2YWx1ZTogYm9vbGVhbiB8IG51bGwpIHtcbiAgICAgICAgdGhpcy5fc2VuZEludmFsaWRWYWx1ZXMgPSB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZTtcbiAgICB9XG5cbiAgICBnZXQgd2FpdGluZ0ZvclJlc3BvbnNlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fd2FpdGluZ0ZvclJlc3BvbnNlO1xuICAgIH1cblxuICAgIHNldCB3YWl0aW5nRm9yUmVzcG9uc2UodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fd2FpdGluZ0ZvclJlc3BvbnNlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlLm5leHQoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsdWVDaGFuZ2VzKCk6IE9ic2VydmFibGU8VD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWUuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgc2V0IHJldmVydGluZyhzZXQ6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fcmV2ZXJ0aW5nID0gc2V0O1xuICAgIH1cblxuICAgIGdldCByZXZlcnRpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXZlcnRpbmc7XG4gICAgfVxuXG4gICAgcHVibGljIGZvY3VzKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLl9pbnB1dCkge1xuICAgICAgICAgICAgdGhpcy5faW5wdXQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IGlucHV0KCk6IEVsZW1lbnRSZWYge1xuICAgICAgICByZXR1cm4gdGhpcy5faW5wdXQ7XG4gICAgfVxuXG4gICAgc2V0IGlucHV0KHZhbHVlOiBFbGVtZW50UmVmKSB7XG4gICAgICAgIHRoaXMuX2lucHV0ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IGZvcm1Db250cm9sUmVmKCk6IEZvcm1Db250cm9sIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Zvcm1Db250cm9sUmVmO1xuICAgIH1cblxuICAgIHNldCBmb3JtQ29udHJvbFJlZihmb3JtQ29udHJvbDogRm9ybUNvbnRyb2wpIHtcbiAgICAgICAgdGhpcy5fZm9ybUNvbnRyb2xSZWYgPSBmb3JtQ29udHJvbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VXBkYXRlT25TdHJhdGVneSgpOiBVcGRhdGVPblN0cmF0ZWd5IHtcbiAgICAgICAgcmV0dXJuIFVwZGF0ZVN0cmF0ZWd5LkJMVVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiByZXNvbHZlIHR5cGUgb2YgY29tcG9uZW50IGZvciBIVE1MXG4gICAgICogQHJldHVybnMgdHlwZSBvZiBjb21wb25lbnQgaW4gc3RyaW5nXG4gICAgICovXG4gICAgcHVibGljIGdldENvbXBvbmVudFR5cGUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcG9uZW50Py5uYW1lID8/IERFRkFVTFQ7XG4gICAgfVxuXG4gICAgcHVibGljIGFic3RyYWN0IGdldFR5cGVkQ29tcG9uZW50VHlwZSgpOiBzdHJpbmc7XG5cbiAgICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fdmFsdWUuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5fcHJldmlvdXNWYWx1ZS5jb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLl91cGRhdGUuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5fdG91Y2guY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5fYmxvY2suY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZWQkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMubGF5b3V0U3ViamVjdC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWdpc3RlckZvcm1Db250cm9sKGZvcm1Db250cm9sOiBGb3JtQ29udHJvbCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5pbml0aWFsaXplZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEYXRhIGZpZWxkIGNhbiBiZSBpbml0aWFsaXplZCBvbmx5IG9uY2UhJ1xuICAgICAgICAgICAgICAgICsgJyBEaXNjb25uZWN0IHRoZSBwcmV2aW91cyBmb3JtIGNvbnRyb2wgYmVmb3JlIGluaXRpYWxpemluZyB0aGUgZGF0YSBmaWVsZCBhZ2FpbiEnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9ybUNvbnRyb2xSZWYgPSBmb3JtQ29udHJvbDtcbiAgICAgICAgZm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyh0aGlzLnJlc29sdmVGb3JtQ29udHJvbFZhbGlkYXRvcnMoKSk7XG5cbiAgICAgICAgdGhpcy5fZm9ybUNvbnRyb2xWYWx1ZVN1YnNjcmlwdGlvbiA9IGZvcm1Db250cm9sLnZhbHVlQ2hhbmdlcy5waXBlKFxuICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQodGhpcy52YWx1ZUVxdWFsaXR5KVxuICAgICAgICApLnN1YnNjcmliZShuZXdWYWx1ZSA9PiB7XG4gICAgICAgICAgICB0aGlzLl92YWxpZCA9IHRoaXMuX2RldGVybWluZUZvcm1Db250cm9sVmFsaWRpdHkoZm9ybUNvbnRyb2wpO1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9teVZhbHVlU3Vic2NyaXB0aW9uID0gdGhpcy5fdmFsdWUucGlwZShcbiAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKHRoaXMudmFsdWVFcXVhbGl0eSlcbiAgICAgICAgKS5zdWJzY3JpYmUobmV3VmFsdWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5fdmFsaWQgPSB0aGlzLl9kZXRlcm1pbmVGb3JtQ29udHJvbFZhbGlkaXR5KGZvcm1Db250cm9sKTtcbiAgICAgICAgICAgIGZvcm1Db250cm9sLnNldFZhbHVlKG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMudXBkYXRlRm9ybUNvbnRyb2xTdGF0ZShmb3JtQ29udHJvbCk7XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkJC5uZXh0KHRydWUpO1xuICAgICAgICB0aGlzLl9jaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3dhaXRpbmdGb3JSZXNwb25zZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIHB1YmxpYyBkaXNjb25uZWN0Rm9ybUNvbnRyb2woKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5pbml0aWFsaXplZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkJC5uZXh0KGZhbHNlKTtcbiAgICAgICAgY29uc3Qgc3VicyA9IFtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVN1YnNjcmlwdGlvbixcbiAgICAgICAgICAgIHRoaXMuX2Jsb2NrU3Vic2NyaXB0aW9uLFxuICAgICAgICAgICAgdGhpcy5fdG91Y2hTdWJzY3JpcHRpb24sXG4gICAgICAgICAgICB0aGlzLl9mb3JtQ29udHJvbFZhbHVlU3Vic2NyaXB0aW9uLFxuICAgICAgICAgICAgdGhpcy5fbXlWYWx1ZVN1YnNjcmlwdGlvblxuICAgICAgICBdO1xuICAgICAgICBmb3IgKGNvbnN0IHN1YiBvZiBzdWJzKSB7XG4gICAgICAgICAgICBpZiAoc3ViKSB7XG4gICAgICAgICAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgdXBkYXRlRm9ybUNvbnRyb2xTdGF0ZShmb3JtQ29udHJvbDogRm9ybUNvbnRyb2wpOiB2b2lkIHtcbiAgICAgICAgZm9ybUNvbnRyb2wuc2V0VmFsdWUodGhpcy52YWx1ZSk7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlVG9Jbm5lclN1YmplY3RzKGZvcm1Db250cm9sKTtcbiAgICAgICAgdGhpcy51cGRhdGUoKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc3Vic2NyaWJlVG9Jbm5lclN1YmplY3RzKGZvcm1Db250cm9sOiBGb3JtQ29udHJvbCkge1xuICAgICAgICB0aGlzLl91cGRhdGVTdWJzY3JpcHRpb24gPSB0aGlzLl91cGRhdGUuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudmFsaWRSZXF1aXJlZCA9IHRoaXMuY2FsY3VsYXRlVmFsaWRpdHkodHJ1ZSwgZm9ybUNvbnRyb2wpO1xuICAgICAgICAgICAgdGhpcy52YWxpZCA9IHRoaXMuY2FsY3VsYXRlVmFsaWRpdHkoZmFsc2UsIGZvcm1Db250cm9sKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fYmxvY2tlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZWQgPyBmb3JtQ29udHJvbC5kaXNhYmxlKCkgOiBmb3JtQ29udHJvbC5lbmFibGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fYmxvY2tTdWJzY3JpcHRpb24gPSB0aGlzLl9ibG9jay5zdWJzY3JpYmUoYm9vbCA9PiB7XG4gICAgICAgICAgICBpZiAoYm9vbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Jsb2NrZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGZvcm1Db250cm9sLmRpc2FibGUoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYmxvY2tlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZWQgPyBmb3JtQ29udHJvbC5kaXNhYmxlKCkgOiBmb3JtQ29udHJvbC5lbmFibGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fdG91Y2hTdWJzY3JpcHRpb24gPSB0aGlzLl90b3VjaC5zdWJzY3JpYmUoYm9vbCA9PiB7XG4gICAgICAgICAgICBpZiAoYm9vbCkge1xuICAgICAgICAgICAgICAgIGZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wubWFya0FzVW50b3VjaGVkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHdoZXRoZXIgdGhlIEZvcm1Db250cm9sIHNpIHZhbGlkLlxuICAgICAqIEBwYXJhbSBmb3JtQ29udHJvbCBjaGVjayBmb3JtIGNvbnRyb2xcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2RldGVybWluZUZvcm1Db250cm9sVmFsaWRpdHkoZm9ybUNvbnRyb2w6IEZvcm1Db250cm9sKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGRpc2FibGVkIGZvcm0gY29udHJvbHMgYXJlIG1hcmtlZCBhcyBpbnZhbGlkIGFzIHBlciBXM0Mgc3RhbmRhcmQsIHRoaXMgc29sdmVzIHRoYXQgcHJvYmxlbVxuICAgICAgICByZXR1cm4gZm9ybUNvbnRyb2wuZGlzYWJsZWQgfHwgZm9ybUNvbnRyb2wudmFsaWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBWYWxpZGF0b3Igb2JqZWN0cyBiYXNlZCBvbiBmaWVsZCBgYmVoYXZpb3JgLiBPbmx5IHRoZSBgcmVxdWlyZWRgIGJlaGF2aW9yIGlzIHJlc29sdmVkIGJ5IGRlZmF1bHQuXG4gICAgICogUmVxdWlyZWQgaXMgcmVzb2x2ZWQgYXMgYFZhbGlkYXRvcnMucmVxdWlyZWRgLlxuICAgICAqIElmIHlvdSBuZWVkIHRvIHJlc29sdmUgYWRkaXRpb25hbCBWYWxpZGF0b3JzIG9yIG5lZWQgYSBkaWZmZXJlbnQgcmVzb2x1dGlvbiBmb3IgdGhlIGByZXF1aXJlZGAgVmFsaWRhdG9yIG92ZXJyaWRlIHRoaXMgbWV0aG9kLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBCZWhhdmlvcn0gZm9yIGluZm9ybWF0aW9uIGFib3V0IGRhdGEgZmllbGQgYmVoYXZpb3IuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIFZhbGlkYXRvckZufSBhbmQge0BsaW5rIFZhbGlkYXRvcnN9IGZvciBpbmZvcm1hdGlvbiBhYm91dCBWYWxpZGF0b3JzLlxuICAgICAqXG4gICAgICogQWx0ZXJuYXRpdmVseSBzZWUgW0Zvcm0gVmFsaWRhdGlvbiBndWlkZV17QGxpbmsgaHR0cHM6Ly9hbmd1bGFyLmlvL2d1aWRlL2Zvcm0tdmFsaWRhdGlvbiNyZWFjdGl2ZS1mb3JtLXZhbGlkYXRpb259IGZyb20gQW5ndWxhci5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVzb2x2ZUZvcm1Db250cm9sVmFsaWRhdG9ycygpOiBBcnJheTxWYWxpZGF0b3JGbj4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBbXTtcblxuICAgICAgICBpZiAodGhpcy5iZWhhdmlvci5yZXF1aXJlZCkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goVmFsaWRhdG9ycy5yZXF1aXJlZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy52YWxpZGF0aW9ucykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbGlkYXRvcnMpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaCguLi50aGlzLl92YWxpZGF0b3JzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsaWRhdG9ycyA9IHRoaXMucmVzb2x2ZVZhbGlkYXRpb25zKCk7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goLi4udGhpcy5fdmFsaWRhdG9ycyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHB1YmxpYyByZXBsYWNlVmFsaWRhdGlvbnModmFsaWRhdGlvbnM6IEFycmF5PFZhbGlkYXRpb24+KSB7XG4gICAgICAgIHRoaXMuY2xlYXJWYWxpZGF0b3JzKCk7XG4gICAgICAgIHRoaXMudmFsaWRhdGlvbnMgPSB2YWxpZGF0aW9ucztcbiAgICB9XG5cbiAgICBwdWJsaWMgY2xlYXJWYWxpZGF0b3JzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl92YWxpZGF0b3JzID0gbnVsbDtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVzb2x2ZVZhbGlkYXRpb25zKCk6IEFycmF5PFZhbGlkYXRvckZuPiB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIGlmIHR3byB2YWx1ZXMgb2YgdGhlIGRhdGEgZmllbGQgYXJlIGVxdWFsLlxuICAgICAqXG4gICAgICogYGEgPT09IGJgIGVxdWFsaXR5IGlzIHVzZWQgYnkgZGVmYXVsdC4gSWYgeW91IHdhbnQgZGlmZmVyZW50IGJlaGF2aW9yIG92ZXJyaWRlIHRoaXMgbWV0aG9kLlxuICAgICAqIEBwYXJhbSBhIC0gZmlyc3QgY29tcGFyZWQgdmFsdWVcbiAgICAgKiBAcGFyYW0gYiAtIHNlY29uZCBjb21wYXJlZCB2YWx1ZVxuICAgICAqL1xuICAgIHByb3RlY3RlZCB2YWx1ZUVxdWFsaXR5KGE6IFQsIGI6IFQpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGEgPT09IGIgfHwgKE51bWJlci5pc05hTihhKSAmJiBOdW1iZXIuaXNOYU4oYikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIHN0YXRlIG9mIHRoaXMgZGF0YSBmaWVsZCBtb2RlbCBvYmplY3QuXG4gICAgICogQHBhcmFtIGNoYW5nZSAtIG9iamVjdCBkZXNjcmliaW5nIHRoZSBjaGFuZ2VzIC0gcmV0dXJuZWQgZnJvbSBiYWNrZW5kXG4gICAgICpcbiAgICAgKiBBbHNvIHNlZSB7QGxpbmsgQ2hhbmdlZEZpZWxkc30uXG4gICAgICovXG4gICAgcHVibGljIGFwcGx5Q2hhbmdlKGNoYW5nZTogQ2hhbmdlKTogdm9pZCB7XG4gICAgICAgIE9iamVjdC5rZXlzKGNoYW5nZSkuZm9yRWFjaChjaGFuZ2VkQXR0cmlidXRlID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAoY2hhbmdlZEF0dHJpYnV0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3ZhbHVlJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IGNoYW5nZVtjaGFuZ2VkQXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnYmVoYXZpb3InOlxuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMuYmVoYXZpb3IsIGNoYW5nZVtjaGFuZ2VkQXR0cmlidXRlXSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBhdHRyaWJ1dGUgJyR7Y2hhbmdlZEF0dHJpYnV0ZX0nIGluIGNoYW5nZSBvYmplY3RgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlc29sdmVBcHBlYXJhbmNlKGNvbmZpZzogQ29uZmlndXJhdGlvblNlcnZpY2UpOiB2b2lkIHtcbiAgICAgICAgbGV0IGFwcGVhcmFuY2UgPSAnb3V0bGluZSc7XG4gICAgICAgIGlmICh0aGlzLmxheW91dCAmJiB0aGlzLmxheW91dC5hcHBlYXJhbmNlKSB7XG4gICAgICAgICAgICBhcHBlYXJhbmNlID0gdGhpcy5sYXlvdXQuYXBwZWFyYW5jZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFmaWVsZENvbmZpZ3VyYXRpb24gPSBjb25maWcuZ2V0RGF0YWZpZWxkQ29uZmlndXJhdGlvbigpO1xuICAgICAgICAgICAgaWYgKGRhdGFmaWVsZENvbmZpZ3VyYXRpb24gJiYgZGF0YWZpZWxkQ29uZmlndXJhdGlvbi5hcHBlYXJhbmNlKSB7XG4gICAgICAgICAgICAgICAgYXBwZWFyYW5jZSA9IGRhdGFmaWVsZENvbmZpZ3VyYXRpb24uYXBwZWFyYW5jZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1hdGVyaWFsQXBwZWFyYW5jZSA9IGFwcGVhcmFuY2U7XG5cbiAgICAgICAgLyogTGlzdGVuIGZvciBjaGFuZ2VzIG9mIGxheW91dCBpbiBmdXR1cmUgKi9cbiAgICAgICAgdGhpcy5sYXlvdXRTdWJqZWN0LnN1YnNjcmliZShsYXlvdXQgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0ICYmIHRoaXMubGF5b3V0LmFwcGVhcmFuY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsQXBwZWFyYW5jZSA9IHRoaXMubGF5b3V0LmFwcGVhcmFuY2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyByZXNvbHZlUHJldlZhbHVlKHZhbHVlOiBUKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl92YWx1ZS5nZXRWYWx1ZSgpICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICYmIHRoaXMuX3ZhbHVlLmdldFZhbHVlKCkgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9wcmV2aW91c1ZhbHVlLm5leHQodGhpcy5fdmFsdWUuZ2V0VmFsdWUoKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY2FsY3VsYXRlVmFsaWRpdHkoZm9yVmFsaWRSZXF1aXJlZDogYm9vbGVhbiwgZm9ybUNvbnRyb2w6IEZvcm1Db250cm9sKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGlzRGlzYWJsZWQgPSBmb3JtQ29udHJvbC5kaXNhYmxlZDtcbiAgICAgICAgaWYgKGZvclZhbGlkUmVxdWlyZWQpIHtcbiAgICAgICAgICAgIGZvcm1Db250cm9sLmVuYWJsZSgpO1xuICAgICAgICB9XG4gICAgICAgIGZvcm1Db250cm9sLmNsZWFyVmFsaWRhdG9ycygpO1xuICAgICAgICBpZiAoZm9yVmFsaWRSZXF1aXJlZCkge1xuICAgICAgICAgICAgZm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyh0aGlzLmJlaGF2aW9yLnJlcXVpcmVkID8gW1ZhbGlkYXRvcnMucmVxdWlyZWRdIDogW10pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyh0aGlzLnJlc29sdmVGb3JtQ29udHJvbFZhbGlkYXRvcnMoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9ybUNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgICAgICBjb25zdCB2YWxpZGl0eSA9IHRoaXMuX2RldGVybWluZUZvcm1Db250cm9sVmFsaWRpdHkoZm9ybUNvbnRyb2wpO1xuICAgICAgICBpc0Rpc2FibGVkID8gZm9ybUNvbnRyb2wuZGlzYWJsZSgpIDogZm9ybUNvbnRyb2wuZW5hYmxlKCk7XG4gICAgICAgIHJldHVybiB2YWxpZGl0eTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNJbnZhbGlkKGZvcm1Db250cm9sOiBGb3JtQ29udHJvbCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIWZvcm1Db250cm9sLmRpc2FibGVkICYmICFmb3JtQ29udHJvbC52YWxpZCAmJiBmb3JtQ29udHJvbC50b3VjaGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyB0aGUgbGF5b3V0IHNldHRpbmdzIGludG8gdGhlIGxvY2FsIGxheW91dC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVzZXRMb2NhbExheW91dCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2xheW91dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2NhbExheW91dCA9IHsuLi50aGlzLl9sYXlvdXR9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbG9jYWxMYXlvdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=