@tangential/input-widgets
Version:
Input Widgets with persistable, dynamic configuration.
254 lines • 25.8 kB
JavaScript
import { ChangeDetectorRef, Component, EventEmitter, forwardRef, HostBinding, Input, Output, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Hacks } from '@tangential/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@tangential/components";
/**
* Provider Expression that allows this widget to register as a ControlValueAccessor.
* This allows it to support [(ngModel)].
* @docs-private
*/
export const TANJ_NUMBER_SPINNER_WIDGET_VIEW_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumberSpinnerWidgetComponent),
multi: true
};
export class NumberSpinnerWidgetChange {
constructor(source, value) {
this.source = source;
this.value = value;
}
}
export class NumberSpinnerWidgetComponent {
constructor(changeDetectorRef) {
this.changeDetectorRef = changeDetectorRef;
// turn this into a class
this.flex = '';
this.flexLayout = 'column';
this.flexLayoutAlign = 'start';
this.value = 0;
this.valueChange = new EventEmitter(false);
this.labelPosition = 'before';
this.disabled = false;
this.hideLabel = false;
this.onlyLabel = false;
/**
* Configuration Fields
*/
this.label = '';
this.defaultValue = 0;
this.max = 10;
this.min = 0;
this.step = 1;
/* end Configuration Fields */
this.change = new EventEmitter(false);
this.keyboardInputToggled = false;
this.onTouched = () => { };
this.controlValueAccessorChangeFn = (value) => { };
}
ngOnInit() {
Hacks.materialDesignPlaceholderText(this.changeDetectorRef);
}
ngOnChanges(changes) {
}
handleValueChange(value) {
if (!this.disabled) {
this.value = value;
this.valueChange.emit(this.value);
this.emitChangeEvent();
}
}
onPreviousValueRequest() {
if (!this.disabled) {
const v = this.previousValue();
if (v !== null) {
this.handleValueChange(v);
}
}
}
onNextValueRequest() {
if (!this.disabled) {
const v = this.nextValue();
if (v !== null) {
this.handleValueChange(v);
}
}
}
nextValue() {
let v = this.value + this.step;
if (v > this.max) {
v = this.max;
}
return v;
}
previousValue() {
let v = this.value - this.step;
if (v < this.min) {
v = this.min;
}
return v;
}
swipeUp(event) {
this.onNextValueRequest();
}
swipeDown(event) {
this.onPreviousValueRequest();
}
onKeyboardInputRequest(event) {
this.keyboardInputToggled = this.disabled ? false : !this.keyboardInputToggled;
}
/**
* Boilerplate / required for Angular
*/
emitChangeEvent() {
this.controlValueAccessorChangeFn(this.value);
this.change.emit(new NumberSpinnerWidgetChange(this, this.value));
}
writeValue(value) {
this.value = value;
}
registerOnChange(fn) {
this.controlValueAccessorChangeFn = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* Sets the input's disabled state. Implemented as a part of ControlValueAccessor.
* @param isDisabled Whether the input should be disabled.
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
}
NumberSpinnerWidgetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: NumberSpinnerWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
NumberSpinnerWidgetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: NumberSpinnerWidgetComponent, selector: "tanj-number-spinner-widget", inputs: { value: "value", labelPosition: "labelPosition", disabled: "disabled", hideLabel: "hideLabel", onlyLabel: "onlyLabel", label: "label", defaultValue: "defaultValue", max: "max", min: "min", step: "step" }, outputs: { valueChange: "valueChange", change: "change" }, host: { properties: { "attr.flex": "this.flex", "attr.layout": "this.flexLayout", "attr.layout-align": "this.flexLayoutAlign" } }, providers: [TANJ_NUMBER_SPINNER_WIDGET_VIEW_CONTROL_VALUE_ACCESSOR], usesOnChanges: true, ngImport: i0, template: `<!-- -->
<div flex
class="tanj-input-template tanj-mode-edit"
[ngClass]="{'tanj-disabled': disabled}"
layout="row" layout-align="center center">
<span *ngIf="!hideLabel && labelPosition == 'before'" class="tanj-label tanj-before tanj-number-spinner-label">{{label}}</span>
<div flex class="tanj-widget-input" layout="column" layout-align="start center">
<div *ngIf="!onlyLabel"
class="tanj-input-spinner-field"
layout="column"
layout-align="start"
(swipeUp)="swipeUp($event)"
(swipeDown)="swipeDown($event)">
<tanj-icon align="center"
font="material-icons"
ligature="arrow_drop_up"
(click)="$event.stopPropagation(); $event.preventDefault(); onNextValueRequest()"></tanj-icon>
<div class="tanj-spinner-value tanj-previous ">{{previousValue() | number:'1.0-0'}}</div>
<div *ngIf="!keyboardInputToggled"
class="tanj-spinner-value tanj-current"
(click)="onKeyboardInputRequest($event)">{{value | number:'1.0-0'}}
</div>
<input *ngIf="keyboardInputToggled"
class="tanj-spinner-value tanj-current tanj-spinner-keyboard-input-toggled tanj-raw-input tanj-number"
type="number"
min="{{min}}"
max="{{max}}"
step="{{step}}"
[(ngModel)]="value"
autofocus
(blur)="keyboardInputToggled = false">
<div class="tanj-spinner-value tanj-next">{{nextValue() | number:'1.0-0'}}</div>
<tanj-icon align="center"
font="material-icons"
ligature="arrow_drop_down"
(click)="$event.stopPropagation(); $event.preventDefault(); onPreviousValueRequest()"></tanj-icon>
</div>
<span *ngIf="!hideLabel && labelPosition == 'below'" class="tanj-label tanj-below tanj-number-spinner-label">{{label}}</span>
</div>
<span *ngIf="!hideLabel && labelPosition == 'after'"
class="tanj-label tanj-after tanj-number-spinner-label">{{label}}</span>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.IconComponent, selector: "tanj-icon", inputs: ["icon", "align", "font", "ligature", "disabled", "label"], outputs: ["click"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }], encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: NumberSpinnerWidgetComponent, decorators: [{
type: Component,
args: [{
selector: 'tanj-number-spinner-widget',
template: `<!-- -->
<div flex
class="tanj-input-template tanj-mode-edit"
[ngClass]="{'tanj-disabled': disabled}"
layout="row" layout-align="center center">
<span *ngIf="!hideLabel && labelPosition == 'before'" class="tanj-label tanj-before tanj-number-spinner-label">{{label}}</span>
<div flex class="tanj-widget-input" layout="column" layout-align="start center">
<div *ngIf="!onlyLabel"
class="tanj-input-spinner-field"
layout="column"
layout-align="start"
(swipeUp)="swipeUp($event)"
(swipeDown)="swipeDown($event)">
<tanj-icon align="center"
font="material-icons"
ligature="arrow_drop_up"
(click)="$event.stopPropagation(); $event.preventDefault(); onNextValueRequest()"></tanj-icon>
<div class="tanj-spinner-value tanj-previous ">{{previousValue() | number:'1.0-0'}}</div>
<div *ngIf="!keyboardInputToggled"
class="tanj-spinner-value tanj-current"
(click)="onKeyboardInputRequest($event)">{{value | number:'1.0-0'}}
</div>
<input *ngIf="keyboardInputToggled"
class="tanj-spinner-value tanj-current tanj-spinner-keyboard-input-toggled tanj-raw-input tanj-number"
type="number"
min="{{min}}"
max="{{max}}"
step="{{step}}"
[(ngModel)]="value"
autofocus
(blur)="keyboardInputToggled = false">
<div class="tanj-spinner-value tanj-next">{{nextValue() | number:'1.0-0'}}</div>
<tanj-icon align="center"
font="material-icons"
ligature="arrow_drop_down"
(click)="$event.stopPropagation(); $event.preventDefault(); onPreviousValueRequest()"></tanj-icon>
</div>
<span *ngIf="!hideLabel && labelPosition == 'below'" class="tanj-label tanj-below tanj-number-spinner-label">{{label}}</span>
</div>
<span *ngIf="!hideLabel && labelPosition == 'after'"
class="tanj-label tanj-after tanj-number-spinner-label">{{label}}</span>
</div>
`,
providers: [TANJ_NUMBER_SPINNER_WIDGET_VIEW_CONTROL_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { flex: [{
type: HostBinding,
args: ['attr.flex']
}], flexLayout: [{
type: HostBinding,
args: ['attr.layout']
}], flexLayoutAlign: [{
type: HostBinding,
args: ['attr.layout-align']
}], value: [{
type: Input
}], valueChange: [{
type: Output
}], labelPosition: [{
type: Input
}], disabled: [{
type: Input
}], hideLabel: [{
type: Input
}], onlyLabel: [{
type: Input
}], label: [{
type: Input
}], defaultValue: [{
type: Input
}], max: [{
type: Input
}], min: [{
type: Input
}], step: [{
type: Input
}], change: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVtYmVyLXNwaW5uZXItd2lkZ2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdlbnRpYWwvaW5wdXQtd2lkZ2V0cy9zcmMvbGliL251bWJlci1zcGlubmVyLXdpZGdldC9udW1iZXItc3Bpbm5lci13aWRnZXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLEtBQUssRUFHTCxNQUFNLEVBQ04saUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFBO0FBQ3RCLE9BQU8sRUFFTCxpQkFBaUIsRUFDbEIsTUFBTSxnQkFBZ0IsQ0FBQTtBQUN2QixPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sa0JBQWtCLENBQUE7Ozs7O0FBR3RDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxzREFBc0QsR0FBUTtJQUN6RSxPQUFPLEVBQU0saUJBQWlCO0lBQzlCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsNEJBQTRCLENBQUM7SUFDM0QsS0FBSyxFQUFRLElBQUk7Q0FDbEIsQ0FBQztBQUVGLE1BQU0sT0FBTyx5QkFBeUI7SUFFcEMsWUFBbUIsTUFBb0MsRUFBUyxLQUFhO1FBQTFELFdBQU0sR0FBTixNQUFNLENBQThCO1FBQVMsVUFBSyxHQUFMLEtBQUssQ0FBUTtJQUM3RSxDQUFDO0NBQ0Y7QUFtREQsTUFBTSxPQUFPLDRCQUE0QjtJQWdDdkMsWUFBb0IsaUJBQW9DO1FBQXBDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUE5QnhELHlCQUF5QjtRQUNDLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDUixlQUFVLEdBQUcsUUFBUSxDQUFDO1FBQ2hCLG9CQUFlLEdBQUcsT0FBTyxDQUFDO1FBRW5ELFVBQUssR0FBVyxDQUFDLENBQUE7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S0FBSztnQkFDSSxXQUFXO3NCQUFwQixNQUFNO2dCQUVFLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBS0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csR0FBRztzQkFBWCxLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBR0ksTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBIb3N0QmluZGluZyxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxuICBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQge1xuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgTkdfVkFMVUVfQUNDRVNTT1Jcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnXG5pbXBvcnQge0hhY2tzfSBmcm9tICdAdGFuZ2VudGlhbC9jb3JlJ1xuXG5cbi8qKlxuICogUHJvdmlkZXIgRXhwcmVzc2lvbiB0aGF0IGFsbG93cyB0aGlzIHdpZGdldCB0byByZWdpc3RlciBhcyBhIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICogVGhpcyBhbGxvd3MgaXQgdG8gc3VwcG9ydCBbKG5nTW9kZWwpXS5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IFRBTkpfTlVNQkVSX1NQSU5ORVJfV0lER0VUX1ZJRVdfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUjogYW55ID0ge1xuICBwcm92aWRlOiAgICAgTkdfVkFMVUVfQUNDRVNTT1IsXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE51bWJlclNwaW5uZXJXaWRnZXRDb21wb25lbnQpLFxuICBtdWx0aTogICAgICAgdHJ1ZVxufTtcblxuZXhwb3J0IGNsYXNzIE51bWJlclNwaW5uZXJXaWRnZXRDaGFuZ2Uge1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzb3VyY2U6IE51bWJlclNwaW5uZXJXaWRnZXRDb21wb25lbnQsIHB1YmxpYyB2YWx1ZTogbnVtYmVyKSB7XG4gIH1cbn1cblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICAgICAgJ3RhbmotbnVtYmVyLXNwaW5uZXItd2lkZ2V0JyxcbiAgdGVtcGxhdGU6ICAgICAgYDwhLS0gLS0+XG4gIDxkaXYgZmxleFxuICAgICAgIGNsYXNzPVwidGFuai1pbnB1dC10ZW1wbGF0ZSB0YW5qLW1vZGUtZWRpdFwiXG4gICAgICAgW25nQ2xhc3NdPVwieyd0YW5qLWRpc2FibGVkJzogZGlzYWJsZWR9XCJcbiAgICAgICBsYXlvdXQ9XCJyb3dcIiBsYXlvdXQtYWxpZ249XCJjZW50ZXIgY2VudGVyXCI+XG4gICAgPHNwYW4gKm5nSWY9XCIhaGlkZUxhYmVsICYmIGxhYmVsUG9zaXRpb24gPT0gJ2JlZm9yZSdcIiBjbGFzcz1cInRhbmotbGFiZWwgdGFuai1iZWZvcmUgIHRhbmotbnVtYmVyLXNwaW5uZXItbGFiZWxcIj57e2xhYmVsfX08L3NwYW4+XG4gICAgPGRpdiBmbGV4IGNsYXNzPVwidGFuai13aWRnZXQtaW5wdXRcIiBsYXlvdXQ9XCJjb2x1bW5cIiBsYXlvdXQtYWxpZ249XCJzdGFydCBjZW50ZXJcIj5cbiAgICAgIDxkaXYgKm5nSWY9XCIhb25seUxhYmVsXCJcbiAgICAgICAgICAgY2xhc3M9XCJ0YW5qLWlucHV0LXNwaW5uZXItZmllbGRcIlxuICAgICAgICAgICBsYXlvdXQ9XCJjb2x1bW5cIlxuICAgICAgICAgICBsYXlvdXQtYWxpZ249XCJzdGFydFwiXG4gICAgICAgICAgIChzd2lwZVVwKT1cInN3aXBlVXAoJGV2ZW50KVwiXG4gICAgICAgICAgIChzd2lwZURvd24pPVwic3dpcGVEb3duKCRldmVudClcIj5cbiAgICAgICAgPHRhbmotaWNvbiBhbGlnbj1cImNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgZm9udD1cIm1hdGVyaWFsLWljb25zXCJcbiAgICAgICAgICAgICAgICAgICBsaWdhdHVyZT1cImFycm93X2Ryb3BfdXBcIlxuICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7ICRldmVudC5wcmV2ZW50RGVmYXVsdCgpOyBvbk5leHRWYWx1ZVJlcXVlc3QoKVwiPjwvdGFuai1pY29uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFuai1zcGlubmVyLXZhbHVlIHRhbmotcHJldmlvdXMgXCI+e3twcmV2aW91c1ZhbHVlKCkgfCBudW1iZXI6JzEuMC0wJ319PC9kaXY+XG4gICAgICAgIDxkaXYgKm5nSWY9XCIha2V5Ym9hcmRJbnB1dFRvZ2dsZWRcIlxuICAgICAgICAgICAgIGNsYXNzPVwidGFuai1zcGlubmVyLXZhbHVlIHRhbmotY3VycmVudFwiXG4gICAgICAgICAgICAgKGNsaWNrKT1cIm9uS2V5Ym9hcmRJbnB1dFJlcXVlc3QoJGV2ZW50KVwiPnt7dmFsdWUgfCBudW1iZXI6JzEuMC0wJ319XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8aW5wdXQgKm5nSWY9XCJrZXlib2FyZElucHV0VG9nZ2xlZFwiXG4gICAgICAgICAgICAgICBjbGFzcz1cInRhbmotc3Bpbm5lci12YWx1ZSB0YW5qLWN1cnJlbnQgdGFuai1zcGlubmVyLWtleWJvYXJkLWlucHV0LXRvZ2dsZWQgdGFuai1yYXctaW5wdXQgdGFuai1udW1iZXJcIlxuICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgICBtaW49XCJ7e21pbn19XCJcbiAgICAgICAgICAgICAgIG1heD1cInt7bWF4fX1cIlxuICAgICAgICAgICAgICAgc3RlcD1cInt7c3RlcH19XCJcbiAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgYXV0b2ZvY3VzXG4gICAgICAgICAgICAgICAoYmx1cik9XCJrZXlib2FyZElucHV0VG9nZ2xlZCA9IGZhbHNlXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YW5qLXNwaW5uZXItdmFsdWUgdGFuai1uZXh0XCI+e3tuZXh0VmFsdWUoKSB8IG51bWJlcjonMS4wLTAnfX08L2Rpdj5cbiAgICAgICAgPHRhbmotaWNvbiBhbGlnbj1cImNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgZm9udD1cIm1hdGVyaWFsLWljb25zXCJcbiAgICAgICAgICAgICAgICAgICBsaWdhdHVyZT1cImFycm93X2Ryb3BfZG93blwiXG4gICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IG9uUHJldmlvdXNWYWx1ZVJlcXVlc3QoKVwiPjwvdGFuai1pY29uPlxuICAgICAgPC9kaXY+XG4gICAgICA8c3BhbiAqbmdJZj1cIiFoaWRlTGFiZWwgJiYgbGFiZWxQb3NpdGlvbiA9PSAnYmVsb3cnXCIgY2xhc3M9XCJ0YW5qLWxhYmVsIHRhbmotYmVsb3cgIHRhbmotbnVtYmVyLXNwaW5uZXItbGFiZWxcIj57e2xhYmVsfX08L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPHNwYW4gKm5nSWY9XCIhaGlkZUxhYmVsICYmIGxhYmVsUG9zaXRpb24gPT0gJ2FmdGVyJ1wiXG4gICAgICAgICAgY2xhc3M9XCJ0YW5qLWxhYmVsIHRhbmotYWZ0ZXIgIHRhbmotbnVtYmVyLXNwaW5uZXItbGFiZWxcIj57e2xhYmVsfX08L3NwYW4+XG4gIDwvZGl2PlxuICAgICAgICAgICAgICAgICBgLFxuICBwcm92aWRlcnM6ICAgICBbVEFOSl9OVU1CRVJfU1BJTk5FUl9XSURHRVRfVklFV19DT05UUk9MX1ZBTFVFX0FDQ0VTU09SXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBOdW1iZXJTcGlubmVyV2lkZ2V0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcblxuICAvLyB0dXJuIHRoaXMgaW50byBhIGNsYXNzXG4gIEBIb3N0QmluZGluZygnYXR0ci5mbGV4JykgZmxleCA9ICcnO1xuICBASG9zdEJpbmRpbmcoJ2F0dHIubGF5b3V0JykgZmxleExheW91dCA9ICdjb2x1bW4nO1xuICBASG9zdEJpbmRpbmcoJ2F0dHIubGF5b3V0LWFsaWduJykgZmxleExheW91dEFsaWduID0gJ3N0YXJ0JztcblxuICBASW5wdXQoKSB2YWx1ZTogbnVtYmVyID0gMFxuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSlcblxuICBASW5wdXQoKSBsYWJlbFBvc2l0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicgfCAnYmVsb3cnID0gJ2JlZm9yZSdcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZVxuICBASW5wdXQoKSBoaWRlTGFiZWw6IGJvb2xlYW4gPSBmYWxzZVxuICBASW5wdXQoKSBvbmx5TGFiZWw6IGJvb2xlYW4gPSBmYWxzZVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIEZpZWxkc1xuICAgKi9cbiAgQElucHV0KCkgbGFiZWw6IHN0cmluZyA9ICcnXG4gIEBJbnB1dCgpIGRlZmF1bHRWYWx1ZTogbnVtYmVyID0gMFxuICBASW5wdXQoKSBtYXg6IG51bWJlciA9IDEwXG4gIEBJbnB1dCgpIG1pbjogbnVtYmVyID0gMFxuICBASW5wdXQoKSBzdGVwOiBudW1iZXIgPSAxXG4gIC8qIGVuZCBDb25maWd1cmF0aW9uIEZpZWxkcyAqL1xuXG4gIEBPdXRwdXQoKSBjaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSlcblxuICBrZXlib2FyZElucHV0VG9nZ2xlZCA9IGZhbHNlXG5cbiAgb25Ub3VjaGVkOiAoKSA9PiBhbnkgPSAoKSA9PiB7IH07XG4gIHByaXZhdGUgY29udHJvbFZhbHVlQWNjZXNzb3JDaGFuZ2VGbjogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAodmFsdWUpID0+IHsgfTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICB9XG5cblxuICBuZ09uSW5pdCgpIHtcbiAgICBIYWNrcy5tYXRlcmlhbERlc2lnblBsYWNlaG9sZGVyVGV4dCh0aGlzLmNoYW5nZURldGVjdG9yUmVmKVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICB9XG5cbiAgaGFuZGxlVmFsdWVDaGFuZ2UodmFsdWU6IG51bWJlcikge1xuICAgIGlmICghdGhpcy5kaXNhYmxlZCkge1xuICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy52YWx1ZSlcbiAgICAgIHRoaXMuZW1pdENoYW5nZUV2ZW50KClcbiAgICB9XG4gIH1cblxuXG4gIG9uUHJldmlvdXNWYWx1ZVJlcXVlc3QoKSB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XG4gICAgICBjb25zdCB2ID0gdGhpcy5wcmV2aW91c1ZhbHVlKClcbiAgICAgIGlmICh2ICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlVmFsdWVDaGFuZ2UodilcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbk5leHRWYWx1ZVJlcXVlc3QoKSB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XG4gICAgICBjb25zdCB2ID0gdGhpcy5uZXh0VmFsdWUoKVxuICAgICAgaWYgKHYgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVWYWx1ZUNoYW5nZSh2KVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5leHRWYWx1ZSgpOiBudW1iZXIge1xuICAgIGxldCB2ID0gdGhpcy52YWx1ZSArIHRoaXMuc3RlcFxuICAgIGlmICh2ID4gdGhpcy5tYXgpIHtcbiAgICAgIHYgPSB0aGlzLm1heFxuICAgIH1cbiAgICByZXR1cm4gdlxuICB9XG5cbiAgcHJldmlvdXNWYWx1ZSgpOiBudW1iZXIge1xuICAgIGxldCB2ID0gdGhpcy52YWx1ZSAtIHRoaXMuc3RlcFxuICAgIGlmICh2IDwgdGhpcy5taW4pIHtcbiAgICAgIHYgPSB0aGlzLm1pblxuICAgIH1cbiAgICByZXR1cm4gdlxuICB9XG5cbiAgc3dpcGVVcChldmVudDogYW55KSB7XG4gICAgdGhpcy5vbk5leHRWYWx1ZVJlcXVlc3QoKVxuICB9XG5cbiAgc3dpcGVEb3duKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLm9uUHJldmlvdXNWYWx1ZVJlcXVlc3QoKVxuICB9XG5cbiAgb25LZXlib2FyZElucHV0UmVxdWVzdChldmVudDogYW55KSB7XG4gICAgdGhpcy5rZXlib2FyZElucHV0VG9nZ2xlZCA9IHRoaXMuZGlzYWJsZWQgPyBmYWxzZSA6ICF0aGlzLmtleWJvYXJkSW5wdXRUb2dnbGVkXG4gIH1cblxuXG4gIC8qKlxuICAgKiBCb2lsZXJwbGF0ZSAvIHJlcXVpcmVkIGZvciBBbmd1bGFyXG4gICAqL1xuICBwcml2YXRlIGVtaXRDaGFuZ2VFdmVudCgpIHtcbiAgICB0aGlzLmNvbnRyb2xWYWx1ZUFjY2Vzc29yQ2hhbmdlRm4odGhpcy52YWx1ZSk7XG4gICAgdGhpcy5jaGFuZ2UuZW1pdChuZXcgTnVtYmVyU3Bpbm5lcldpZGdldENoYW5nZSh0aGlzLCB0aGlzLnZhbHVlKSlcbiAgfVxuXG4gIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWVcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xWYWx1ZUFjY2Vzc29yQ2hhbmdlRm4gPSBmbjtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBpbnB1dCdzIGRpc2FibGVkIHN0YXRlLiBJbXBsZW1lbnRlZCBhcyBhIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gICAqIEBwYXJhbSBpc0Rpc2FibGVkIFdoZXRoZXIgdGhlIGlucHV0IHNob3VsZCBiZSBkaXNhYmxlZC5cbiAgICovXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbikge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICB9XG59XG4iXX0=