UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

228 lines 31.1 kB
import { Component, EventEmitter, Input, Output, ViewChild, } from '@angular/core'; import { FormBuilder, FormControl, Validators } from '@angular/forms'; import { AbstractVariable } from '@iotize/tap/data'; import { CurrentDeviceService, LibError, PendingCallManager, } from '@iotize/ionic'; import { Subject } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; import * as i2 from "@iotize/ionic"; import * as i3 from "@angular/common"; import * as i4 from "@ionic/angular"; /** * @deprecated */ export class MonitoringEditTextComponent { set inputStream(stream) { this.setStream(stream); } set variable(variable) { this._variable = variable; } set value(v) { this.myControl.setValue(v); } errorToString(item) { if (item.key in this.validationMessages) { return this.validationMessages[item.key]; } return item.value; } submit() { const newValue = this.myControl.value; if (this.actions) { this.actions.next(newValue); } if (!this._variable) { throw LibError.componentArgumentRequired(this.constructor.name, 'variable'); } this.pendingCallManager .exec(async () => { if (this._variable) { await this.startAction(this._variable.write(newValue).then(() => { this.myControl.setErrors(null); this.outEvent.emit({ type: 'WRITE_SUCCESS', payload: { newValue: newValue, }, }); })); } }) .catch((err) => { this.addFormError.bind(err); throw err; }); } onKeydown(event) { if (event.key === 'Enter') { this.submit(); } else if (event.key === 'Escape') { this.close(); } } ngAfterViewInit() { setTimeout(() => { // if (!this.inputref.nativeElement) { // console.warn('no this.inputref'); // return; // } this.inputref.setFocus(); }, 200); } close() { this.outEvent.emit({ type: 'CLOSE', }); } addFormError(err) { console.warn('Form error', err); this.myControl.setErrors({ write: err.message, }); this.outEvent.emit({ type: 'WRITE_ERROR', payload: { error: err, }, }); } refresh() { if (!this._variable) { throw LibError.componentArgumentRequired(this.constructor.name, 'variable'); } this.startAction(this._variable .read() .then((v) => { this.value = v; }) .catch(this.addFormError.bind(this))).catch((err) => { console.log(err); }); } startAction(actions) { this.setLoading(true); return actions.finally(() => this.setLoading(false)); } setLoading(value) { this.loading = value; if (this.loading) { this.myControl.disable(); } else { this.myControl.enable(); } } setStream(stream) { this.subscription?.unsubscribe(); if (stream) { this.subscription = stream.subscribe({ next: (value) => { this.value = value; }, error: (err) => { this.myControl.setErrors({ refresh: err.message, }); }, }); } } constructor(formBuilder, tapService) { this.formBuilder = formBuilder; this.loading = false; this.validationMessages = { required: 'Input is required', minlength: 'Input is too short', maxlength: 'Input is too long', pattern: 'Input does not match pattern', }; this.label = undefined; this.input = 'string'; this.type = 'string'; this.clearInput = false; this.clearOnEdit = false; this.color = 'primary'; this.disabled = false; this.inputMode = 'text'; this.max = undefined; this.min = undefined; this.maxLength = undefined; this.minLength = undefined; this.name = undefined; this.pattern = undefined; this.placeholder = undefined; this.readonly = false; this.required = false; this.outEvent = new EventEmitter(); this.myControl = new FormControl('', Validators.compose([ Validators.required, // Validators.maxLength(this.minLength), // Validators.minLength(this.maxLength), // Validators.pattern(this.pattern), ])); this.myGroup = this.formBuilder.group({ myControl: this.myControl, }); this.pendingCallManager = PendingCallManager.create(tapService); this.loading = false; } ngOnInit() { this.refresh(); } } /** @nocollapse */ MonitoringEditTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MonitoringEditTextComponent, deps: [{ token: i1.FormBuilder }, { token: i2.CurrentDeviceService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ MonitoringEditTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MonitoringEditTextComponent, selector: "monitoring-edit-text", inputs: { inputStream: "inputStream", variable: "variable", label: "label", input: "input", type: "type", actions: "actions", clearInput: "clearInput", clearOnEdit: "clearOnEdit", color: "color", disabled: "disabled", inputMode: "inputMode", max: "max", min: "min", maxLength: "maxLength", minLength: "minLength", name: "name", pattern: "pattern", placeholder: "placeholder", readonly: "readonly", required: "required", value: "value" }, outputs: { outEvent: "outEvent" }, viewQueries: [{ propertyName: "inputref", first: true, predicate: ["inputref"], descendants: true }], ngImport: i0, template: "<ion-item [formGroup]=\"myGroup\">\n <ion-label *ngIf=\"label\">{{ label }}</ion-label>\n <ion-input\n auto-focus\n (keydown)=\"onKeydown($event)\"\n #inputref\n formControlName=\"myControl\"\n [max]=\"max\"\n [maxlength]=\"maxLength\"\n [min]=\"min\"\n [minlength]=\"minLength\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [type]=\"type\"\n >\n </ion-input>\n <ion-buttons>\n <ion-button [disabled]=\"loading\" (click)=\"submit()\">\n <ion-icon name=\"send\" slot=\"start\"></ion-icon>\n <!-- Write -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"refresh()\">\n <ion-icon name=\"refresh\" slot=\"start\"></ion-icon>\n <!-- Refresh -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"close()\">\n <ion-icon name=\"close\" slot=\"start\"></ion-icon>\n </ion-button>\n </ion-buttons>\n <ion-spinner [hidden]=\"!loading\" name=\"lines\"></ion-spinner>\n</ion-item>\n<ion-item\n class=\"validation-errors\"\n *ngIf=\"\n myControl.dirty &&\n myControl.errors &&\n (myControl.errors | keyvalue).length > 0\n \"\n>\n <!-- {{ myControl.errors | json}} -->\n <ng-container *ngFor=\"let item of myControl.errors | keyvalue\">\n <ion-text color=\"danger error-message \">{{ errorToString(item) }}</ion-text>\n </ng-container>\n</ion-item>\n", styles: [".error-message{font-weight:700}ion-item{background:#ccc}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i4.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MonitoringEditTextComponent, decorators: [{ type: Component, args: [{ selector: 'monitoring-edit-text', template: "<ion-item [formGroup]=\"myGroup\">\n <ion-label *ngIf=\"label\">{{ label }}</ion-label>\n <ion-input\n auto-focus\n (keydown)=\"onKeydown($event)\"\n #inputref\n formControlName=\"myControl\"\n [max]=\"max\"\n [maxlength]=\"maxLength\"\n [min]=\"min\"\n [minlength]=\"minLength\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [type]=\"type\"\n >\n </ion-input>\n <ion-buttons>\n <ion-button [disabled]=\"loading\" (click)=\"submit()\">\n <ion-icon name=\"send\" slot=\"start\"></ion-icon>\n <!-- Write -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"refresh()\">\n <ion-icon name=\"refresh\" slot=\"start\"></ion-icon>\n <!-- Refresh -->\n </ion-button>\n <ion-button [disabled]=\"loading\" (click)=\"close()\">\n <ion-icon name=\"close\" slot=\"start\"></ion-icon>\n </ion-button>\n </ion-buttons>\n <ion-spinner [hidden]=\"!loading\" name=\"lines\"></ion-spinner>\n</ion-item>\n<ion-item\n class=\"validation-errors\"\n *ngIf=\"\n myControl.dirty &&\n myControl.errors &&\n (myControl.errors | keyvalue).length > 0\n \"\n>\n <!-- {{ myControl.errors | json}} -->\n <ng-container *ngFor=\"let item of myControl.errors | keyvalue\">\n <ion-text color=\"danger error-message \">{{ errorToString(item) }}</ion-text>\n </ng-container>\n</ion-item>\n", styles: [".error-message{font-weight:700}ion-item{background:#ccc}\n"] }] }], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i2.CurrentDeviceService }]; }, propDecorators: { inputref: [{ type: ViewChild, args: ['inputref', { static: false }] }], inputStream: [{ type: Input }], variable: [{ type: Input }], label: [{ type: Input }], input: [{ type: Input }], type: [{ type: Input }], actions: [{ type: Input }], clearInput: [{ type: Input }], clearOnEdit: [{ type: Input }], color: [{ type: Input }], disabled: [{ type: Input }], inputMode: [{ type: Input }], max: [{ type: Input }], min: [{ type: Input }], maxLength: [{ type: Input }], minLength: [{ type: Input }], name: [{ type: Input }], pattern: [{ type: Input }], placeholder: [{ type: Input }], readonly: [{ type: Input }], required: [{ type: Input }], value: [{ type: Input }], outEvent: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9uaXRvcmluZy1lZGl0LXRleHQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL21vbml0b3Jpbmcvc3JjL2xpYi91aS1jb21wb25lbnRzL21vbml0b3JpbmctZWRpdC10ZXh0L21vbml0b3JpbmctZWRpdC10ZXh0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9tb25pdG9yaW5nL3NyYy9saWIvdWktY29tcG9uZW50cy9tb25pdG9yaW5nLWVkaXQtdGV4dC9tb25pdG9yaW5nLWVkaXQtdGV4dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNwRCxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLFFBQVEsRUFDUixrQkFBa0IsR0FDbkIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFjLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7Ozs7OztBQU96RDs7R0FFRztBQU1ILE1BQU0sT0FBTywyQkFBMkI7SUFpQnRDLElBQ0ksV0FBVyxDQUFDLE1BQW1DO1FBQ2pELElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELElBQWEsUUFBUSxDQUFDLFFBQStCO1FBQ25ELElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO0lBQzVCLENBQUM7SUFzQkQsSUFBYSxLQUFLLENBQUMsQ0FBTTtRQUN2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Q0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFFTyxLQUFLO3NCQUFqQixLQUFLO2dCQUlJLFFBQVE7c0JBQWpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWJzdHJhY3RWYXJpYWJsZSB9IGZyb20gJ0Bpb3RpemUvdGFwL2RhdGEnO1xuaW1wb3J0IHtcbiAgQ3VycmVudERldmljZVNlcnZpY2UsXG4gIExpYkVycm9yLFxuICBQZW5kaW5nQ2FsbE1hbmFnZXIsXG59IGZyb20gJ0Bpb3RpemUvaW9uaWMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9uaXRvcmluZ0VkaXRUZXh0RXZlbnQge1xuICB0eXBlOiAnQ0xPU0UnIHwgJ1dSSVRFX1NVQ0NFU1MnIHwgJ1dSSVRFX0VSUk9SJztcbiAgcGF5bG9hZD86IGFueTtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdtb25pdG9yaW5nLWVkaXQtdGV4dCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9tb25pdG9yaW5nLWVkaXQtdGV4dC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL21vbml0b3JpbmctZWRpdC10ZXh0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIE1vbml0b3JpbmdFZGl0VGV4dENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG4gIGxvYWRpbmcgPSBmYWxzZTtcblxuICB2YWxpZGF0aW9uTWVzc2FnZXMgPSB7XG4gICAgcmVxdWlyZWQ6ICdJbnB1dCBpcyByZXF1aXJlZCcsXG4gICAgbWlubGVuZ3RoOiAnSW5wdXQgaXMgdG9vIHNob3J0JyxcbiAgICBtYXhsZW5ndGg6ICdJbnB1dCBpcyB0b28gbG9uZycsXG4gICAgcGF0dGVybjogJ0lucHV0IGRvZXMgbm90IG1hdGNoIHBhdHRlcm4nLFxuICB9O1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gIF92YXJpYWJsZT86IEFic3RyYWN0VmFyaWFibGU8YW55PjtcblxuICBAVmlld0NoaWxkKCdpbnB1dHJlZicsIHsgc3RhdGljOiBmYWxzZSB9KSBpbnB1dHJlZjogYW55O1xuICBwZW5kaW5nQ2FsbE1hbmFnZXI6IFBlbmRpbmdDYWxsTWFuYWdlcjtcblxuICBASW5wdXQoKVxuICBzZXQgaW5wdXRTdHJlYW0oc3RyZWFtOiBPYnNlcnZhYmxlPGFueT4gfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnNldFN0cmVhbShzdHJlYW0pO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IHZhcmlhYmxlKHZhcmlhYmxlOiBBYnN0cmFjdFZhcmlhYmxlPGFueT4pIHtcbiAgICB0aGlzLl92YXJpYWJsZSA9IHZhcmlhYmxlO1xuICB9XG5cbiAgQElucHV0KCkgbGFiZWw/OiBzdHJpbmcgPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGlucHV0ID0gJ3N0cmluZyc7XG4gIEBJbnB1dCgpIHR5cGUgPSAnc3RyaW5nJztcbiAgQElucHV0KCkgYWN0aW9ucz86IFN1YmplY3Q8YW55PjtcblxuICBASW5wdXQoKSBjbGVhcklucHV0ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNsZWFyT25FZGl0ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNvbG9yID0gJ3ByaW1hcnknO1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBpbnB1dE1vZGUgPSAndGV4dCc7XG4gIEBJbnB1dCgpIG1heD86IG51bWJlciA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgbWluPzogbnVtYmVyID0gdW5kZWZpbmVkO1xuICBASW5wdXQoKSBtYXhMZW5ndGg/OiBudW1iZXIgPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIG1pbkxlbmd0aD86IG51bWJlciA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgbmFtZT8gPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHBhdHRlcm4/ID0gdW5kZWZpbmVkO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcj8gPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHJlYWRvbmx5ID0gZmFsc2U7XG4gIEBJbnB1dCgpIHJlcXVpcmVkID0gZmFsc2U7XG5cbiAgQElucHV0KCkgc2V0IHZhbHVlKHY6IGFueSkge1xuICAgIHRoaXMubXlDb250cm9sLnNldFZhbHVlKHYpO1xuICB9XG5cbiAgQE91dHB1dCgpIG91dEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxNb25pdG9yaW5nRWRpdFRleHRFdmVudD4oKTtcblxuICBwdWJsaWMgbXlDb250cm9sOiBGb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbChcbiAgICAnJyxcbiAgICBWYWxpZGF0b3JzLmNvbXBvc2UoW1xuICAgICAgVmFsaWRhdG9ycy5yZXF1aXJlZCxcbiAgICAgIC8vIFZhbGlkYXRvcnMubWF4TGVuZ3RoKHRoaXMubWluTGVuZ3RoKSxcbiAgICAgIC8vIFZhbGlkYXRvcnMubWluTGVuZ3RoKHRoaXMubWF4TGVuZ3RoKSxcbiAgICAgIC8vIFZhbGlkYXRvcnMucGF0dGVybih0aGlzLnBhdHRlcm4pLFxuICAgIF0pXG4gICk7XG5cbiAgbXlHcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgIG15Q29udHJvbDogdGhpcy5teUNvbnRyb2wsXG4gIH0pO1xuXG4gIGVycm9yVG9TdHJpbmcoaXRlbTogeyBrZXk6IHN0cmluZzsgdmFsdWU6IGFueSB9KSB7XG4gICAgaWYgKGl0ZW0ua2V5IGluIHRoaXMudmFsaWRhdGlvbk1lc3NhZ2VzKSB7XG4gICAgICByZXR1cm4gKHRoaXMudmFsaWRhdGlvbk1lc3NhZ2VzIGFzIGFueSlbaXRlbS5rZXldO1xuICAgIH1cbiAgICByZXR1cm4gaXRlbS52YWx1ZTtcbiAgfVxuXG4gIHN1Ym1pdCgpIHtcbiAgICBjb25zdCBuZXdWYWx1ZSA9IHRoaXMubXlDb250cm9sLnZhbHVlO1xuICAgIGlmICh0aGlzLmFjdGlvbnMpIHtcbiAgICAgIHRoaXMuYWN0aW9ucy5uZXh0KG5ld1ZhbHVlKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLl92YXJpYWJsZSkge1xuICAgICAgdGhyb3cgTGliRXJyb3IuY29tcG9uZW50QXJndW1lbnRSZXF1aXJlZChcbiAgICAgICAgdGhpcy5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICAndmFyaWFibGUnXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMucGVuZGluZ0NhbGxNYW5hZ2VyXG4gICAgICAuZXhlYyhhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLl92YXJpYWJsZSkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuc3RhcnRBY3Rpb24oXG4gICAgICAgICAgICB0aGlzLl92YXJpYWJsZS53cml0ZShuZXdWYWx1ZSkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMubXlDb250cm9sLnNldEVycm9ycyhudWxsKTtcbiAgICAgICAgICAgICAgdGhpcy5vdXRFdmVudC5lbWl0KHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnV1JJVEVfU1VDQ0VTUycsXG4gICAgICAgICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgdGhpcy5hZGRGb3JtRXJyb3IuYmluZChlcnIpO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9KTtcbiAgfVxuXG4gIG9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIHRoaXMuc3VibWl0KCk7XG4gICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgLy8gaWYgKCF0aGlzLmlucHV0cmVmLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIC8vICAgY29uc29sZS53YXJuKCdubyB0aGlzLmlucHV0cmVmJyk7XG4gICAgICAvLyAgIHJldHVybjtcbiAgICAgIC8vIH1cbiAgICAgIHRoaXMuaW5wdXRyZWYuc2V0Rm9jdXMoKTtcbiAgICB9LCAyMDApO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5vdXRFdmVudC5lbWl0KHtcbiAgICAgIHR5cGU6ICdDTE9TRScsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFkZEZvcm1FcnJvcihlcnI6IEVycm9yKSB7XG4gICAgY29uc29sZS53YXJuKCdGb3JtIGVycm9yJywgZXJyKTtcbiAgICB0aGlzLm15Q29udHJvbC5zZXRFcnJvcnMoe1xuICAgICAgd3JpdGU6IGVyci5tZXNzYWdlLFxuICAgIH0pO1xuICAgIHRoaXMub3V0RXZlbnQuZW1pdCh7XG4gICAgICB0eXBlOiAnV1JJVEVfRVJST1InLFxuICAgICAgcGF5bG9hZDoge1xuICAgICAgICBlcnJvcjogZXJyLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHJlZnJlc2goKSB7XG4gICAgaWYgKCF0aGlzLl92YXJpYWJsZSkge1xuICAgICAgdGhyb3cgTGliRXJyb3IuY29tcG9uZW50QXJndW1lbnRSZXF1aXJlZChcbiAgICAgICAgdGhpcy5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICAndmFyaWFibGUnXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0QWN0aW9uKFxuICAgICAgdGhpcy5fdmFyaWFibGVcbiAgICAgICAgLnJlYWQoKVxuICAgICAgICAudGhlbigodikgPT4ge1xuICAgICAgICAgIHRoaXMudmFsdWUgPSB2O1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2godGhpcy5hZGRGb3JtRXJyb3IuYmluZCh0aGlzKSlcbiAgICApLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0QWN0aW9uKGFjdGlvbnM6IFByb21pc2U8YW55Pik6IFByb21pc2U8YW55PiB7XG4gICAgdGhpcy5zZXRMb2FkaW5nKHRydWUpO1xuICAgIHJldHVybiBhY3Rpb25zLmZpbmFsbHkoKCkgPT4gdGhpcy5zZXRMb2FkaW5nKGZhbHNlKSk7XG4gIH1cblxuICBzZXRMb2FkaW5nKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkaW5nID0gdmFsdWU7XG4gICAgaWYgKHRoaXMubG9hZGluZykge1xuICAgICAgdGhpcy5teUNvbnRyb2wuZGlzYWJsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm15Q29udHJvbC5lbmFibGUoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldFN0cmVhbShzdHJlYW06IE9ic2VydmFibGU8YW55PiB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIGlmIChzdHJlYW0pIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gc3RyZWFtLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICB0aGlzLm15Q29udHJvbC5zZXRFcnJvcnMoe1xuICAgICAgICAgICAgcmVmcmVzaDogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgIHRhcFNlcnZpY2U6IEN1cnJlbnREZXZpY2VTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMucGVuZGluZ0NhbGxNYW5hZ2VyID0gUGVuZGluZ0NhbGxNYW5hZ2VyLmNyZWF0ZSh0YXBTZXJ2aWNlKTtcbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMucmVmcmVzaCgpO1xuICB9XG59XG4iLCI8aW9uLWl0ZW0gW2Zvcm1Hcm91cF09XCJteUdyb3VwXCI+XG4gIDxpb24tbGFiZWwgKm5nSWY9XCJsYWJlbFwiPnt7IGxhYmVsIH19PC9pb24tbGFiZWw+XG4gIDxpb24taW5wdXRcbiAgICBhdXRvLWZvY3VzXG4gICAgKGtleWRvd24pPVwib25LZXlkb3duKCRldmVudClcIlxuICAgICNpbnB1dHJlZlxuICAgIGZvcm1Db250cm9sTmFtZT1cIm15Q29udHJvbFwiXG4gICAgW21heF09XCJtYXhcIlxuICAgIFttYXhsZW5ndGhdPVwibWF4TGVuZ3RoXCJcbiAgICBbbWluXT1cIm1pblwiXG4gICAgW21pbmxlbmd0aF09XCJtaW5MZW5ndGhcIlxuICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgW3JlcXVpcmVkXT1cInJlcXVpcmVkXCJcbiAgICBbdHlwZV09XCJ0eXBlXCJcbiAgPlxuICA8L2lvbi1pbnB1dD5cbiAgPGlvbi1idXR0b25zPlxuICAgIDxpb24tYnV0dG9uIFtkaXNhYmxlZF09XCJsb2FkaW5nXCIgKGNsaWNrKT1cInN1Ym1pdCgpXCI+XG4gICAgICA8aW9uLWljb24gbmFtZT1cInNlbmRcIiBzbG90PVwic3RhcnRcIj48L2lvbi1pY29uPlxuICAgICAgPCEtLSBXcml0ZSAtLT5cbiAgICA8L2lvbi1idXR0b24+XG4gICAgPGlvbi1idXR0b24gW2Rpc2FibGVkXT1cImxvYWRpbmdcIiAoY2xpY2spPVwicmVmcmVzaCgpXCI+XG4gICAgICA8aW9uLWljb24gbmFtZT1cInJlZnJlc2hcIiBzbG90PVwic3RhcnRcIj48L2lvbi1pY29uPlxuICAgICAgPCEtLSBSZWZyZXNoIC0tPlxuICAgIDwvaW9uLWJ1dHRvbj5cbiAgICA8aW9uLWJ1dHRvbiBbZGlzYWJsZWRdPVwibG9hZGluZ1wiIChjbGljayk9XCJjbG9zZSgpXCI+XG4gICAgICA8aW9uLWljb24gbmFtZT1cImNsb3NlXCIgc2xvdD1cInN0YXJ0XCI+PC9pb24taWNvbj5cbiAgICA8L2lvbi1idXR0b24+XG4gIDwvaW9uLWJ1dHRvbnM+XG4gIDxpb24tc3Bpbm5lciBbaGlkZGVuXT1cIiFsb2FkaW5nXCIgbmFtZT1cImxpbmVzXCI+PC9pb24tc3Bpbm5lcj5cbjwvaW9uLWl0ZW0+XG48aW9uLWl0ZW1cbiAgY2xhc3M9XCJ2YWxpZGF0aW9uLWVycm9yc1wiXG4gICpuZ0lmPVwiXG4gICAgbXlDb250cm9sLmRpcnR5ICYmXG4gICAgbXlDb250cm9sLmVycm9ycyAmJlxuICAgIChteUNvbnRyb2wuZXJyb3JzIHwga2V5dmFsdWUpLmxlbmd0aCA+IDBcbiAgXCJcbj5cbiAgPCEtLSB7eyBteUNvbnRyb2wuZXJyb3JzIHwganNvbn19IC0tPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIG15Q29udHJvbC5lcnJvcnMgfCBrZXl2YWx1ZVwiPlxuICAgIDxpb24tdGV4dCBjb2xvcj1cImRhbmdlciBlcnJvci1tZXNzYWdlIFwiPnt7IGVycm9yVG9TdHJpbmcoaXRlbSkgfX08L2lvbi10ZXh0PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvaW9uLWl0ZW0+XG4iXX0=