ngrx-forms
Version:
Proper integration of forms in Angular 4 applications using ngrx
235 lines • 32.9 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import { Directive, HostBinding, HostListener, Inject, Input, Optional, Self, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ActionsSubject } from '@ngrx/store';
import { FocusAction, MarkAsDirtyAction, MarkAsTouchedAction, SetValueAction, UnfocusAction } from '../actions';
import { selectViewAdapter } from '../view-adapter/util';
import { NGRX_FORM_VIEW_ADAPTER } from '../view-adapter/view-adapter';
import { NgrxValueConverters } from './value-converter';
import * as i0 from "@angular/core";
import * as i1 from "@ngrx/store";
export var NGRX_UPDATE_ON_TYPE;
(function (NGRX_UPDATE_ON_TYPE) {
NGRX_UPDATE_ON_TYPE["CHANGE"] = "change";
NGRX_UPDATE_ON_TYPE["BLUR"] = "blur";
NGRX_UPDATE_ON_TYPE["NEVER"] = "never";
})(NGRX_UPDATE_ON_TYPE || (NGRX_UPDATE_ON_TYPE = {}));
class ControlValueAccessorAdapter {
constructor(valueAccessor) {
this.valueAccessor = valueAccessor;
}
setViewValue(value) {
this.valueAccessor.writeValue(value);
}
setOnChangeCallback(fn) {
this.valueAccessor.registerOnChange(fn);
}
setOnTouchedCallback(fn) {
this.valueAccessor.registerOnTouched(fn);
}
setIsDisabled(isDisabled) {
if (this.valueAccessor.setDisabledState) {
this.valueAccessor.setDisabledState(isDisabled);
}
}
}
export class NgrxFormControlDirective {
constructor(el,
// for the dom parameter the `null` type must be last to ensure that in the compiled output
// there is no reference to the Document type to support non-browser platforms
dom, actionsSubject, viewAdapters, valueAccessors) {
this.el = el;
this.dom = dom;
this.actionsSubject = actionsSubject;
this.isInitialized = false;
this.focusTrackingIsEnabled = false;
this.ngrxUpdateOn = NGRX_UPDATE_ON_TYPE.CHANGE;
this.ngrxValueConverter = NgrxValueConverters.default();
viewAdapters = viewAdapters || [];
valueAccessors = valueAccessors || [];
if (valueAccessors.length > 1) {
throw new Error('More than one custom control value accessor matches!');
}
this.viewAdapter = valueAccessors.length > 0
? new ControlValueAccessorAdapter(valueAccessors[0])
: selectViewAdapter(viewAdapters);
}
set ngrxFormControlState(newState) {
if (!newState) {
throw new Error('The control state must not be undefined!');
}
const oldState = this.state;
this.state = newState;
if (this.isInitialized) {
this.updateViewIfControlIdChanged(newState, oldState);
this.updateViewIfValueChanged(newState, oldState);
this.updateViewIfIsDisabledChanged(newState, oldState);
this.updateViewIfIsFocusedChanged(newState, oldState);
}
}
set ngrxEnableFocusTracking(value) {
if (value && !this.dom) {
throw new Error('focus tracking is only supported on the browser platform');
}
this.focusTrackingIsEnabled = value;
}
// TODO: move this into a separate directive
// automatically apply the attribute that's used by the CDK to set initial focus
get focusRegionStartAttr() {
return this.state && this.state.isFocused ? '' : null;
}
updateViewIfControlIdChanged(newState, oldState) {
if (oldState && newState.id === oldState.id) {
return;
}
this.stateValue = newState.value;
this.viewValue = this.ngrxValueConverter.convertStateToViewValue(this.stateValue);
this.viewAdapter.setViewValue(this.viewValue);
if (this.viewAdapter.setIsDisabled) {
this.viewAdapter.setIsDisabled(newState.isDisabled);
}
}
updateViewIfValueChanged(newState, _) {
if (newState.value === this.stateValue) {
return;
}
this.stateValue = newState.value;
this.viewValue = this.ngrxValueConverter.convertStateToViewValue(newState.value);
this.viewAdapter.setViewValue(this.viewValue);
}
updateViewIfIsDisabledChanged(newState, oldState) {
if (!this.viewAdapter.setIsDisabled) {
return;
}
if (oldState && newState.isDisabled === oldState.isDisabled) {
return;
}
this.viewAdapter.setIsDisabled(newState.isDisabled);
}
updateViewIfIsFocusedChanged(newState, oldState) {
if (!this.focusTrackingIsEnabled) {
return;
}
if (oldState && newState.isFocused === oldState.isFocused) {
return;
}
if (newState.isFocused) {
this.el.nativeElement.focus();
}
else {
this.el.nativeElement.blur();
}
}
dispatchAction(action) {
if (this.actionsSubject !== null) {
this.actionsSubject.next(action);
}
else {
throw new Error('ActionsSubject must be present in order to dispatch actions!');
}
}
ngOnInit() {
if (!this.state) {
throw new Error('The form state must not be undefined!');
}
this.isInitialized = true;
this.updateViewIfControlIdChanged(this.state, undefined);
this.updateViewIfValueChanged(this.state, undefined);
this.updateViewIfIsDisabledChanged(this.state, undefined);
this.updateViewIfIsFocusedChanged(this.state, undefined);
const dispatchMarkAsDirtyAction = () => {
if (this.state.isPristine) {
this.dispatchAction(new MarkAsDirtyAction(this.state.id));
}
};
const dispatchSetValueAction = () => {
this.stateValue = this.ngrxValueConverter.convertViewToStateValue(this.viewValue);
if (this.stateValue !== this.state.value) {
this.dispatchAction(new SetValueAction(this.state.id, this.stateValue));
dispatchMarkAsDirtyAction();
}
};
this.viewAdapter.setOnChangeCallback((viewValue) => {
this.viewValue = viewValue;
if (this.ngrxUpdateOn === NGRX_UPDATE_ON_TYPE.CHANGE) {
dispatchSetValueAction();
}
});
this.viewAdapter.setOnTouchedCallback(() => {
if (!this.state.isTouched && this.ngrxUpdateOn !== NGRX_UPDATE_ON_TYPE.NEVER) {
this.dispatchAction(new MarkAsTouchedAction(this.state.id));
}
if (this.ngrxUpdateOn === NGRX_UPDATE_ON_TYPE.BLUR) {
dispatchSetValueAction();
}
});
}
ngAfterViewInit() {
// we need to update the view again after it was initialized since some
// controls depend on child elements for setting the value (e.g. selects)
this.viewAdapter.setViewValue(this.viewValue);
if (this.viewAdapter.setIsDisabled) {
this.viewAdapter.setIsDisabled(this.state.isDisabled);
}
}
onFocusChange() {
if (!this.focusTrackingIsEnabled) {
return;
}
const isControlFocused = this.el.nativeElement === this.dom.activeElement;
if (isControlFocused !== this.state.isFocused) {
this.dispatchAction(isControlFocused ? new FocusAction(this.state.id) : new UnfocusAction(this.state.id));
}
}
}
NgrxFormControlDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: NgrxFormControlDirective, deps: [{ token: i0.ElementRef }, { token: DOCUMENT, optional: true }, { token: ActionsSubject, optional: true }, { token: NGRX_FORM_VIEW_ADAPTER, optional: true, self: true }, { token: NG_VALUE_ACCESSOR, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
NgrxFormControlDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.13", type: NgrxFormControlDirective, selector: ":not([ngrxFormsAction])[ngrxFormControlState]", inputs: { ngrxFormControlState: "ngrxFormControlState", ngrxUpdateOn: "ngrxUpdateOn", ngrxEnableFocusTracking: "ngrxEnableFocusTracking", ngrxValueConverter: "ngrxValueConverter" }, host: { listeners: { "focusin": "onFocusChange()", "focusout": "onFocusChange()" }, properties: { "attr.cdk-focus-region-start": "this.focusRegionStartAttr" } }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: NgrxFormControlDirective, decorators: [{
type: Directive,
args: [{
// tslint:disable-next-line:directive-selector
selector: ':not([ngrxFormsAction])[ngrxFormControlState]',
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DOCUMENT]
}] }, { type: i1.ActionsSubject, decorators: [{
type: Optional
}, {
type: Inject,
args: [ActionsSubject]
}] }, { type: undefined, decorators: [{
type: Self
}, {
type: Optional
}, {
type: Inject,
args: [NGRX_FORM_VIEW_ADAPTER]
}] }, { type: undefined, decorators: [{
type: Self
}, {
type: Optional
}, {
type: Inject,
args: [NG_VALUE_ACCESSOR]
}] }]; }, propDecorators: { ngrxFormControlState: [{
type: Input
}], ngrxUpdateOn: [{
type: Input
}], ngrxEnableFocusTracking: [{
type: Input
}], ngrxValueConverter: [{
type: Input
}], focusRegionStartAttr: [{
type: HostBinding,
args: ['attr.cdk-focus-region-start']
}], onFocusChange: [{
type: HostListener,
args: ['focusin']
}, {
type: HostListener,
args: ['focusout']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbnRyb2wvZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBRUwsU0FBUyxFQUVULFdBQVcsRUFDWCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFFTCxRQUFRLEVBQ1IsSUFBSSxHQUNMLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTdDLE9BQU8sRUFBVyxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV6SCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN6RCxPQUFPLEVBQW1CLHNCQUFzQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkYsT0FBTyxFQUFzQixtQkFBbUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7QUFNNUUsTUFBTSxDQUFOLElBQVksbUJBSVg7QUFKRCxXQUFZLG1CQUFtQjtJQUM3Qix3Q0FBaUIsQ0FBQTtJQUNqQixvQ0FBYSxDQUFBO0lBQ2Isc0NBQWUsQ0FBQTtBQUNqQixDQUFDLEVBSlcsbUJBQW1CLEtBQW5CLG1CQUFtQixRQUk5QjtBQUVELE1BQU0sMkJBQTJCO0lBQy9CLFlBQW9CLGFBQW1DO1FBQW5DLGtCQUFhLEdBQWIsYUFBYSxDQUFzQjtJQUFJLENBQUM7SUFFNUQsWUFBWSxDQUFDLEtBQVU7UUFDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELG1CQUFtQixDQUFDLEVBQXdCO1FBQzFD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QkFDM0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxjQUFjOzswQkFDakMsSUFBSTs7MEJBQUksUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxzQkFBc0I7OzBCQUNqRCxJQUFJOzswQkFBSSxRQUFROzswQkFBSSxNQUFNOzJCQUFDLGlCQUFpQjs0Q0F2RGxDLG9CQUFvQjtzQkFBaEMsS0FBSztnQkFnQkcsWUFBWTtzQkFBcEIsS0FBSztnQkFDTyx1QkFBdUI7c0JBQW5DLEtBQUs7Z0JBUUcsa0JBQWtCO3NCQUExQixLQUFLO2dCQUkwQyxvQkFBb0I7c0JBQW5FLFdBQVc7dUJBQUMsNkJBQTZCO2dCQXdLMUMsYUFBYTtzQkFGWixZQUFZO3VCQUFDLFNBQVM7O3NCQUN0QixZQUFZO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBEaXJlY3RpdmUsXHJcbiAgRWxlbWVudFJlZixcclxuICBIb3N0QmluZGluZyxcclxuICBIb3N0TGlzdGVuZXIsXHJcbiAgSW5qZWN0LFxyXG4gIElucHV0LFxyXG4gIE9uSW5pdCxcclxuICBPcHRpb25hbCxcclxuICBTZWxmLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEFjdGlvbnNTdWJqZWN0IH0gZnJvbSAnQG5ncngvc3RvcmUnO1xyXG5cclxuaW1wb3J0IHsgQWN0aW9ucywgRm9jdXNBY3Rpb24sIE1hcmtBc0RpcnR5QWN0aW9uLCBNYXJrQXNUb3VjaGVkQWN0aW9uLCBTZXRWYWx1ZUFjdGlvbiwgVW5mb2N1c0FjdGlvbiB9IGZyb20gJy4uL2FjdGlvbnMnO1xyXG5pbXBvcnQgeyBGb3JtQ29udHJvbFN0YXRlLCBGb3JtQ29udHJvbFZhbHVlVHlwZXMgfSBmcm9tICcuLi9zdGF0ZSc7XHJcbmltcG9ydCB7IHNlbGVjdFZpZXdBZGFwdGVyIH0gZnJvbSAnLi4vdmlldy1hZGFwdGVyL3V0aWwnO1xyXG5pbXBvcnQgeyBGb3JtVmlld0FkYXB0ZXIsIE5HUlhfRk9STV9WSUVXX0FEQVBURVIgfSBmcm9tICcuLi92aWV3LWFkYXB0ZXIvdmlldy1hZGFwdGVyJztcclxuaW1wb3J0IHsgTmdyeFZhbHVlQ29udmVydGVyLCBOZ3J4VmFsdWVDb252ZXJ0ZXJzIH0gZnJvbSAnLi92YWx1ZS1jb252ZXJ0ZXInO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBEb2N1bWVudCB7XHJcbiAgYWN0aXZlRWxlbWVudDogYW55O1xyXG59XHJcblxyXG5leHBvcnQgZW51bSBOR1JYX1VQREFURV9PTl9UWVBFIHtcclxuICBDSEFOR0UgPSAnY2hhbmdlJyxcclxuICBCTFVSID0gJ2JsdXInLFxyXG4gIE5FVkVSID0gJ25ldmVyJyxcclxufVxyXG5cclxuY2xhc3MgQ29udHJvbFZhbHVlQWNjZXNzb3JBZGFwdGVyIGltcGxlbWVudHMgRm9ybVZpZXdBZGFwdGVyIHtcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHZhbHVlQWNjZXNzb3I6IENvbnRyb2xWYWx1ZUFjY2Vzc29yKSB7IH1cclxuXHJcbiAgc2V0Vmlld1ZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMudmFsdWVBY2Nlc3Nvci53cml0ZVZhbHVlKHZhbHVlKTtcclxuICB9XHJcblxyXG4gIHNldE9uQ2hhbmdlQ2FsbGJhY2soZm46ICh2YWx1ZTogYW55KSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICB0aGlzLnZhbHVlQWNjZXNzb3IucmVnaXN0ZXJPbkNoYW5nZShmbik7XHJcbiAgfVxyXG4gIHNldE9uVG91Y2hlZENhbGxiYWNrKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICB0aGlzLnZhbHVlQWNjZXNzb3IucmVnaXN0ZXJPblRvdWNoZWQoZm4pO1xyXG4gIH1cclxuXHJcbiAgc2V0SXNEaXNhYmxlZChpc0Rpc2FibGVkOiBib29sZWFuKSB7XHJcbiAgICBpZiAodGhpcy52YWx1ZUFjY2Vzc29yLnNldERpc2FibGVkU3RhdGUpIHtcclxuICAgICAgdGhpcy52YWx1ZUFjY2Vzc29yLnNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgdHlwZSBOZ3J4Rm9ybUNvbnRyb2xWYWx1ZVR5cGU8VFN0YXRlVmFsdWU+ID0gVFN0YXRlVmFsdWUgZXh0ZW5kcyBGb3JtQ29udHJvbFZhbHVlVHlwZXMgPyBUU3RhdGVWYWx1ZSA6IG5ldmVyO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRpcmVjdGl2ZS1zZWxlY3RvclxyXG4gIHNlbGVjdG9yOiAnOm5vdChbbmdyeEZvcm1zQWN0aW9uXSlbbmdyeEZvcm1Db250cm9sU3RhdGVdJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIE5ncnhGb3JtQ29udHJvbERpcmVjdGl2ZTxUU3RhdGVWYWx1ZSwgVFZpZXdWYWx1ZSA9IFRTdGF0ZVZhbHVlPiBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uSW5pdCB7XHJcbiAgcHJpdmF0ZSBpc0luaXRpYWxpemVkID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBmb2N1c1RyYWNraW5nSXNFbmFibGVkID0gZmFsc2U7XHJcblxyXG4gIEBJbnB1dCgpIHNldCBuZ3J4Rm9ybUNvbnRyb2xTdGF0ZShuZXdTdGF0ZTogRm9ybUNvbnRyb2xTdGF0ZTxOZ3J4Rm9ybUNvbnRyb2xWYWx1ZVR5cGU8VFN0YXRlVmFsdWU+Pikge1xyXG4gICAgaWYgKCFuZXdTdGF0ZSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb250cm9sIHN0YXRlIG11c3Qgbm90IGJlIHVuZGVmaW5lZCEnKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBvbGRTdGF0ZSA9IHRoaXMuc3RhdGU7XHJcbiAgICB0aGlzLnN0YXRlID0gbmV3U3RhdGU7XHJcblxyXG4gICAgaWYgKHRoaXMuaXNJbml0aWFsaXplZCkge1xyXG4gICAgICB0aGlzLnVwZGF0ZVZpZXdJZkNvbnRyb2xJZENoYW5nZWQobmV3U3RhdGUsIG9sZFN0YXRlKTtcclxuICAgICAgdGhpcy51cGRhdGVWaWV3SWZWYWx1ZUNoYW5nZWQobmV3U3RhdGUsIG9sZFN0YXRlKTtcclxuICAgICAgdGhpcy51cGRhdGVWaWV3SWZJc0Rpc2FibGVkQ2hhbmdlZChuZXdTdGF0ZSwgb2xkU3RhdGUpO1xyXG4gICAgICB0aGlzLnVwZGF0ZVZpZXdJZklzRm9jdXNlZENoYW5nZWQobmV3U3RhdGUsIG9sZFN0YXRlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIG5ncnhVcGRhdGVPbjogTkdSWF9VUERBVEVfT05fVFlQRSA9IE5HUlhfVVBEQVRFX09OX1RZUEUuQ0hBTkdFO1xyXG4gIEBJbnB1dCgpIHNldCBuZ3J4RW5hYmxlRm9jdXNUcmFja2luZyh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgaWYgKHZhbHVlICYmICF0aGlzLmRvbSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZvY3VzIHRyYWNraW5nIGlzIG9ubHkgc3VwcG9ydGVkIG9uIHRoZSBicm93c2VyIHBsYXRmb3JtJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5mb2N1c1RyYWNraW5nSXNFbmFibGVkID0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKSBuZ3J4VmFsdWVDb252ZXJ0ZXI6IE5ncnhWYWx1ZUNvbnZlcnRlcjxUVmlld1ZhbHVlLCBUU3RhdGVWYWx1ZT4gPSBOZ3J4VmFsdWVDb252ZXJ0ZXJzLmRlZmF1bHQ8YW55PigpO1xyXG5cclxuICAvLyBUT0RPOiBtb3ZlIHRoaXMgaW50byBhIHNlcGFyYXRlIGRpcmVjdGl2ZVxyXG4gIC8vIGF1dG9tYXRpY2FsbHkgYXBwbHkgdGhlIGF0dHJpYnV0ZSB0aGF0J3MgdXNlZCBieSB0aGUgQ0RLIHRvIHNldCBpbml0aWFsIGZvY3VzXHJcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmNkay1mb2N1cy1yZWdpb24tc3RhcnQnKSBnZXQgZm9jdXNSZWdpb25TdGFydEF0dHIoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLmlzRm9jdXNlZCA/ICcnIDogbnVsbDtcclxuICB9XHJcblxyXG4gIHN0YXRlOiBGb3JtQ29udHJvbFN0YXRlPE5ncnhGb3JtQ29udHJvbFZhbHVlVHlwZTxUU3RhdGVWYWx1ZT4+O1xyXG5cclxuICBwcml2YXRlIHZpZXdBZGFwdGVyOiBGb3JtVmlld0FkYXB0ZXI7XHJcblxyXG4gIC8vIHdlIGhhdmUgdG8gc3RvcmUgdGhlIGxhdGVzdCBrbm93biBzdGF0ZSB2YWx1ZSBzaW5jZSBtb3N0IGlucHV0IGVsZW1lbnRzIGRvbid0IHBsYXkgbmljZWx5IHdpdGhcclxuICAvLyBzZXR0aW5nIHRoZSBzYW1lIHZhbHVlIGFnYWluIChlLmcuIGlucHV0IGVsZW1lbnRzIG1vdmUgdGhlIGN1cnNvciB0byB0aGUgZW5kIG9mIHRoZSBpbnB1dCB3aGVuXHJcbiAgLy8gYSBuZXcgdmFsdWUgaXMgc2V0IHdoaWNoIG1lYW5zIHdoZW5ldmVyIHRoZSB1c2VyIHR5cGVzIHNvbWV0aGluZyB0aGUgY3Vyc29yIGlzIGZvcmNlZCB0byB0aGVcclxuICAvLyBlbmQgb2YgdGhlIGlucHV0KSB3aGljaCB3b3VsZCBmb3IgZXhhbXBsZSBoYXBwZW4gZXZlcnkgdGltZSBhIG5ldyB2YWx1ZSBpcyBwdXNoZWQgdG8gdGhlIHN0YXRlXHJcbiAgLy8gc2luY2Ugd2hlbiB0aGUgYWN0aW9uIHRvIHVwZGF0ZSB0aGUgc3RhdGUgaXMgZGlzcGF0Y2hlZCBhIG5ldyBzdGF0ZSB3aWxsIGJlIHJlY2VpdmVkIGluc2lkZVxyXG4gIC8vIHRoZSBkaXJlY3RpdmUsIHdoaWNoIGluIHR1cm4gd291bGQgdHJpZ2dlciBhIHZpZXcgdXBkYXRlOyB0byBwcmV2ZW50IHRoaXMgYmVoYXZpb3Igd2UgY29tcGFyZVxyXG4gIC8vIHRoZSBsYXRlc3Qga25vd24gc3RhdGUgdmFsdWUgd2l0aCB0aGUgdmFsdWUgdG8gYmUgc2V0IGFuZCBmaWx0ZXIgb3V0IHRob3NlIHZhbHVlcyB0aGF0IGFyZSBlcXVhbFxyXG4gIC8vIHRvIHRoZSBsYXRlc3Qga25vd24gdmFsdWVcclxuICBwcml2YXRlIHZpZXdWYWx1ZTogVFZpZXdWYWx1ZTtcclxuICBwcml2YXRlIHN0YXRlVmFsdWU6IFRTdGF0ZVZhbHVlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXHJcbiAgICAvLyBmb3IgdGhlIGRvbSBwYXJhbWV0ZXIgdGhlIGBudWxsYCB0eXBlIG11c3QgYmUgbGFzdCB0byBlbnN1cmUgdGhhdCBpbiB0aGUgY29tcGlsZWQgb3V0cHV0XHJcbiAgICAvLyB0aGVyZSBpcyBubyByZWZlcmVuY2UgdG8gdGhlIERvY3VtZW50IHR5cGUgdG8gc3VwcG9ydCBub24tYnJvd3NlciBwbGF0Zm9ybXNcclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9tOiBEb2N1bWVudCB8IG51bGwsXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFjdGlvbnNTdWJqZWN0KSBwcml2YXRlIGFjdGlvbnNTdWJqZWN0OiBBY3Rpb25zU3ViamVjdCB8IG51bGwsXHJcbiAgICBAU2VsZigpIEBPcHRpb25hbCgpIEBJbmplY3QoTkdSWF9GT1JNX1ZJRVdfQURBUFRFUikgdmlld0FkYXB0ZXJzOiBGb3JtVmlld0FkYXB0ZXJbXSxcclxuICAgIEBTZWxmKCkgQE9wdGlvbmFsKCkgQEluamVjdChOR19WQUxVRV9BQ0NFU1NPUikgdmFsdWVBY2Nlc3NvcnM6IENvbnRyb2xWYWx1ZUFjY2Vzc29yW10sXHJcbiAgKSB7XHJcbiAgICB2aWV3QWRhcHRlcnMgPSB2aWV3QWRhcHRlcnMgfHwgW107XHJcbiAgICB2YWx1ZUFjY2Vzc29ycyA9IHZhbHVlQWNjZXNzb3JzIHx8IFtdO1xyXG5cclxuICAgIGlmICh2YWx1ZUFjY2Vzc29ycy5sZW5ndGggPiAxKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignTW9yZSB0aGFuIG9uZSBjdXN0b20gY29udHJvbCB2YWx1ZSBhY2Nlc3NvciBtYXRjaGVzIScpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudmlld0FkYXB0ZXIgPSB2YWx1ZUFjY2Vzc29ycy5sZW5ndGggPiAwXHJcbiAgICAgID8gbmV3IENvbnRyb2xWYWx1ZUFjY2Vzc29yQWRhcHRlcih2YWx1ZUFjY2Vzc29yc1swXSlcclxuICAgICAgOiBzZWxlY3RWaWV3QWRhcHRlcih2aWV3QWRhcHRlcnMpO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlVmlld0lmQ29udHJvbElkQ2hhbmdlZChcclxuICAgIG5ld1N0YXRlOiBGb3JtQ29udHJvbFN0YXRlPE5ncnhGb3JtQ29udHJvbFZhbHVlVHlwZTxUU3RhdGVWYWx1ZT4+LFxyXG4gICAgb2xkU3RhdGU6IEZvcm1Db250cm9sU3RhdGU8TmdyeEZvcm1Db250cm9sVmFsdWVUeXBlPFRTdGF0ZVZhbHVlPj4gfCB1bmRlZmluZWQsXHJcbiAgKSB7XHJcbiAgICBpZiAob2xkU3RhdGUgJiYgbmV3U3RhdGUuaWQgPT09IG9sZFN0YXRlLmlkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnN0YXRlVmFsdWUgPSBuZXdTdGF0ZS52YWx1ZTtcclxuICAgIHRoaXMudmlld1ZhbHVlID0gdGhpcy5uZ3J4VmFsdWVDb252ZXJ0ZXIuY29udmVydFN0YXRlVG9WaWV3VmFsdWUodGhpcy5zdGF0ZVZhbHVlKTtcclxuICAgIHRoaXMudmlld0FkYXB0ZXIuc2V0Vmlld1ZhbHVlKHRoaXMudmlld1ZhbHVlKTtcclxuICAgIGlmICh0aGlzLnZpZXdBZGFwdGVyLnNldElzRGlzYWJsZWQpIHtcclxuICAgICAgdGhpcy52aWV3QWRhcHRlci5zZXRJc0Rpc2FibGVkKG5ld1N0YXRlLmlzRGlzYWJsZWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlVmlld0lmVmFsdWVDaGFuZ2VkKFxyXG4gICAgbmV3U3RhdGU6IEZvcm1Db250cm9sU3RhdGU8TmdyeEZvcm1Db250cm9sVmFsdWVUeXBlPFRTdGF0ZVZhbHVlPj4sXHJcbiAgICBfOiBGb3JtQ29udHJvbFN0YXRlPE5ncnhGb3JtQ29udHJvbFZhbHVlVHlwZTxUU3RhdGVWYWx1ZT4+IHwgdW5kZWZpbmVkLFxyXG4gICkge1xyXG4gICAgaWYgKG5ld1N0YXRlLnZhbHVlID09PSB0aGlzLnN0YXRlVmFsdWUpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc3RhdGVWYWx1ZSA9IG5ld1N0YXRlLnZhbHVlO1xyXG4gICAgdGhpcy52aWV3VmFsdWUgPSB0aGlzLm5ncnhWYWx1ZUNvbnZlcnRlci5jb252ZXJ0U3RhdGVUb1ZpZXdWYWx1ZShuZXdTdGF0ZS52YWx1ZSk7XHJcbiAgICB0aGlzLnZpZXdBZGFwdGVyLnNldFZpZXdWYWx1ZSh0aGlzLnZpZXdWYWx1ZSk7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVWaWV3SWZJc0Rpc2FibGVkQ2hhbmdlZChcclxuICAgIG5ld1N0YXRlOiBGb3JtQ29udHJvbFN0YXRlPE5ncnhGb3JtQ29udHJvbFZhbHVlVHlwZTxUU3RhdGVWYWx1ZT4+LFxyXG4gICAgb2xkU3RhdGU6IEZvcm1Db250cm9sU3RhdGU8TmdyeEZvcm1Db250cm9sVmFsdWVUeXBlPFRTdGF0ZVZhbHVlPj4gfCB1bmRlZmluZWQsXHJcbiAgKSB7XHJcbiAgICBpZiAoIXRoaXMudmlld0FkYXB0ZXIuc2V0SXNEaXNhYmxlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG9sZFN0YXRlICYmIG5ld1N0YXRlLmlzRGlzYWJsZWQgPT09IG9sZFN0YXRlLmlzRGlzYWJsZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudmlld0FkYXB0ZXIuc2V0SXNEaXNhYmxlZChuZXdTdGF0ZS5pc0Rpc2FibGVkKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVZpZXdJZklzRm9jdXNlZENoYW5nZWQoXHJcbiAgICBuZXdTdGF0ZTogRm9ybUNvbnRyb2xTdGF0ZTxOZ3J4Rm9ybUNvbnRyb2xWYWx1ZVR5cGU8VFN0YXRlVmFsdWU+PixcclxuICAgIG9sZFN0YXRlOiBGb3JtQ29udHJvbFN0YXRlPE5ncnhGb3JtQ29udHJvbFZhbHVlVHlwZTxUU3RhdGVWYWx1ZT4+IHwgdW5kZWZpbmVkLFxyXG4gICkge1xyXG4gICAgaWYgKCF0aGlzLmZvY3VzVHJhY2tpbmdJc0VuYWJsZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvbGRTdGF0ZSAmJiBuZXdTdGF0ZS5pc0ZvY3VzZWQgPT09IG9sZFN0YXRlLmlzRm9jdXNlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5ld1N0YXRlLmlzRm9jdXNlZCkge1xyXG4gICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5ibHVyKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgZGlzcGF0Y2hBY3Rpb24oYWN0aW9uOiBBY3Rpb25zPE5ncnhGb3JtQ29udHJvbFZhbHVlVHlwZTxUU3RhdGVWYWx1ZT4+KSB7XHJcbiAgICBpZiAodGhpcy5hY3Rpb25zU3ViamVjdCAhPT0gbnVsbCkge1xyXG4gICAgICB0aGlzLmFjdGlvbnNTdWJqZWN0Lm5leHQoYWN0aW9uKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uc1N1YmplY3QgbXVzdCBiZSBwcmVzZW50IGluIG9yZGVyIHRvIGRpc3BhdGNoIGFjdGlvbnMhJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIGlmICghdGhpcy5zdGF0ZSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBmb3JtIHN0YXRlIG11c3Qgbm90IGJlIHVuZGVmaW5lZCEnKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG5cclxuICAgIHRoaXMudXBkYXRlVmlld0lmQ29udHJvbElkQ2hhbmdlZCh0aGlzLnN0YXRlLCB1bmRlZmluZWQpO1xyXG4gICAgdGhpcy51cGRhdGVWaWV3SWZWYWx1ZUNoYW5nZWQodGhpcy5zdGF0ZSwgdW5kZWZpbmVkKTtcclxuICAgIHRoaXMudXBkYXRlVmlld0lmSXNEaXNhYmxlZENoYW5nZWQodGhpcy5zdGF0ZSwgdW5kZWZpbmVkKTtcclxuICAgIHRoaXMudXBkYXRlVmlld0lmSXNGb2N1c2VkQ2hhbmdlZCh0aGlzLnN0YXRlLCB1bmRlZmluZWQpO1xyXG5cclxuICAgIGNvbnN0IGRpc3BhdGNoTWFya0FzRGlydHlBY3Rpb24gPSAoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnN0YXRlLmlzUHJpc3RpbmUpIHtcclxuICAgICAgICB0aGlzLmRpc3BhdGNoQWN0aW9uKG5ldyBNYXJrQXNEaXJ0eUFjdGlvbih0aGlzLnN0YXRlLmlkKSk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgZGlzcGF0Y2hTZXRWYWx1ZUFjdGlvbiA9ICgpID0+IHtcclxuICAgICAgdGhpcy5zdGF0ZVZhbHVlID0gdGhpcy5uZ3J4VmFsdWVDb252ZXJ0ZXIuY29udmVydFZpZXdUb1N0YXRlVmFsdWUodGhpcy52aWV3VmFsdWUpO1xyXG4gICAgICBpZiAodGhpcy5zdGF0ZVZhbHVlICE9PSB0aGlzLnN0YXRlLnZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5kaXNwYXRjaEFjdGlvbihuZXcgU2V0VmFsdWVBY3Rpb24odGhpcy5zdGF0ZS5pZCwgdGhpcy5zdGF0ZVZhbHVlIGFzIE5ncnhGb3JtQ29udHJvbFZhbHVlVHlwZTxUU3RhdGVWYWx1ZT4pKTtcclxuXHJcbiAgICAgICAgZGlzcGF0Y2hNYXJrQXNEaXJ0eUFjdGlvbigpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMudmlld0FkYXB0ZXIuc2V0T25DaGFuZ2VDYWxsYmFjaygodmlld1ZhbHVlOiBUVmlld1ZhbHVlKSA9PiB7XHJcbiAgICAgIHRoaXMudmlld1ZhbHVlID0gdmlld1ZhbHVlO1xyXG5cclxuICAgICAgaWYgKHRoaXMubmdyeFVwZGF0ZU9uID09PSBOR1JYX1VQREFURV9PTl9UWVBFLkNIQU5HRSkge1xyXG4gICAgICAgIGRpc3BhdGNoU2V0VmFsdWVBY3Rpb24oKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy52aWV3QWRhcHRlci5zZXRPblRvdWNoZWRDYWxsYmFjaygoKSA9PiB7XHJcbiAgICAgIGlmICghdGhpcy5zdGF0ZS5pc1RvdWNoZWQgJiYgdGhpcy5uZ3J4VXBkYXRlT24gIT09IE5HUlhfVVBEQVRFX09OX1RZUEUuTkVWRVIpIHtcclxuICAgICAgICB0aGlzLmRpc3BhdGNoQWN0aW9uKG5ldyBNYXJrQXNUb3VjaGVkQWN0aW9uKHRoaXMuc3RhdGUuaWQpKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHRoaXMubmdyeFVwZGF0ZU9uID09PSBOR1JYX1VQREFURV9PTl9UWVBFLkJMVVIpIHtcclxuICAgICAgICBkaXNwYXRjaFNldFZhbHVlQWN0aW9uKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgLy8gd2UgbmVlZCB0byB1cGRhdGUgdGhlIHZpZXcgYWdhaW4gYWZ0ZXIgaXQgd2FzIGluaXRpYWxpemVkIHNpbmNlIHNvbWVcclxuICAgIC8vIGNvbnRyb2xzIGRlcGVuZCBvbiBjaGlsZCBlbGVtZW50cyBmb3Igc2V0dGluZyB0aGUgdmFsdWUgKGUuZy4gc2VsZWN0cylcclxuICAgIHRoaXMudmlld0FkYXB0ZXIuc2V0Vmlld1ZhbHVlKHRoaXMudmlld1ZhbHVlKTtcclxuICAgIGlmICh0aGlzLnZpZXdBZGFwdGVyLnNldElzRGlzYWJsZWQpIHtcclxuICAgICAgdGhpcy52aWV3QWRhcHRlci5zZXRJc0Rpc2FibGVkKHRoaXMuc3RhdGUuaXNEaXNhYmxlZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdmb2N1c2luJylcclxuICBASG9zdExpc3RlbmVyKCdmb2N1c291dCcpXHJcbiAgb25Gb2N1c0NoYW5nZSgpIHtcclxuICAgIGlmICghdGhpcy5mb2N1c1RyYWNraW5nSXNFbmFibGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBpc0NvbnRyb2xGb2N1c2VkID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50ID09PSB0aGlzLmRvbSEuYWN0aXZlRWxlbWVudDtcclxuICAgIGlmIChpc0NvbnRyb2xGb2N1c2VkICE9PSB0aGlzLnN0YXRlLmlzRm9jdXNlZCkge1xyXG4gICAgICB0aGlzLmRpc3BhdGNoQWN0aW9uKGlzQ29udHJvbEZvY3VzZWQgPyBuZXcgRm9jdXNBY3Rpb24odGhpcy5zdGF0ZS5pZCkgOiBuZXcgVW5mb2N1c0FjdGlvbih0aGlzLnN0YXRlLmlkKSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiJdfQ==