UNPKG

gentics-ui-core

Version:

This is the common core framework for the Gentics CMS and Mesh UI, and other Angular applications.

284 lines 31.9 kB
import { Attribute, ChangeDetectorRef, Component, Directive, EventEmitter, HostListener, Input, Optional, Output, forwardRef } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { KeyCode } from '../../common/keycodes'; import { coerceToBoolean } from '../../common/coerce-to-boolean'; import * as i0 from "@angular/core"; const GTX_RADIO_GROUP_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RadioGroup), multi: true }; const GTX_RADIO_BUTTON_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RadioButton), multi: true }; /** * RadioGroup groups multiple {@link RadioButton} elements together. * Use ngModel to connect it to a form model. */ export class RadioGroup { constructor() { this.radioButtons = []; this.onTouched = () => { }; this.onChange = (_) => { }; this.groupID = RadioGroup.instanceCounter++; } get uniqueName() { return 'group-' + this.groupID; } add(radio) { if (this.radioButtons.indexOf(radio) < 0) { this.radioButtons.push(radio); } } remove(radio) { let pos = this.radioButtons.indexOf(radio); if (pos >= 0) { this.radioButtons.splice(pos, 1); } } radioSelected(selected) { for (let radio of this.radioButtons) { if (radio != selected) { radio.writeValue(selected ? selected.value : null); } } // setTimeout because this method is invoked from a child component (RadioButton), which is the wrong direction // for change propagation (which should normally always be parent -> child). If we synchronously now update the // ngModel value, we will cause "changed after checked" errors in dev mode. setTimeout(() => { this.onChange(selected ? selected.value : null); }); } writeValue(value) { for (let radio of this.radioButtons) { radio.writeValue(value); } } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } } RadioGroup.instanceCounter = 0; /** @nocollapse */ RadioGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: RadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); /** @nocollapse */ RadioGroup.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.8", type: RadioGroup, selector: "gtx-radio-group, [gtx-radio-group]", providers: [GTX_RADIO_GROUP_VALUE_ACCESSOR], ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: RadioGroup, decorators: [{ type: Directive, args: [{ selector: 'gtx-radio-group, [gtx-radio-group]', providers: [GTX_RADIO_GROUP_VALUE_ACCESSOR] }] }], ctorParameters: function () { return []; } }); /** * RadioButton wraps the native `<input type="radio">` form element. * To connect multiple radio buttons with a form via ngModel, * wrap them in a {@link RadioGroup} (`<gtx-radio-group>`). * * ```html * <gtx-radio-button [(ngModel)]="val" value="A" label="A"></gtx-radio-button> * <gtx-radio-button [(ngModel)]="val" value="B" label="B"></gtx-radio-button> * <gtx-radio-button [(ngModel)]="val" value="C" label="C"></gtx-radio-button> * ``` * * ## Stateless Mode * By default, the RadioButton keeps track of its own internal checked state. This makes sense * for most use cases, such as when used in a form bound to ngModel. * * However, in some cases we want to explicitly set the state from outside. This is done by binding * to the <code>checked</code> attribute. When this attribute is bound, the checked state of the * RadioButton will *only* change when the value of the binding changes. Clicking on the RadioButton * will have no effect other than to emit an event which the parent can use to update the binding. * * Here is a basic example of a stateless RadioButton where the parent component manages the state: * * ```html * <gtx-radio-button [checked]="isChecked"></gtx-checkbox> * ``` */ export class RadioButton { constructor(group, modelAttrib, changeDetector) { this.group = group; this.changeDetector = changeDetector; /** * Sets the radio button to be auto-focused. Handled by `AutofocusDirective`. */ this.autofocus = false; /** * The disabled state of the control */ this.disabled = false; /** * ID of the control */ this.id = randomID(); /** * Label for the radio button */ this.label = ''; /** * Sets the required state */ this.required = false; /** * Value associated with this input */ this.value = ''; /** * Blur event */ this.blur = new EventEmitter(true); /** * Focus event */ this.focus = new EventEmitter(true); /** * Change event */ this.change = new EventEmitter(true); this.tabbedFocus = false; this.inputChecked = false; /** * See note above on stateless mode. */ this.statelessMode = false; this.onChange = (_) => { }; this.onTouched = () => { }; // Pre-set a common input name for grouped input elements if (group) { this.name = group.uniqueName; } else if (modelAttrib) { this.name = modelAttrib; } } /** * The checked state of the control. When set, the RadioButton will be * in stateless mode. */ get checked() { return this.inputChecked; } set checked(val) { this.statelessMode = true; if (val != this.inputChecked) { this.inputChecked = coerceToBoolean(val); if (val && this.group) { this.group.radioSelected(this); } if (val) { this.onChange(this.value); } else if (val === false) { if (this.group) { this.group.radioSelected(null); } this.onChange(false); } this.change.emit(this.value); } } onBlur() { this.blur.emit(this.checked); this.onTouched(); this.tabbedFocus = false; } onFocus() { this.focus.emit(this.checked); } focusHandler(e) { if (e.keyCode === KeyCode.Tab) { if (!this.tabbedFocus) { this.tabbedFocus = true; } } } writeValue(value) { this.inputChecked = (value === this.value); } ngOnInit() { if (this.inputChecked) { this.onChange(this.value); } if (this.group) { this.group.add(this); if (this.inputChecked) { this.group.radioSelected(this); } } } ngOnDestroy() { if (this.group) { this.group.remove(this); } } onInputChecked(e, input) { if (e) { e.stopPropagation(); } if (this.statelessMode) { let newState = input.checked; if (input.checked !== this.inputChecked) { input.checked = !!this.inputChecked; } this.change.emit(newState); return false; } this.inputChecked = true; this.onChange(this.value); this.change.emit(this.value); if (this.group) { this.group.radioSelected(this); } return true; } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(disabled) { this.disabled = disabled; this.changeDetector.markForCheck(); } } /** @nocollapse */ RadioButton.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: RadioButton, deps: [{ token: RadioGroup, optional: true }, { token: 'ngModel', attribute: true }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ RadioButton.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: RadioButton, selector: "gtx-radio-button", inputs: { autofocus: "autofocus", checked: "checked", disabled: "disabled", id: "id", label: "label", name: "name", required: "required", value: "value" }, outputs: { blur: "blur", focus: "focus", change: "change" }, host: { listeners: { "keyup": "focusHandler($event)" } }, providers: [GTX_RADIO_BUTTON_VALUE_ACCESSOR], ngImport: i0, template: "<div>\n <input type=\"radio\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [checked]=\"checked\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n [value]=\"value\"\n\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n (change)=\"onInputChecked($event, input)\"\n\n [class.tabbed]=\"tabbedFocus\"\n\n #input\n >\n <label [attr.for]=\"id\" (click)=\"input.focus()\">{{ label }}</label>\n</div>\n" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: RadioButton, decorators: [{ type: Component, args: [{ selector: 'gtx-radio-button', providers: [GTX_RADIO_BUTTON_VALUE_ACCESSOR], template: "<div>\n <input type=\"radio\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [checked]=\"checked\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n [value]=\"value\"\n\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n (change)=\"onInputChecked($event, input)\"\n\n [class.tabbed]=\"tabbedFocus\"\n\n #input\n >\n <label [attr.for]=\"id\" (click)=\"input.focus()\">{{ label }}</label>\n</div>\n" }] }], ctorParameters: function () { return [{ type: RadioGroup, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Attribute, args: ['ngModel'] }] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { autofocus: [{ type: Input }], checked: [{ type: Input }], disabled: [{ type: Input }], id: [{ type: Input }], label: [{ type: Input }], name: [{ type: Input }], required: [{ type: Input }], value: [{ type: Input }], blur: [{ type: Output }], focus: [{ type: Output }], change: [{ type: Output }], focusHandler: [{ type: HostListener, args: ['keyup', ['$event']] }] } }); function randomID() { return 'radio-' + Math.random().toString(36).substr(2); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaW8tYnV0dG9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3JhZGlvLWJ1dHRvbi9yYWRpby1idXR0b24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvcmFkaW8tYnV0dG9uL3JhZGlvLWJ1dHRvbi50cGwuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0gsU0FBUyxFQUNULGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUdMLFFBQVEsRUFDUixNQUFNLEVBQ04sVUFBVSxFQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBdUIsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDOUMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGdDQUFnQyxDQUFDOztBQUcvRCxNQUFNLDhCQUE4QixHQUFHO0lBQ25DLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUM7SUFDekMsS0FBSyxFQUFFLElBQUk7Q0FDZCxDQUFDO0FBRUYsTUFBTSwrQkFBK0IsR0FBRztJQUNwQyxPQUFPLEVBQUUsaUJBQWlCO0lBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDO0lBQzFDLEtBQUssRUFBRSxJQUFJO0NBQ2QsQ0FBQztBQUVGOzs7R0FHRztBQUtILE1BQU0sT0FBTyxVQUFVO0lBV25CO1FBUFEsaUJBQVksR0FBa0IsRUFBRSxDQUFDO1FBb0RqQyxjQUFTLEdBQWEsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDO1FBQy9CLGFBQVEsR0FBYSxDQUFDLENBQU0sRUFBRSxFQUFF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O1FBQzlCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdkMsQ0FBQzs7MkhBcktRLFdBQVcsa0JBb0ZtQixVQUFVLDZCQUMxQixTQUFTOytHQXJGdkIsV0FBVyw4VEFGVCxDQUFDLCtCQUErQixDQUFDLDBCQ2pJaEQsa2dCQW1CQTsyRkRnSGEsV0FBVztrQkFMdkIsU0FBUzsrQkFDSSxrQkFBa0IsYUFFakIsQ0FBQywrQkFBK0IsQ0FBQzswREFzRkwsVUFBVTswQkFBcEMsUUFBUTs7MEJBQ1IsU0FBUzsyQkFBQyxTQUFTOzRFQWpGdkIsU0FBUztzQkFBakIsS0FBSztnQkFNTyxPQUFPO3NCQUFuQixLQUFLO2dCQXlCRyxRQUFRO3NCQUFoQixLQUFLO2dCQUtHLEVBQUU7c0JBQVYsS0FBSztnQkFLRyxLQUFLO3NCQUFiLEtBQUs7Z0JBS0csSUFBSTtzQkFBWixLQUFLO2dCQUtHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBS0csS0FBSztzQkFBYixLQUFLO2dCQUtJLElBQUk7c0JBQWIsTUFBTTtnQkFLRyxLQUFLO3NCQUFkLE1BQU07Z0JBS0csTUFBTTtzQkFBZixNQUFNO2dCQWdDTCxZQUFZO3NCQURiLFlBQVk7dUJBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDOztBQWlFckMsU0FBUyxRQUFRO0lBQ2IsT0FBTyxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQXR0cmlidXRlLFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBEaXJlY3RpdmUsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIEhvc3RMaXN0ZW5lcixcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT25Jbml0LFxuICAgIE9wdGlvbmFsLFxuICAgIE91dHB1dCxcbiAgICBmb3J3YXJkUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1J9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7S2V5Q29kZX0gZnJvbSAnLi4vLi4vY29tbW9uL2tleWNvZGVzJztcbmltcG9ydCB7Y29lcmNlVG9Cb29sZWFufSBmcm9tICcuLi8uLi9jb21tb24vY29lcmNlLXRvLWJvb2xlYW4nO1xuXG5cbmNvbnN0IEdUWF9SQURJT19HUk9VUF9WQUxVRV9BQ0NFU1NPUiA9IHtcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBSYWRpb0dyb3VwKSxcbiAgICBtdWx0aTogdHJ1ZVxufTtcblxuY29uc3QgR1RYX1JBRElPX0JVVFRPTl9WQUxVRV9BQ0NFU1NPUiA9IHtcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBSYWRpb0J1dHRvbiksXG4gICAgbXVsdGk6IHRydWVcbn07XG5cbi8qKlxuICogUmFkaW9Hcm91cCBncm91cHMgbXVsdGlwbGUge0BsaW5rIFJhZGlvQnV0dG9ufSBlbGVtZW50cyB0b2dldGhlci5cbiAqIFVzZSBuZ01vZGVsIHRvIGNvbm5lY3QgaXQgdG8gYSBmb3JtIG1vZGVsLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ2d0eC1yYWRpby1ncm91cCwgW2d0eC1yYWRpby1ncm91cF0nLFxuICAgIHByb3ZpZGVyczogW0dUWF9SQURJT19HUk9VUF9WQUxVRV9BQ0NFU1NPUl1cbn0pXG5leHBvcnQgY2xhc3MgUmFkaW9Hcm91cCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcblxuICAgIHByaXZhdGUgc3RhdGljIGluc3RhbmNlQ291bnRlcjogbnVtYmVyID0gMDtcblxuICAgIHByaXZhdGUgcmFkaW9CdXR0b25zOiBSYWRpb0J1dHRvbltdID0gW107XG4gICAgcHJpdmF0ZSBncm91cElEOiBudW1iZXI7XG5cbiAgICBnZXQgdW5pcXVlTmFtZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gJ2dyb3VwLScgKyB0aGlzLmdyb3VwSUQ7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZ3JvdXBJRCA9IFJhZGlvR3JvdXAuaW5zdGFuY2VDb3VudGVyKys7XG4gICAgfVxuXG4gICAgYWRkKHJhZGlvOiBSYWRpb0J1dHRvbik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5yYWRpb0J1dHRvbnMuaW5kZXhPZihyYWRpbykgPCAwKSB7XG4gICAgICAgICAgICB0aGlzLnJhZGlvQnV0dG9ucy5wdXNoKHJhZGlvKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbW92ZShyYWRpbzogUmFkaW9CdXR0b24pOiB2b2lkIHtcbiAgICAgICAgbGV0IHBvczogbnVtYmVyID0gdGhpcy5yYWRpb0J1dHRvbnMuaW5kZXhPZihyYWRpbyk7XG4gICAgICAgIGlmIChwb3MgPj0gMCkge1xuICAgICAgICAgICAgdGhpcy5yYWRpb0J1dHRvbnMuc3BsaWNlKHBvcywgMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByYWRpb1NlbGVjdGVkKHNlbGVjdGVkPzogUmFkaW9CdXR0b24pOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgcmFkaW8gb2YgdGhpcy5yYWRpb0J1dHRvbnMpIHtcbiAgICAgICAgICAgIGlmIChyYWRpbyAhPSBzZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgIHJhZGlvLndyaXRlVmFsdWUoc2VsZWN0ZWQgPyBzZWxlY3RlZC52YWx1ZSA6IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHNldFRpbWVvdXQgYmVjYXVzZSB0aGlzIG1ldGhvZCBpcyBpbnZva2VkIGZyb20gYSBjaGlsZCBjb21wb25lbnQgKFJhZGlvQnV0dG9uKSwgd2hpY2ggaXMgdGhlIHdyb25nIGRpcmVjdGlvblxuICAgICAgICAvLyBmb3IgY2hhbmdlIHByb3BhZ2F0aW9uICh3aGljaCBzaG91bGQgbm9ybWFsbHkgYWx3YXlzIGJlIHBhcmVudCAtPiBjaGlsZCkuIElmIHdlIHN5bmNocm9ub3VzbHkgbm93IHVwZGF0ZSB0aGVcbiAgICAgICAgLy8gbmdNb2RlbCB2YWx1ZSwgd2Ugd2lsbCBjYXVzZSBcImNoYW5nZWQgYWZ0ZXIgY2hlY2tlZFwiIGVycm9ycyBpbiBkZXYgbW9kZS5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHNlbGVjdGVkID8gc2VsZWN0ZWQudmFsdWUgOiBudWxsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IHJhZGlvIG9mIHRoaXMucmFkaW9CdXR0b25zKSB7XG4gICAgICAgICAgICByYWRpby53cml0ZVZhbHVlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKTogdm9pZCB7XG4gICAgICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgICB9XG5cbiAgICByZWdpc3Rlck9uVG91Y2hlZChmbjogRnVuY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uVG91Y2hlZDogRnVuY3Rpb24gPSAoKSA9PiB7fTtcbiAgICBwcml2YXRlIG9uQ2hhbmdlOiBGdW5jdGlvbiA9IChfOiBhbnkpID0+IHt9O1xufVxuXG5cbi8qKlxuICogUmFkaW9CdXR0b24gd3JhcHMgdGhlIG5hdGl2ZSBgPGlucHV0IHR5cGU9XCJyYWRpb1wiPmAgZm9ybSBlbGVtZW50LlxuICogVG8gY29ubmVjdCBtdWx0aXBsZSByYWRpbyBidXR0b25zIHdpdGggYSBmb3JtIHZpYSBuZ01vZGVsLFxuICogd3JhcCB0aGVtIGluIGEge0BsaW5rIFJhZGlvR3JvdXB9IChgPGd0eC1yYWRpby1ncm91cD5gKS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8Z3R4LXJhZGlvLWJ1dHRvbiBbKG5nTW9kZWwpXT1cInZhbFwiIHZhbHVlPVwiQVwiIGxhYmVsPVwiQVwiPjwvZ3R4LXJhZGlvLWJ1dHRvbj5cbiAqIDxndHgtcmFkaW8tYnV0dG9uIFsobmdNb2RlbCldPVwidmFsXCIgdmFsdWU9XCJCXCIgbGFiZWw9XCJCXCI+PC9ndHgtcmFkaW8tYnV0dG9uPlxuICogPGd0eC1yYWRpby1idXR0b24gWyhuZ01vZGVsKV09XCJ2YWxcIiB2YWx1ZT1cIkNcIiBsYWJlbD1cIkNcIj48L2d0eC1yYWRpby1idXR0b24+XG4gKiBgYGBcbiAqXG4gKiAjIyBTdGF0ZWxlc3MgTW9kZVxuICogQnkgZGVmYXVsdCwgdGhlIFJhZGlvQnV0dG9uIGtlZXBzIHRyYWNrIG9mIGl0cyBvd24gaW50ZXJuYWwgY2hlY2tlZCBzdGF0ZS4gVGhpcyBtYWtlcyBzZW5zZVxuICogZm9yIG1vc3QgdXNlIGNhc2VzLCBzdWNoIGFzIHdoZW4gdXNlZCBpbiBhIGZvcm0gYm91bmQgdG8gbmdNb2RlbC5cbiAqXG4gKiBIb3dldmVyLCBpbiBzb21lIGNhc2VzIHdlIHdhbnQgdG8gZXhwbGljaXRseSBzZXQgdGhlIHN0YXRlIGZyb20gb3V0c2lkZS4gVGhpcyBpcyBkb25lIGJ5IGJpbmRpbmdcbiAqIHRvIHRoZSA8Y29kZT5jaGVja2VkPC9jb2RlPiBhdHRyaWJ1dGUuIFdoZW4gdGhpcyBhdHRyaWJ1dGUgaXMgYm91bmQsIHRoZSBjaGVja2VkIHN0YXRlIG9mIHRoZVxuICogUmFkaW9CdXR0b24gd2lsbCAqb25seSogY2hhbmdlIHdoZW4gdGhlIHZhbHVlIG9mIHRoZSBiaW5kaW5nIGNoYW5nZXMuIENsaWNraW5nIG9uIHRoZSBSYWRpb0J1dHRvblxuICogd2lsbCBoYXZlIG5vIGVmZmVjdCBvdGhlciB0aGFuIHRvIGVtaXQgYW4gZXZlbnQgd2hpY2ggdGhlIHBhcmVudCBjYW4gdXNlIHRvIHVwZGF0ZSB0aGUgYmluZGluZy5cbiAqXG4gKiBIZXJlIGlzIGEgYmFzaWMgZXhhbXBsZSBvZiBhIHN0YXRlbGVzcyBSYWRpb0J1dHRvbiB3aGVyZSB0aGUgcGFyZW50IGNvbXBvbmVudCBtYW5hZ2VzIHRoZSBzdGF0ZTpcbiAqXG4gKiBgYGBodG1sXG4gKiA8Z3R4LXJhZGlvLWJ1dHRvbiBbY2hlY2tlZF09XCJpc0NoZWNrZWRcIj48L2d0eC1jaGVja2JveD5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2d0eC1yYWRpby1idXR0b24nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9yYWRpby1idXR0b24udHBsLmh0bWwnLFxuICAgIHByb3ZpZGVyczogW0dUWF9SQURJT19CVVRUT05fVkFMVUVfQUNDRVNTT1JdXG59KVxuZXhwb3J0IGNsYXNzIFJhZGlvQnV0dG9uIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSByYWRpbyBidXR0b24gdG8gYmUgYXV0by1mb2N1c2VkLiBIYW5kbGVkIGJ5IGBBdXRvZm9jdXNEaXJlY3RpdmVgLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIGF1dG9mb2N1czogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNoZWNrZWQgc3RhdGUgb2YgdGhlIGNvbnRyb2wuIFdoZW4gc2V0LCB0aGUgUmFkaW9CdXR0b24gd2lsbCBiZVxuICAgICAqIGluIHN0YXRlbGVzcyBtb2RlLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIGdldCBjaGVja2VkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dENoZWNrZWQ7XG4gICAgfVxuICAgIHNldCBjaGVja2VkKHZhbDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLnN0YXRlbGVzc01vZGUgPSB0cnVlO1xuICAgICAgICBpZiAodmFsICE9IHRoaXMuaW5wdXRDaGVja2VkKSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0Q2hlY2tlZCA9IGNvZXJjZVRvQm9vbGVhbih2YWwpO1xuICAgICAgICAgICAgaWYgKHZhbCAmJiB0aGlzLmdyb3VwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ncm91cC5yYWRpb1NlbGVjdGVkKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMub25DaGFuZ2UodGhpcy52YWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ncm91cCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdyb3VwLnJhZGlvU2VsZWN0ZWQobnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jaGFuZ2UuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkaXNhYmxlZCBzdGF0ZSBvZiB0aGUgY29udHJvbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBJRCBvZiB0aGUgY29udHJvbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIGlkOiBzdHJpbmcgPSByYW5kb21JRCgpO1xuXG4gICAgLyoqXG4gICAgICogTGFiZWwgZm9yIHRoZSByYWRpbyBidXR0b25cbiAgICAgKi9cbiAgICBASW5wdXQoKSBsYWJlbDogc3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBOYW1lIG9mIHRoZSBpbnB1dFxuICAgICAqL1xuICAgIEBJbnB1dCgpIG5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHJlcXVpcmVkIHN0YXRlXG4gICAgICovXG4gICAgQElucHV0KCkgcmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGlucHV0XG4gICAgICovXG4gICAgQElucHV0KCkgdmFsdWU6IGFueSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQmx1ciBldmVudFxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBibHVyID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPih0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIEZvY3VzIGV2ZW50XG4gICAgICovXG4gICAgQE91dHB1dCgpIGZvY3VzID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPih0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIENoYW5nZSBldmVudFxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBjaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4odHJ1ZSk7XG5cbiAgICB0YWJiZWRGb2N1czogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHByaXZhdGUgaW5wdXRDaGVja2VkOiBib29sZWFuID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogU2VlIG5vdGUgYWJvdmUgb24gc3RhdGVsZXNzIG1vZGUuXG4gICAgICovXG4gICAgcHJpdmF0ZSBzdGF0ZWxlc3NNb2RlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBwcml2YXRlIGdyb3VwOiBSYWRpb0dyb3VwLFxuICAgICAgICAgICAgICAgIEBBdHRyaWJ1dGUoJ25nTW9kZWwnKSBtb2RlbEF0dHJpYjogc3RyaW5nLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmKSB7XG5cbiAgICAgICAgLy8gUHJlLXNldCBhIGNvbW1vbiBpbnB1dCBuYW1lIGZvciBncm91cGVkIGlucHV0IGVsZW1lbnRzXG4gICAgICAgIGlmIChncm91cCkge1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gZ3JvdXAudW5pcXVlTmFtZTtcbiAgICAgICAgfSBlbHNlIGlmIChtb2RlbEF0dHJpYikge1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gbW9kZWxBdHRyaWI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkJsdXIoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYmx1ci5lbWl0KHRoaXMuY2hlY2tlZCk7XG4gICAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgICAgIHRoaXMudGFiYmVkRm9jdXMgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBvbkZvY3VzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmZvY3VzLmVtaXQodGhpcy5jaGVja2VkKTtcbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdrZXl1cCcsIFsnJGV2ZW50J10pXG4gICAgICBmb2N1c0hhbmRsZXIoZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgICAgICAgIGlmIChlLmtleUNvZGUgPT09IEtleUNvZGUuVGFiKSB7XG4gICAgICAgICAgICAgIGlmICghdGhpcy50YWJiZWRGb2N1cykge1xuICAgICAgICAgICAgICAgICAgdGhpcy50YWJiZWRGb2N1cyA9IHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG5cbiAgICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pbnB1dENoZWNrZWQgPSAodmFsdWUgPT09IHRoaXMudmFsdWUpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5pbnB1dENoZWNrZWQpIHtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UodGhpcy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ncm91cCkge1xuICAgICAgICAgICAgdGhpcy5ncm91cC5hZGQodGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dENoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmdyb3VwLnJhZGlvU2VsZWN0ZWQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZ3JvdXApIHtcbiAgICAgICAgICAgIHRoaXMuZ3JvdXAucmVtb3ZlKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25JbnB1dENoZWNrZWQoZTogRXZlbnQsIGlucHV0OiBIVE1MSW5wdXRFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0YXRlbGVzc01vZGUpIHtcbiAgICAgICAgICAgIGxldCBuZXdTdGF0ZSA9IGlucHV0LmNoZWNrZWQ7XG4gICAgICAgICAgICBpZiAoaW5wdXQuY2hlY2tlZCAhPT0gdGhpcy5pbnB1dENoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gISF0aGlzLmlucHV0Q2hlY2tlZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQobmV3U3RhdGUpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbnB1dENoZWNrZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMudmFsdWUpO1xuICAgICAgICB0aGlzLmNoYW5nZS5lbWl0KHRoaXMudmFsdWUpO1xuICAgICAgICBpZiAodGhpcy5ncm91cCkge1xuICAgICAgICAgICAgdGhpcy5ncm91cC5yYWRpb1NlbGVjdGVkKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKTogdm9pZCB7IHRoaXMub25DaGFuZ2UgPSBmbjsgfVxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbik6IHZvaWQgeyB0aGlzLm9uVG91Y2hlZCA9IGZuOyB9XG4gICAgc2V0RGlzYWJsZWRTdGF0ZShkaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc2FibGVkID0gZGlzYWJsZWQ7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkNoYW5nZTogRnVuY3Rpb24gPSAoXzogYW55KSA9PiB7fTtcbiAgICBwcml2YXRlIG9uVG91Y2hlZDogRnVuY3Rpb24gPSAoKSA9PiB7fTtcbn1cblxuZnVuY3Rpb24gcmFuZG9tSUQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ3JhZGlvLScgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMik7XG59XG4iLCI8ZGl2PlxuICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIlxuICAgICAgICAgICBbYXR0ci5pZF09XCJpZFwiXG4gICAgICAgICAgIFthdHRyLm5hbWVdPVwibmFtZVwiXG4gICAgICAgICAgIFtjaGVja2VkXT1cImNoZWNrZWRcIlxuICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgICBbdmFsdWVdPVwidmFsdWVcIlxuXG4gICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcbiAgICAgICAgICAgKGZvY3VzKT1cIm9uRm9jdXMoKVwiXG4gICAgICAgICAgIChjaGFuZ2UpPVwib25JbnB1dENoZWNrZWQoJGV2ZW50LCBpbnB1dClcIlxuXG4gICAgICAgICAgIFtjbGFzcy50YWJiZWRdPVwidGFiYmVkRm9jdXNcIlxuXG4gICAgICAgICAgICNpbnB1dFxuICAgID5cbiAgICA8bGFiZWwgW2F0dHIuZm9yXT1cImlkXCIgKGNsaWNrKT1cImlucHV0LmZvY3VzKClcIj57eyBsYWJlbCB9fTwvbGFiZWw+XG48L2Rpdj5cbiJdfQ==