gentics-ui-core
Version:
This is the common core framework for the Gentics CMS and Mesh UI, and other Angular applications.
216 lines • 24.5 kB
JavaScript
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, HostListener, Input, Output, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { KeyCode } from '../../common/keycodes';
import * as i0 from "@angular/core";
const GTX_CHECKBOX_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Checkbox),
multi: true
};
/**
* Checkbox wraps the native `<input type="checkbox">` form element.
*
* ```html
* <gtx-checkbox [(ngModel)]="isOkay" label="Is it okay?"></gtx-checkbox>
* <gtx-checkbox [(ngModel)]="checkStates.B" value="B" label="B"></gtx-checkbox>
* ```
*
* ## Stateless Mode
* By default, the Checkbox keeps track of its own internal checked state. This makes sense
* for most use cases, such as when used in a form bound to NgControl.
*
* 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
* Checkbox will *only* change when the value of the binding changes. Clicking on the Checkbox
* 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 checkbox where the parent component manages the state:
*
* ```html
* <gtx-checkbox [checked]="isChecked"
* (change)="isChecked = $event"></gtx-checkbox>
* ```
*/
export class Checkbox {
constructor(changeDetector) {
this.changeDetector = changeDetector;
/**
* Sets the checkbox to be auto-focused. Handled by `AutofocusDirective`.
*/
this.autofocus = false;
/**
* Set the checkbox to its disabled state.
*/
this.disabled = false;
/**
* Checkbox ID
*/
this.id = randomID();
/**
* Label for the checkbox
*/
this.label = '';
/**
* Sets the required property
*/
this.required = false;
/**
* The value of the checkbox
*/
this.value = '';
/**
* Blur event
*/
this.blur = new EventEmitter();
/**
* Focus event
*/
this.focus = new EventEmitter();
/**
* Change event
*/
this.change = new EventEmitter();
this.checkState = false;
this.tabbedFocus = false;
/**
* See note above on stateless mode.
*/
this.statelessMode = false;
this.onChange = () => { };
this.onTouched = () => { };
}
/**
* Checked state of the checkbox. When set, the Checkbox will be
* in stateless mode.
*/
get checked() {
return this.checkState === true;
}
set checked(value) {
this.statelessMode = true;
let val = value;
let nowChecked = val === true || val === 'true' || val === '';
if (nowChecked != this.checkState) {
this.onChange(this.checkState = nowChecked);
this.changeDetector.markForCheck();
}
}
/**
* Set to "indeterminate" for an indeterminate state (-)
*/
get indeterminate() {
return this.checkState === 'indeterminate';
}
set indeterminate(val) {
if (val != (this.checkState === 'indeterminate')) {
this.checkState = val ? 'indeterminate' : false;
this.change.emit(this.checkState);
this.onChange(this.checkState);
}
}
onBlur() {
this.blur.emit(this.checkState);
this.onTouched();
this.tabbedFocus = false;
}
onFocus() {
this.focus.emit(this.checkState);
}
focusHandler(e) {
if (e.keyCode === KeyCode.Tab) {
if (!this.tabbedFocus) {
this.tabbedFocus = true;
}
}
}
writeValue(value) {
if (value !== this.checkState) {
this.checkState = value;
this.changeDetector.markForCheck();
}
}
ngOnInit() {
this.onChange(this.checkState);
}
ngAfterViewInit() {
this.fixInitialAnimation();
}
onInputChanged(e, input) {
if (e) {
e.stopPropagation();
}
let newState = input.indeterminate ? 'indeterminate' : input.checked;
if (this.statelessMode) {
if (input.checked !== this.checkState) {
input.checked = !!this.checkState;
}
this.change.emit(newState);
return false;
}
if (newState != this.checkState) {
this.checkState = newState;
this.onChange(newState);
this.change.emit(newState);
return true;
}
}
registerOnChange(fn) { this.onChange = fn; }
registerOnTouched(fn) { this.onTouched = fn; }
setDisabledState(disabled) {
this.disabled = disabled;
this.changeDetector.markForCheck();
}
/**
* This is a hacky fix to prevent Materialize from animating ticked checkboxes which
* kicks in when a checkbox is added to the dom with checked=false and immediately
* set to checked=true.
*/
fixInitialAnimation() {
if (this.labelElement && this.labelElement.nativeElement) {
let label = this.labelElement.nativeElement;
label.style.display = 'none';
let ignored = label.offsetWidth;
label.style.display = '';
}
}
}
/** @nocollapse */ Checkbox.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: Checkbox, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ Checkbox.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: Checkbox, selector: "gtx-checkbox", inputs: { autofocus: "autofocus", checked: "checked", indeterminate: "indeterminate", 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_CHECKBOX_VALUE_ACCESSOR], viewQueries: [{ propertyName: "labelElement", first: true, predicate: ["labelElement"], descendants: true, static: true }], ngImport: i0, template: "<div>\n <input type=\"checkbox\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [checked]=\"checkState === true\"\n [indeterminate]=\"checkState === 'indeterminate'\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n [value]=\"value\"\n\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n (change)=\"onInputChanged($event, input)\"\n\n [class.tabbed]=\"tabbedFocus\"\n\n #input\n >\n <label [attr.for]=\"id\" #labelElement>{{ label }}</label>\n</div>\n" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: Checkbox, decorators: [{
type: Component,
args: [{ selector: 'gtx-checkbox', providers: [GTX_CHECKBOX_VALUE_ACCESSOR], template: "<div>\n <input type=\"checkbox\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [checked]=\"checkState === true\"\n [indeterminate]=\"checkState === 'indeterminate'\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n [value]=\"value\"\n\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n (change)=\"onInputChanged($event, input)\"\n\n [class.tabbed]=\"tabbedFocus\"\n\n #input\n >\n <label [attr.for]=\"id\" #labelElement>{{ label }}</label>\n</div>\n" }]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { autofocus: [{
type: Input
}], checked: [{
type: Input
}], indeterminate: [{
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
}], labelElement: [{
type: ViewChild,
args: ['labelElement', { static: true }]
}], focusHandler: [{
type: HostListener,
args: ['keyup', ['$event']]
}] } });
function randomID() {
return 'checkbox-' + Math.random().toString(36).substr(2);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2tib3guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvY2hlY2tib3gvY2hlY2tib3guY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvY2hlY2tib3gvY2hlY2tib3gudHBsLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBdUIsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7O0FBSTlDLE1BQU0sMkJBQTJCLEdBQUc7SUFDaEMsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQztJQUN2QyxLQUFLLEVBQUUsSUFBSTtDQUNkLENBQUM7QUFFRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFNSCxNQUFNLE9BQU8sUUFBUTtJQXNGakIsWUFBb0IsY0FBaUM7UUFBakMsbUJBQWMsR0FBZCxjQUFjLENBQW1CO1FBckZyRDs7V0FFRztRQUNNLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFpQ3BDOztXQUVHO1FBQ00sYUFBUSxHQUFZLEtBQUssQ0FBQztRQUNuQzs7V0FFRztRQUNNLE9BQUUsR0FBVyxRQUFRLEVBQUUsQ0FBQztRQUNqQzs7V0FFRztRQUNNLFVBQUssR0FBVyxFQUFFLENBQUM7UUFLNUI7O1dBRUc7UUFDTSxhQUFRLEdBQVksS0FBSyxDQUFDO1FBQ25DOztXQUVHO1FBQ00sVUFBSyxHQUFRLEVBQUUsQ0FBQztRQUV6Qjs7V0FFRztRQUNPLFNBQUksR0FBRyxJQUFJLFlBQVksRUFBYyxDQUFDO1FBQ2hEOztXQUVHO1FBQ08sVUFBSyxHQUFHLElBQUksWUFBWSxFQUFjLENBQUM7UUFDakQ7O1dBRUc7UUFDTyxXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQWMsQ0FBQztRQUVsRCxlQUFVLEdBQWUsS0FBSyxDQUFDO1FBQy9CLGdCQUFXLEdBQVksS0FBSyxDQUFDO1FBSTdCOztXQUVHO1FBQ0ssa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFrRS9CLGFBQVEsR0FBYSxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFDOUIsY0FBUyxHQUFhLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztJQWhFa0IsQ0FBQztJQWhGMUQ7OztPQUdHO0lBQ0gsSUFBYSxPQUFPO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUM7SUFDcEMsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLEtBQWM7UUFDdEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDMUIsSUFBSSxHQUFHLEdBQWtELEtBQUssQ0FBQztRQUMvRCxJQUFJLFVBQVUsR0FBRyxHQUFHLEtBQUssSUFBSSxJQUFVLEdBQUcsS0FBSyxNQUFNLElBQVUsR0FBRyxLQUFLLEVBQUUsQ0FBQztRQUMxRSxJQUFJLFVBQVUsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ3RDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBYSxhQUFhO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFVBQVUsS0FBSyxlQUFlLENBQUM7SUFDL0MsQ0FBQztJQUNELElBQUksYUFBYSxDQUFDLEdBQVk7UUFDMUIsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxLQUFLLGVBQWUsQ0FBQyxFQUFFO1lBQzlDLElBQUksQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUNoRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDbEM7SUFDTCxDQUFDO0lBcURELE1BQU07UUFDRixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQzdCLENBQUM7SUFFRCxPQUFPO1FBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFHRCxZQUFZLENBQUMsQ0FBZ0I7UUFDekIsSUFBSSxDQUFDLENBQUMsT0FBTyxLQUFLLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2FBQzNCO1NBQ0o7SUFDTCxDQUFDO0lBRUQsVUFBVSxDQUFDLEtBQVU7UUFDakIsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUMzQixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUN4QixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ3RDO0lBQ0wsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsZUFBZTtRQUNYLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxjQUFjLENBQUMsQ0FBUSxFQUFFLEtBQXVCO1FBQzVDLElBQUksQ0FBQyxFQUFFO1lBQ0gsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1NBQ3ZCO1FBQ0QsSUFBSSxRQUFRLEdBQWUsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQ2pGLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNwQixJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDbkMsS0FBSyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQzthQUNyQztZQUNELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO1FBQ0QsSUFBSSxRQUFRLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUM3QixJQUFJLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQztZQUMzQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sSUFBSSxDQUFDO1NBQ2Y7SUFDTCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsRUFBWSxJQUFVLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM1RCxpQkFBaUIsQ0FBQyxFQUFZLElBQVUsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzlELGdCQUFnQixDQUFDLFFBQWlCO1FBQzlCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUtEOzs7O09BSUc7SUFDSyxtQkFBbUI7UUFDdkIsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFO1lBQ3RELElBQUksS0FBSyxHQUFxQixJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztZQUM5RCxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7WUFDN0IsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQztZQUNoQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7U0FDNUI7SUFDTCxDQUFDOzt3SEFwS1EsUUFBUTs0R0FBUixRQUFRLDBWQUZOLENBQUMsMkJBQTJCLENBQUMsc0pDakQ1Qyxva0JBb0JBOzJGRCtCYSxRQUFRO2tCQUxwQixTQUFTOytCQUNJLGNBQWMsYUFFYixDQUFDLDJCQUEyQixDQUFDO3dHQU0vQixTQUFTO3NCQUFqQixLQUFLO2dCQU1PLE9BQU87c0JBQW5CLEtBQUs7Z0JBZ0JPLGFBQWE7c0JBQXpCLEtBQUs7Z0JBY0csUUFBUTtzQkFBaEIsS0FBSztnQkFJRyxFQUFFO3NCQUFWLEtBQUs7Z0JBSUcsS0FBSztzQkFBYixLQUFLO2dCQUlHLElBQUk7c0JBQVosS0FBSztnQkFJRyxRQUFRO3NCQUFoQixLQUFLO2dCQUlHLEtBQUs7c0JBQWIsS0FBSztnQkFLSSxJQUFJO3NCQUFiLE1BQU07Z0JBSUcsS0FBSztzQkFBZCxNQUFNO2dCQUlHLE1BQU07c0JBQWYsTUFBTTtnQkFLc0MsWUFBWTtzQkFBeEQsU0FBUzt1QkFBQyxjQUFjLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQXFCM0MsWUFBWTtzQkFEWCxZQUFZO3VCQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQzs7QUFxRXJDLFNBQVMsUUFBUTtJQUNiLE9BQU8sV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBmb3J3YXJkUmVmLFxuICAgIEhvc3RMaXN0ZW5lcixcbiAgICBJbnB1dCxcbiAgICBPdXRwdXQsXG4gICAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1J9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7S2V5Q29kZX0gZnJvbSAnLi4vLi4vY29tbW9uL2tleWNvZGVzJztcblxuZXhwb3J0IHR5cGUgQ2hlY2tTdGF0ZSA9IGJvb2xlYW4gfCAnaW5kZXRlcm1pbmF0ZSc7XG5cbmNvbnN0IEdUWF9DSEVDS0JPWF9WQUxVRV9BQ0NFU1NPUiA9IHtcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBDaGVja2JveCksXG4gICAgbXVsdGk6IHRydWVcbn07XG5cbi8qKlxuICogQ2hlY2tib3ggd3JhcHMgdGhlIG5hdGl2ZSBgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiPmAgZm9ybSBlbGVtZW50LlxuICpcbiAqIGBgYGh0bWxcbiAqIDxndHgtY2hlY2tib3ggWyhuZ01vZGVsKV09XCJpc09rYXlcIiBsYWJlbD1cIklzIGl0IG9rYXk/XCI+PC9ndHgtY2hlY2tib3g+XG4gKiA8Z3R4LWNoZWNrYm94IFsobmdNb2RlbCldPVwiY2hlY2tTdGF0ZXMuQlwiIHZhbHVlPVwiQlwiIGxhYmVsPVwiQlwiPjwvZ3R4LWNoZWNrYm94PlxuICogYGBgXG4gKlxuICogIyMgU3RhdGVsZXNzIE1vZGVcbiAqIEJ5IGRlZmF1bHQsIHRoZSBDaGVja2JveCBrZWVwcyB0cmFjayBvZiBpdHMgb3duIGludGVybmFsIGNoZWNrZWQgc3RhdGUuIFRoaXMgbWFrZXMgc2Vuc2VcbiAqIGZvciBtb3N0IHVzZSBjYXNlcywgc3VjaCBhcyB3aGVuIHVzZWQgaW4gYSBmb3JtIGJvdW5kIHRvIE5nQ29udHJvbC5cbiAqXG4gKiBIb3dldmVyLCBpbiBzb21lIGNhc2VzIHdlIHdhbnQgdG8gZXhwbGljaXRseSBzZXQgdGhlIHN0YXRlIGZyb20gb3V0c2lkZS4gVGhpcyBpcyBkb25lIGJ5IGJpbmRpbmdcbiAqIHRvIHRoZSA8Y29kZT5jaGVja2VkPC9jb2RlPiBhdHRyaWJ1dGUuIFdoZW4gdGhpcyBhdHRyaWJ1dGUgaXMgYm91bmQsIHRoZSBjaGVja2VkIHN0YXRlIG9mIHRoZVxuICogQ2hlY2tib3ggd2lsbCAqb25seSogY2hhbmdlIHdoZW4gdGhlIHZhbHVlIG9mIHRoZSBiaW5kaW5nIGNoYW5nZXMuIENsaWNraW5nIG9uIHRoZSBDaGVja2JveFxuICogd2lsbCBoYXZlIG5vIGVmZmVjdCBvdGhlciB0aGFuIHRvIGVtaXQgYW4gZXZlbnQgd2hpY2ggdGhlIHBhcmVudCBjYW4gdXNlIHRvIHVwZGF0ZSB0aGUgYmluZGluZy5cbiAqXG4gKiBIZXJlIGlzIGEgYmFzaWMgZXhhbXBsZSBvZiBhIHN0YXRlbGVzcyBjaGVja2JveCB3aGVyZSB0aGUgcGFyZW50IGNvbXBvbmVudCBtYW5hZ2VzIHRoZSBzdGF0ZTpcbiAqXG4gKiBgYGBodG1sXG4gKiA8Z3R4LWNoZWNrYm94IFtjaGVja2VkXT1cImlzQ2hlY2tlZFwiXG4gKiAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiaXNDaGVja2VkID0gJGV2ZW50XCI+PC9ndHgtY2hlY2tib3g+XG4gKiBgYGBcbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdndHgtY2hlY2tib3gnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jaGVja2JveC50cGwuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbR1RYX0NIRUNLQk9YX1ZBTFVFX0FDQ0VTU09SXVxufSlcbmV4cG9ydCBjbGFzcyBDaGVja2JveCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBjaGVja2JveCB0byBiZSBhdXRvLWZvY3VzZWQuIEhhbmRsZWQgYnkgYEF1dG9mb2N1c0RpcmVjdGl2ZWAuXG4gICAgICovXG4gICAgQElucHV0KCkgYXV0b2ZvY3VzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja2VkIHN0YXRlIG9mIHRoZSBjaGVja2JveC4gV2hlbiBzZXQsIHRoZSBDaGVja2JveCB3aWxsIGJlXG4gICAgICogaW4gc3RhdGVsZXNzIG1vZGUuXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IGNoZWNrZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoZWNrU3RhdGUgPT09IHRydWU7XG4gICAgfVxuICAgIHNldCBjaGVja2VkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuc3RhdGVsZXNzTW9kZSA9IHRydWU7XG4gICAgICAgIGxldCB2YWw6IGJvb2xlYW4gfCAndHJ1ZScgfCAnJyB8ICdpbmRldGVybWluYXRlJyA9IDxhbnk+IHZhbHVlO1xuICAgICAgICBsZXQgbm93Q2hlY2tlZCA9IHZhbCA9PT0gdHJ1ZSB8fCA8YW55PiB2YWwgPT09ICd0cnVlJyB8fCA8YW55PiB2YWwgPT09ICcnO1xuICAgICAgICBpZiAobm93Q2hlY2tlZCAhPSB0aGlzLmNoZWNrU3RhdGUpIHtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UodGhpcy5jaGVja1N0YXRlID0gbm93Q2hlY2tlZCk7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRvIFwiaW5kZXRlcm1pbmF0ZVwiIGZvciBhbiBpbmRldGVybWluYXRlIHN0YXRlICgtKVxuICAgICAqL1xuICAgIEBJbnB1dCgpIGdldCBpbmRldGVybWluYXRlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGVja1N0YXRlID09PSAnaW5kZXRlcm1pbmF0ZSc7XG4gICAgfVxuICAgIHNldCBpbmRldGVybWluYXRlKHZhbDogYm9vbGVhbikge1xuICAgICAgICBpZiAodmFsICE9ICh0aGlzLmNoZWNrU3RhdGUgPT09ICdpbmRldGVybWluYXRlJykpIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tTdGF0ZSA9IHZhbCA/ICdpbmRldGVybWluYXRlJyA6IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2UuZW1pdCh0aGlzLmNoZWNrU3RhdGUpO1xuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZSh0aGlzLmNoZWNrU3RhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjaGVja2JveCB0byBpdHMgZGlzYWJsZWQgc3RhdGUuXG4gICAgICovXG4gICAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBDaGVja2JveCBJRFxuICAgICAqL1xuICAgIEBJbnB1dCgpIGlkOiBzdHJpbmcgPSByYW5kb21JRCgpO1xuICAgIC8qKlxuICAgICAqIExhYmVsIGZvciB0aGUgY2hlY2tib3hcbiAgICAgKi9cbiAgICBASW5wdXQoKSBsYWJlbDogc3RyaW5nID0gJyc7XG4gICAgLyoqXG4gICAgICogRm9ybSBuYW1lIGZvciB0aGUgY2hlY2tib3hcbiAgICAgKi9cbiAgICBASW5wdXQoKSBuYW1lOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcmVxdWlyZWQgcHJvcGVydHlcbiAgICAgKi9cbiAgICBASW5wdXQoKSByZXF1aXJlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIFRoZSB2YWx1ZSBvZiB0aGUgY2hlY2tib3hcbiAgICAgKi9cbiAgICBASW5wdXQoKSB2YWx1ZTogYW55ID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBCbHVyIGV2ZW50XG4gICAgICovXG4gICAgQE91dHB1dCgpIGJsdXIgPSBuZXcgRXZlbnRFbWl0dGVyPENoZWNrU3RhdGU+KCk7XG4gICAgLyoqXG4gICAgICogRm9jdXMgZXZlbnRcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgZm9jdXMgPSBuZXcgRXZlbnRFbWl0dGVyPENoZWNrU3RhdGU+KCk7XG4gICAgLyoqXG4gICAgICogQ2hhbmdlIGV2ZW50XG4gICAgICovXG4gICAgQE91dHB1dCgpIGNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hlY2tTdGF0ZT4oKTtcblxuICAgIGNoZWNrU3RhdGU6IENoZWNrU3RhdGUgPSBmYWxzZTtcbiAgICB0YWJiZWRGb2N1czogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgQFZpZXdDaGlsZCgnbGFiZWxFbGVtZW50JywgeyBzdGF0aWM6IHRydWUgfSkgbGFiZWxFbGVtZW50OiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogU2VlIG5vdGUgYWJvdmUgb24gc3RhdGVsZXNzIG1vZGUuXG4gICAgICovXG4gICAgcHJpdmF0ZSBzdGF0ZWxlc3NNb2RlOiBib29sZWFuID0gZmFsc2U7XG5cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmKSB7IH1cblxuICAgIG9uQmx1cigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5ibHVyLmVtaXQodGhpcy5jaGVja1N0YXRlKTtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICAgICAgdGhpcy50YWJiZWRGb2N1cyA9IGZhbHNlO1xuICAgIH1cblxuICAgIG9uRm9jdXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZm9jdXMuZW1pdCh0aGlzLmNoZWNrU3RhdGUpO1xuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ2tleXVwJywgWyckZXZlbnQnXSlcbiAgICBmb2N1c0hhbmRsZXIoZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgICAgICBpZiAoZS5rZXlDb2RlID09PSBLZXlDb2RlLlRhYikge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnRhYmJlZEZvY3VzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YWJiZWRGb2N1cyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgaWYgKHZhbHVlICE9PSB0aGlzLmNoZWNrU3RhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tTdGF0ZSA9IHZhbHVlO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuY2hlY2tTdGF0ZSk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmZpeEluaXRpYWxBbmltYXRpb24oKTtcbiAgICB9XG5cbiAgICBvbklucHV0Q2hhbmdlZChlOiBFdmVudCwgaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGUpIHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG5ld1N0YXRlOiBDaGVja1N0YXRlID0gaW5wdXQuaW5kZXRlcm1pbmF0ZSA/ICdpbmRldGVybWluYXRlJyA6IGlucHV0LmNoZWNrZWQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlbGVzc01vZGUpIHtcbiAgICAgICAgICAgIGlmIChpbnB1dC5jaGVja2VkICE9PSB0aGlzLmNoZWNrU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gISF0aGlzLmNoZWNrU3RhdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNoYW5nZS5lbWl0KG5ld1N0YXRlKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV3U3RhdGUgIT0gdGhpcy5jaGVja1N0YXRlKSB7XG4gICAgICAgICAgICB0aGlzLmNoZWNrU3RhdGUgPSBuZXdTdGF0ZTtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UobmV3U3RhdGUpO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2UuZW1pdChuZXdTdGF0ZSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKTogdm9pZCB7IHRoaXMub25DaGFuZ2UgPSBmbjsgfVxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbik6IHZvaWQgeyB0aGlzLm9uVG91Y2hlZCA9IGZuOyB9XG4gICAgc2V0RGlzYWJsZWRTdGF0ZShkaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc2FibGVkID0gZGlzYWJsZWQ7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkNoYW5nZTogRnVuY3Rpb24gPSAoKSA9PiB7fTtcbiAgICBwcml2YXRlIG9uVG91Y2hlZDogRnVuY3Rpb24gPSAoKSA9PiB7fTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgYSBoYWNreSBmaXggdG8gcHJldmVudCBNYXRlcmlhbGl6ZSBmcm9tIGFuaW1hdGluZyB0aWNrZWQgY2hlY2tib3hlcyB3aGljaFxuICAgICAqIGtpY2tzIGluIHdoZW4gYSBjaGVja2JveCBpcyBhZGRlZCB0byB0aGUgZG9tIHdpdGggY2hlY2tlZD1mYWxzZSBhbmQgaW1tZWRpYXRlbHlcbiAgICAgKiBzZXQgdG8gY2hlY2tlZD10cnVlLlxuICAgICAqL1xuICAgIHByaXZhdGUgZml4SW5pdGlhbEFuaW1hdGlvbigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMubGFiZWxFbGVtZW50ICYmIHRoaXMubGFiZWxFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCBsYWJlbDogSFRNTExhYmVsRWxlbWVudCA9IHRoaXMubGFiZWxFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBsYWJlbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgbGV0IGlnbm9yZWQgPSBsYWJlbC5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgIGxhYmVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gcmFuZG9tSUQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ2NoZWNrYm94LScgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMik7XG59XG4iLCI8ZGl2PlxuICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICBbYXR0ci5pZF09XCJpZFwiXG4gICAgICAgICAgIFthdHRyLm5hbWVdPVwibmFtZVwiXG4gICAgICAgICAgIFtjaGVja2VkXT1cImNoZWNrU3RhdGUgPT09IHRydWVcIlxuICAgICAgICAgICBbaW5kZXRlcm1pbmF0ZV09XCJjaGVja1N0YXRlID09PSAnaW5kZXRlcm1pbmF0ZSdcIlxuICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgICBbdmFsdWVdPVwidmFsdWVcIlxuXG4gICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcbiAgICAgICAgICAgKGZvY3VzKT1cIm9uRm9jdXMoKVwiXG4gICAgICAgICAgIChjaGFuZ2UpPVwib25JbnB1dENoYW5nZWQoJGV2ZW50LCBpbnB1dClcIlxuXG4gICAgICAgICAgIFtjbGFzcy50YWJiZWRdPVwidGFiYmVkRm9jdXNcIlxuXG4gICAgICAgICAgICNpbnB1dFxuICAgID5cbiAgICA8bGFiZWwgW2F0dHIuZm9yXT1cImlkXCIgI2xhYmVsRWxlbWVudD57eyBsYWJlbCB9fTwvbGFiZWw+XG48L2Rpdj5cbiJdfQ==