UNPKG

@iotize/ionic

Version:

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

157 lines 29.9 kB
import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; import { getAbstractVariableOrError, LibError } from '@iotize/ionic'; import { AbstractVariable, TapVariable } from '@iotize/tap/data'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "@angular/common"; import * as i3 from "@ionic/angular"; import * as i4 from "../monitoring-variable-value/monitoring-variable-value.component"; import * as i5 from "../tap-variable-range/tap-variable-range.component"; import * as i6 from "../tap-variable-buttons/tap-variable-buttons.component"; import * as i7 from "../tap-variable-toggle/tap-variable-toggle.component"; import * as i8 from "../tap-variable-select/tap-variable-select.component"; export class VariableCardComponent { // private _switchButtonSubscription?: Subscription; set variable(variable) { // console.log('VariableCardComponent', 'SET VARIABLE', variable); this._variable = variable; if (this._subscription) { this._subscription.unsubscribe(); } this._subscription = variable.values.subscribe({ next: (value) => { if (this.refreshValues) { this.value = value; } }, error: (error) => { // console.warn(`Monitoring error: `, error); this.error = error; }, complete: () => { // console.warn('VariableCardComponent', 'values observable is complete') }, }); } get variable() { return getAbstractVariableOrError(this._variable); } constructor(router) { this.router = router; this.waitForSubmit = false; this.cardType = 'text'; this.cardTypes = [ // 'chart', 'gauge', 'switch', 'text', 'buttons', 'range', 'select', ]; this.editMode = false; this.monitor = true; this.showStartStopMonitoring = false; this.unit = ''; this.bundleName = '...'; this.value = 'Unknown'; this.refreshValues = false; this.monitoringButtons = [0, 1, 2, 3, 4, 5].map((v) => { return { label: `${v}`, value: v, }; }); this.selectOptions = [0, 1, 2, 3, 4, 5].map((v) => { return { key: v, text: `Value ${v}`, }; }); } get variableConfig() { if (this._variable instanceof TapVariable) { return this._variable.context.config; } return undefined; } // editConfig() { // this.router.navigate(['/device/monitoring/add']); // } async switchButtonToggleAction(checked) { if (!this._variable) { throw LibError.componentArgumentRequired('VariableCardComponent', 'variable'); } const value = checked ? 1 : 0; await this._variable.write(value); // .catch((error) => { // console.warn(`Cannot write ${this._variable.identifier()}: ${error}`) // this.error = error; // }) } // onEditEvent(event: MonitoringEditTextEvent) { // console.log('EDIT EVENT => ', event); // switch (event.type) { // case 'CLOSE': // this.editMode = false; // break; // case 'WRITE_SUCCESS': // this.editMode = false; // break; // } // } ngOnDestroy() { if (this._subscription) { this._subscription.unsubscribe(); } // if (this._switchButtonSubscription) { // this._switchButtonSubscription.unsubscribe(); // } } onCardTypeChange($event) { // console.log('onCardTypeChange', $event); // this.cardType = $event.detail.value; } toggleMonitoring() { // if (this.monitor) { // if (!this._variable) { // throw LibError.componentArgumentRequired('VariableCardComponent', 'variable'); // } this.refreshValues = !this.refreshValues; // if (this.refreshValues) { // // console.log('Start monitoring with period: ', this.monitoringPeriod); // this._variable.monitor().start({ // forceChange: false, // period: this.monitoringPeriod // }); // } else { // // console.log('Pause monitoring'); // this._variable.monitor().pause(); // } // } } } /** @nocollapse */ VariableCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VariableCardComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ VariableCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: VariableCardComponent, selector: "app-variable-card", inputs: { cardType: "cardType", cardTypes: "cardTypes", editMode: "editMode", monitor: "monitor", showStartStopMonitoring: "showStartStopMonitoring", unit: "unit", bundleName: "bundleName", variable: "variable" }, ngImport: i0, template: "<ion-card *ngIf=\"_variable\">\n <ion-item lines=\"none\">\n <ion-label slot=\"start\">{{ bundleName }}</ion-label>\n <ion-label slot=\"end\">#{{ _variable.id }}</ion-label>\n </ion-item>\n <!-- <ion-item>\n <ion-icon *ngIf=\"icon\" name=\"{{icon}}\" slot=\"start\"></ion-icon>\n <ion-label>{{variable.identifier() || variableConfig.id }}</ion-label>\n </ion-item> -->\n <ion-card-content *ngIf=\"monitor\">\n <ng-container [ngSwitch]=\"cardType\">\n <ion-item *ngSwitchCase=\"'text'\" lines=\"none\" class=\"ion-no-padding\">\n <monitoring-variable-value\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [editable]=\"editMode\"\n ></monitoring-variable-value>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <ion-item *ngSwitchCase=\"'select'\" lines=\"none\" class=\"ion-no-padding\">\n <tap-variable-select\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [options]=\"selectOptions\"\n [editable]=\"editMode\"\n ></tap-variable-select>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <tap-variable-toggle\n *ngSwitchCase=\"'switch'\"\n [variable]=\"_variable\"\n ></tap-variable-toggle>\n <tap-variable-buttons\n *ngSwitchCase=\"'buttons'\"\n [variable]=\"variable\"\n [buttons]=\"monitoringButtons\"\n ></tap-variable-buttons>\n <tap-variable-range\n *ngSwitchCase=\"'range'\"\n [variable]=\"_variable\"\n [pin]=\"true\"\n [snaps]=\"true\"\n [ticks]=\"true\"\n [min]=\"0\"\n [max]=\"100\"\n ></tap-variable-range>\n <ion-text color=\"danger\" *ngSwitchDefault>\n <ion-icon name=\"alert\"></ion-icon> Unknown card type {{ cardType }}\n </ion-text>\n </ng-container>\n </ion-card-content>\n <ion-card-content *ngIf=\"error\">\n <ion-text color=\"danger\">{{ error }}</ion-text>\n </ion-card-content>\n <!--\n <ion-item>\n <ion-select\n [(ngModel)]=\"cardType\"\n okText=\"Select\"\n cancelText=\"Dismiss\"\n (ionChange)=\"onCardTypeChange($event)\"\n >\n <ion-select-option\n *ngFor=\"let cardType of cardTypes\"\n value=\"{{ cardType }}\"\n >{{ cardType }}</ion-select-option\n >\n </ion-select>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"toggleMonitoring()\" *ngIf=\"showStartStopMonitoring\">\n <ion-icon *ngIf=\"!playMonitoring\" name=\"play\"></ion-icon>\n <ion-icon *ngIf=\"playMonitoring\" name=\"pause\"></ion-icon>\n </ion-button>\n <ion-button (click)=\"editMode = !editMode\">\n <ion-icon *ngIf=\"!editMode\" name=\"create\"></ion-icon> <span *ngIf=\"!editMode\"></span>\n <ion-icon *ngIf=\"editMode\" name=\"close\"></ion-icon> \n </ion-button>\n <ion-button (click)=\"editConfig()\">\n \n <ion-icon name=\"cog\"></ion-icon> \n </ion-button>\n </ion-buttons>\n </ion-item>\n -->\n</ion-card>\n", styles: [".variable-value{font-size:1.4em;font-weight:700}ion-card-content{text-align:center}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i3.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i3.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i3.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: i3.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i3.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i4.MonitoringVariableValueComponent, selector: "monitoring-variable-value", inputs: ["lines", "unitValue", "error", "variable", "config", "inputOptions", "editable", "modalEdition", "valueStyle", "digitsInfo", "refreshable", "valueFormatting"] }, { kind: "component", type: i5.TapVariableRangeComponent, selector: "tap-variable-range", inputs: ["variable", "editable", "writeValueForEveryChange", "min", "max", "step", "color", "pin", "snaps", "ticks", "debounce", "leftIcon", "leftIconColor", "rightIcon", "rightIconColor", "value"], outputs: ["valueChange"] }, { kind: "component", type: i6.TapVariableButtonsComponent, selector: "tap-variable-buttons", inputs: ["variable", "editable", "color", "segment", "buttons"] }, { kind: "component", type: i7.TapVariableToggleComponent, selector: "tap-variable-toggle", inputs: ["textOnLeft", "textOnRight", "lines", "toggleColor", "variable", "editable", "valueOn", "valueOff", "chip"] }, { kind: "component", type: i8.TapVariableSelectComponent, selector: "tap-variable-select", inputs: ["variable", "value", "editable", "refreshable", "multiple", "lines", "options"], outputs: ["valueChange"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VariableCardComponent, decorators: [{ type: Component, args: [{ selector: 'app-variable-card', template: "<ion-card *ngIf=\"_variable\">\n <ion-item lines=\"none\">\n <ion-label slot=\"start\">{{ bundleName }}</ion-label>\n <ion-label slot=\"end\">#{{ _variable.id }}</ion-label>\n </ion-item>\n <!-- <ion-item>\n <ion-icon *ngIf=\"icon\" name=\"{{icon}}\" slot=\"start\"></ion-icon>\n <ion-label>{{variable.identifier() || variableConfig.id }}</ion-label>\n </ion-item> -->\n <ion-card-content *ngIf=\"monitor\">\n <ng-container [ngSwitch]=\"cardType\">\n <ion-item *ngSwitchCase=\"'text'\" lines=\"none\" class=\"ion-no-padding\">\n <monitoring-variable-value\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [editable]=\"editMode\"\n ></monitoring-variable-value>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <ion-item *ngSwitchCase=\"'select'\" lines=\"none\" class=\"ion-no-padding\">\n <tap-variable-select\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [options]=\"selectOptions\"\n [editable]=\"editMode\"\n ></tap-variable-select>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <tap-variable-toggle\n *ngSwitchCase=\"'switch'\"\n [variable]=\"_variable\"\n ></tap-variable-toggle>\n <tap-variable-buttons\n *ngSwitchCase=\"'buttons'\"\n [variable]=\"variable\"\n [buttons]=\"monitoringButtons\"\n ></tap-variable-buttons>\n <tap-variable-range\n *ngSwitchCase=\"'range'\"\n [variable]=\"_variable\"\n [pin]=\"true\"\n [snaps]=\"true\"\n [ticks]=\"true\"\n [min]=\"0\"\n [max]=\"100\"\n ></tap-variable-range>\n <ion-text color=\"danger\" *ngSwitchDefault>\n <ion-icon name=\"alert\"></ion-icon> Unknown card type {{ cardType }}\n </ion-text>\n </ng-container>\n </ion-card-content>\n <ion-card-content *ngIf=\"error\">\n <ion-text color=\"danger\">{{ error }}</ion-text>\n </ion-card-content>\n <!--\n <ion-item>\n <ion-select\n [(ngModel)]=\"cardType\"\n okText=\"Select\"\n cancelText=\"Dismiss\"\n (ionChange)=\"onCardTypeChange($event)\"\n >\n <ion-select-option\n *ngFor=\"let cardType of cardTypes\"\n value=\"{{ cardType }}\"\n >{{ cardType }}</ion-select-option\n >\n </ion-select>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"toggleMonitoring()\" *ngIf=\"showStartStopMonitoring\">\n <ion-icon *ngIf=\"!playMonitoring\" name=\"play\"></ion-icon>\n <ion-icon *ngIf=\"playMonitoring\" name=\"pause\"></ion-icon>\n </ion-button>\n <ion-button (click)=\"editMode = !editMode\">\n <ion-icon *ngIf=\"!editMode\" name=\"create\"></ion-icon> <span *ngIf=\"!editMode\"></span>\n <ion-icon *ngIf=\"editMode\" name=\"close\"></ion-icon> \n </ion-button>\n <ion-button (click)=\"editConfig()\">\n \n <ion-icon name=\"cog\"></ion-icon> \n </ion-button>\n </ion-buttons>\n </ion-item>\n -->\n</ion-card>\n", styles: [".variable-value{font-size:1.4em;font-weight:700}ion-card-content{text-align:center}\n"] }] }], ctorParameters: function () { return [{ type: i1.Router }]; }, propDecorators: { cardType: [{ type: Input }], cardTypes: [{ type: Input }], editMode: [{ type: Input }], monitor: [{ type: Input }], showStartStopMonitoring: [{ type: Input }], unit: [{ type: Input }], bundleName: [{ type: Input }], variable: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFyaWFibGUtY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pb3RpemUtaW9uaWMvbW9uaXRvcmluZy9zcmMvbGliL3VpLWNvbXBvbmVudHMvdmFyaWFibGUtY2FyZC92YXJpYWJsZS1jYXJkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9tb25pdG9yaW5nL3NyYy9saWIvdWktY29tcG9uZW50cy92YXJpYWJsZS1jYXJkL3ZhcmlhYmxlLWNhcmQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDNUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLGtCQUFrQixDQUFDOzs7Ozs7Ozs7O0FBa0JqRSxNQUFNLE9BQU8scUJBQXFCO0lBNkNoQyxvREFBb0Q7SUFFcEQsSUFBYSxRQUFRLENBQUMsUUFBK0I7UUFDbkQsa0VBQWtFO1FBQ2xFLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO1FBQzFCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN0QixJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQ2xDO1FBQ0QsSUFBSSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUM3QyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDZCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7b0JBQ3RCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO2lCQUNwQjtZQUNILENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDZiw2Q0FBNkM7Z0JBQzdDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ3JCLENBQUM7WUFDRCxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUNiLHlFQUF5RTtZQUMzRSxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE9BQU8sMEJBQTBCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRCxZQUFtQixNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQXhFakMsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFFYixhQUFRLEdBQWEsTUFBTSxDQUFDO1FBRTVCLGNBQVMsR0FBZTtZQUMvQixXQUFXO1lBQ1gsT0FBTztZQUNQLFFBQVE7WUFDUixNQUFNO1lBQ04sU0FBUztZQUNULE9BQU87WUFDUCxRQUFRO1NBQ1QsQ0FBQztRQUVPLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFFakIsWUFBTyxHQUFHLElBQUksQ0FBQztRQUVmLDRCQUF1QixHQUFHLEtBQUssQ0FBQztRQUVoQyxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBRVYsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUc1QixVQUFLLEdBQVEsU0FBUyxDQUFDO1FBQ3ZCLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBRXRCLHNCQUFpQixHQUF3QixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDcEUsT0FBTztnQkFDTCxLQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ2IsS0FBSyxFQUFFLENBQUM7YUFDVCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxrQkFBYSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMzQyxPQUFPO2dCQUNMLEdBQUcsRUFBRSxDQUFDO2dCQUNOLElBQUksRUFBRSxTQUFTLENBQUMsRUFBRTthQUNuQixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFnQ2lDLENBQUM7SUFFckMsSUFBSSxjQUFjO1FBQ2hCLElBQUksSUFBSSxDQUFDLFNBQVMsWUFBWSxXQUFXLEVBQUU7WUFDekMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7U0FDdEM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsaUJBQWlCO0lBQ2pCLHNEQUFzRDtJQUN0RCxJQUFJO0lBRUosS0FBSyxDQUFDLHdCQUF3QixDQUFDLE9BQWdCO1FBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ25CLE1BQU0sUUFBUSxDQUFDLHlCQUF5QixDQUN0Qyx1QkFBdUIsRUFDdkIsVUFBVSxDQUNYLENBQUM7U0FDSDtRQUNELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxzQkFBc0I7UUFDdEIsMEVBQTBFO1FBQzFFLHdCQUF3QjtRQUN4QixLQUFLO0lBQ1AsQ0FBQztJQUVELGdEQUFnRDtJQUNoRCwwQ0FBMEM7SUFDMUMsMEJBQTBCO0lBQzFCLG9CQUFvQjtJQUNwQiwrQkFBK0I7SUFDL0IsZUFBZTtJQUNmLDRCQUE0QjtJQUM1QiwrQkFBK0I7SUFDL0IsZUFBZTtJQUNmLE1BQU07SUFDTixJQUFJO0lBRUosV0FBVztRQUNULElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN0QixJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQ2xDO1FBQ0Qsd0NBQXdDO1FBQ3hDLGtEQUFrRDtRQUNsRCxJQUFJO0lBQ04sQ0FBQztJQUVELGdCQUFnQixDQUFDLE1BQXdDO1FBQ3ZELDJDQUEyQztRQUMzQyx1Q0FBdUM7SUFDekMsQ0FBQztJQUVELGdCQUFnQjtRQUNkLHNCQUFzQjtRQUN0Qix5QkFBeUI7UUFDekIsbUZBQW1GO1FBQ25GLElBQUk7UUFDSixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUN6Qyw0QkFBNEI7UUFDNUIsNkVBQTZFO1FBQzdFLHFDQUFxQztRQUNyQywwQkFBMEI7UUFDMUIsb0NBQW9DO1FBQ3BDLFFBQVE7UUFDUixXQUFXO1FBQ1gsd0NBQXdDO1FBQ3hDLHNDQUFzQztRQUN0QyxJQUFJO1FBQ0osSUFBSTtJQUNOLENBQUM7O3NJQWhKVSxxQkFBcUI7MEhBQXJCLHFCQUFxQiwrUUNyQmxDLG9uR0F1RkE7NEZEbEVhLHFCQUFxQjtrQkFMakMsU0FBUzsrQkFDRSxtQkFBbUI7NkZBT3BCLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFVRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBd0JPLFFBQVE7c0JBQXBCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBnZXRBYnN0cmFjdFZhcmlhYmxlT3JFcnJvciwgTGliRXJyb3IgfSBmcm9tICdAaW90aXplL2lvbmljJztcbmltcG9ydCB7IEFic3RyYWN0VmFyaWFibGUsIFRhcFZhcmlhYmxlIH0gZnJvbSAnQGlvdGl6ZS90YXAvZGF0YSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFRhcFZhcmlhYmxlQnV0dG9uIH0gZnJvbSAnLi4vdGFwLXZhcmlhYmxlLWJ1dHRvbnMvdGFwLXZhcmlhYmxlLWJ1dHRvbnMuY29tcG9uZW50JztcblxudHlwZSBDYXJkVHlwZSA9XG4gIHwgJ2dhdWdlJ1xuICB8ICd0ZXh0J1xuICB8ICdjaGFydCdcbiAgfCAnc3dpdGNoJ1xuICB8ICdidXR0b25zJ1xuICB8ICdyYW5nZSdcbiAgfCAnc2VsZWN0JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXZhcmlhYmxlLWNhcmQnLFxuICB0ZW1wbGF0ZVVybDogJy4vdmFyaWFibGUtY2FyZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3ZhcmlhYmxlLWNhcmQuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgVmFyaWFibGVDYXJkQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgd2FpdEZvclN1Ym1pdCA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIGNhcmRUeXBlOiBDYXJkVHlwZSA9ICd0ZXh0JztcblxuICBASW5wdXQoKSBjYXJkVHlwZXM6IENhcmRUeXBlW10gPSBbXG4gICAgLy8gJ2NoYXJ0JyxcbiAgICAnZ2F1Z2UnLFxuICAgICdzd2l0Y2gnLFxuICAgICd0ZXh0JyxcbiAgICAnYnV0dG9ucycsXG4gICAgJ3JhbmdlJyxcbiAgICAnc2VsZWN0JyxcbiAgXTtcblxuICBASW5wdXQoKSBlZGl0TW9kZSA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIG1vbml0b3IgPSB0cnVlO1xuXG4gIEBJbnB1dCgpIHNob3dTdGFydFN0b3BNb25pdG9yaW5nID0gZmFsc2U7XG5cbiAgQElucHV0KCkgdW5pdCA9ICcnO1xuXG4gIEBJbnB1dCgpIGJ1bmRsZU5hbWUgPSAnLi4uJztcblxuICBlcnJvcj86IEVycm9yO1xuICB2YWx1ZTogYW55ID0gJ1Vua25vd24nO1xuICByZWZyZXNoVmFsdWVzID0gZmFsc2U7XG5cbiAgbW9uaXRvcmluZ0J1dHRvbnM6IFRhcFZhcmlhYmxlQnV0dG9uW10gPSBbMCwgMSwgMiwgMywgNCwgNV0ubWFwKCh2KSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxhYmVsOiBgJHt2fWAsXG4gICAgICB2YWx1ZTogdixcbiAgICB9O1xuICB9KTtcblxuICBzZWxlY3RPcHRpb25zID0gWzAsIDEsIDIsIDMsIDQsIDVdLm1hcCgodikgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBrZXk6IHYsXG4gICAgICB0ZXh0OiBgVmFsdWUgJHt2fWAsXG4gICAgfTtcbiAgfSk7XG5cbiAgcHVibGljIF92YXJpYWJsZT86IEFic3RyYWN0VmFyaWFibGU8YW55PjtcbiAgcHJpdmF0ZSBfc3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICAvLyBwcml2YXRlIF9zd2l0Y2hCdXR0b25TdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgQElucHV0KCkgc2V0IHZhcmlhYmxlKHZhcmlhYmxlOiBBYnN0cmFjdFZhcmlhYmxlPGFueT4pIHtcbiAgICAvLyBjb25zb2xlLmxvZygnVmFyaWFibGVDYXJkQ29tcG9uZW50JywgJ1NFVCBWQVJJQUJMRScsIHZhcmlhYmxlKTtcbiAgICB0aGlzLl92YXJpYWJsZSA9IHZhcmlhYmxlO1xuICAgIGlmICh0aGlzLl9zdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX3N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSB2YXJpYWJsZS52YWx1ZXMuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5yZWZyZXNoVmFsdWVzKSB7XG4gICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAvLyBjb25zb2xlLndhcm4oYE1vbml0b3JpbmcgZXJyb3I6IGAsIGVycm9yKTtcbiAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yO1xuICAgICAgfSxcbiAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgIC8vIGNvbnNvbGUud2FybignVmFyaWFibGVDYXJkQ29tcG9uZW50JywgJ3ZhbHVlcyBvYnNlcnZhYmxlIGlzIGNvbXBsZXRlJylcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBnZXQgdmFyaWFibGUoKTogQWJzdHJhY3RWYXJpYWJsZTxhbnk+IHtcbiAgICByZXR1cm4gZ2V0QWJzdHJhY3RWYXJpYWJsZU9yRXJyb3IodGhpcy5fdmFyaWFibGUpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIHJvdXRlcjogUm91dGVyKSB7fVxuXG4gIGdldCB2YXJpYWJsZUNvbmZpZygpOiBUYXBWYXJpYWJsZS5Db25maWcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0aGlzLl92YXJpYWJsZSBpbnN0YW5jZW9mIFRhcFZhcmlhYmxlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdmFyaWFibGUuY29udGV4dC5jb25maWc7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBlZGl0Q29uZmlnKCkge1xuICAvLyAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2RldmljZS9tb25pdG9yaW5nL2FkZCddKTtcbiAgLy8gfVxuXG4gIGFzeW5jIHN3aXRjaEJ1dHRvblRvZ2dsZUFjdGlvbihjaGVja2VkOiBib29sZWFuKSB7XG4gICAgaWYgKCF0aGlzLl92YXJpYWJsZSkge1xuICAgICAgdGhyb3cgTGliRXJyb3IuY29tcG9uZW50QXJndW1lbnRSZXF1aXJlZChcbiAgICAgICAgJ1ZhcmlhYmxlQ2FyZENvbXBvbmVudCcsXG4gICAgICAgICd2YXJpYWJsZSdcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gY2hlY2tlZCA/IDEgOiAwO1xuICAgIGF3YWl0IHRoaXMuX3ZhcmlhYmxlLndyaXRlKHZhbHVlKTtcbiAgICAvLyAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgLy8gICBjb25zb2xlLndhcm4oYENhbm5vdCB3cml0ZSAke3RoaXMuX3ZhcmlhYmxlLmlkZW50aWZpZXIoKX06ICR7ZXJyb3J9YClcbiAgICAvLyAgIHRoaXMuZXJyb3IgPSBlcnJvcjtcbiAgICAvLyB9KVxuICB9XG5cbiAgLy8gb25FZGl0RXZlbnQoZXZlbnQ6IE1vbml0b3JpbmdFZGl0VGV4dEV2ZW50KSB7XG4gIC8vICAgY29uc29sZS5sb2coJ0VESVQgRVZFTlQgPT4gJywgZXZlbnQpO1xuICAvLyAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAvLyAgICAgY2FzZSAnQ0xPU0UnOlxuICAvLyAgICAgICB0aGlzLmVkaXRNb2RlID0gZmFsc2U7XG4gIC8vICAgICAgIGJyZWFrO1xuICAvLyAgICAgY2FzZSAnV1JJVEVfU1VDQ0VTUyc6XG4gIC8vICAgICAgIHRoaXMuZWRpdE1vZGUgPSBmYWxzZTtcbiAgLy8gICAgICAgYnJlYWs7XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuX3N1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5fc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIC8vIGlmICh0aGlzLl9zd2l0Y2hCdXR0b25TdWJzY3JpcHRpb24pIHtcbiAgICAvLyAgIHRoaXMuX3N3aXRjaEJ1dHRvblN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIC8vIH1cbiAgfVxuXG4gIG9uQ2FyZFR5cGVDaGFuZ2UoJGV2ZW50OiBDdXN0b21FdmVudDx7IHZhbHVlOiBDYXJkVHlwZSB9Pikge1xuICAgIC8vIGNvbnNvbGUubG9nKCdvbkNhcmRUeXBlQ2hhbmdlJywgJGV2ZW50KTtcbiAgICAvLyB0aGlzLmNhcmRUeXBlID0gJGV2ZW50LmRldGFpbC52YWx1ZTtcbiAgfVxuXG4gIHRvZ2dsZU1vbml0b3JpbmcoKSB7XG4gICAgLy8gaWYgKHRoaXMubW9uaXRvcikge1xuICAgIC8vIGlmICghdGhpcy5fdmFyaWFibGUpIHtcbiAgICAvLyAgIHRocm93IExpYkVycm9yLmNvbXBvbmVudEFyZ3VtZW50UmVxdWlyZWQoJ1ZhcmlhYmxlQ2FyZENvbXBvbmVudCcsICd2YXJpYWJsZScpO1xuICAgIC8vIH1cbiAgICB0aGlzLnJlZnJlc2hWYWx1ZXMgPSAhdGhpcy5yZWZyZXNoVmFsdWVzO1xuICAgIC8vIGlmICh0aGlzLnJlZnJlc2hWYWx1ZXMpIHtcbiAgICAvLyAgIC8vIGNvbnNvbGUubG9nKCdTdGFydCBtb25pdG9yaW5nIHdpdGggcGVyaW9kOiAnLCB0aGlzLm1vbml0b3JpbmdQZXJpb2QpO1xuICAgIC8vICAgdGhpcy5fdmFyaWFibGUubW9uaXRvcigpLnN0YXJ0KHtcbiAgICAvLyAgICAgZm9yY2VDaGFuZ2U6IGZhbHNlLFxuICAgIC8vICAgICBwZXJpb2Q6IHRoaXMubW9uaXRvcmluZ1BlcmlvZFxuICAgIC8vICAgfSk7XG4gICAgLy8gfSBlbHNlIHtcbiAgICAvLyAgIC8vIGNvbnNvbGUubG9nKCdQYXVzZSBtb25pdG9yaW5nJyk7XG4gICAgLy8gICB0aGlzLl92YXJpYWJsZS5tb25pdG9yKCkucGF1c2UoKTtcbiAgICAvLyB9XG4gICAgLy8gfVxuICB9XG59XG4iLCI8aW9uLWNhcmQgKm5nSWY9XCJfdmFyaWFibGVcIj5cbiAgPGlvbi1pdGVtIGxpbmVzPVwibm9uZVwiPlxuICAgIDxpb24tbGFiZWwgc2xvdD1cInN0YXJ0XCI+e3sgYnVuZGxlTmFtZSB9fTwvaW9uLWxhYmVsPlxuICAgIDxpb24tbGFiZWwgc2xvdD1cImVuZFwiPiN7eyBfdmFyaWFibGUuaWQgfX08L2lvbi1sYWJlbD5cbiAgPC9pb24taXRlbT5cbiAgPCEtLSA8aW9uLWl0ZW0+XG4gICAgPGlvbi1pY29uICpuZ0lmPVwiaWNvblwiIG5hbWU9XCJ7e2ljb259fVwiIHNsb3Q9XCJzdGFydFwiPjwvaW9uLWljb24+XG4gICAgPGlvbi1sYWJlbD57e3ZhcmlhYmxlLmlkZW50aWZpZXIoKSB8fCB2YXJpYWJsZUNvbmZpZy5pZCB9fTwvaW9uLWxhYmVsPlxuICA8L2lvbi1pdGVtPiAtLT5cbiAgPGlvbi1jYXJkLWNvbnRlbnQgKm5nSWY9XCJtb25pdG9yXCI+XG4gICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwiY2FyZFR5cGVcIj5cbiAgICAgIDxpb24taXRlbSAqbmdTd2l0Y2hDYXNlPVwiJ3RleHQnXCIgbGluZXM9XCJub25lXCIgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICA8bW9uaXRvcmluZy12YXJpYWJsZS12YWx1ZVxuICAgICAgICAgIHN0eWxlPVwibWFyZ2luOiBhdXRvXCJcbiAgICAgICAgICBbbGluZXNdPVwiJ25vbmUnXCJcbiAgICAgICAgICBbdmFyaWFibGVdPVwidmFyaWFibGVcIlxuICAgICAgICAgIFtlZGl0YWJsZV09XCJlZGl0TW9kZVwiXG4gICAgICAgID48L21vbml0b3JpbmctdmFyaWFibGUtdmFsdWU+XG4gICAgICAgIDxzcGFuIHNsb3Q9XCJlbmRcIiAqbmdJZj1cInVuaXRcIiBjbGFzcz1cInVuaXRcIj57eyB1bml0IH19PC9zcGFuPlxuICAgICAgPC9pb24taXRlbT5cbiAgICAgIDxpb24taXRlbSAqbmdTd2l0Y2hDYXNlPVwiJ3NlbGVjdCdcIiBsaW5lcz1cIm5vbmVcIiBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgIDx0YXAtdmFyaWFibGUtc2VsZWN0XG4gICAgICAgICAgc3R5bGU9XCJtYXJnaW46IGF1dG9cIlxuICAgICAgICAgIFtsaW5lc109XCInbm9uZSdcIlxuICAgICAgICAgIFt2YXJpYWJsZV09XCJ2YXJpYWJsZVwiXG4gICAgICAgICAgW29wdGlvbnNdPVwic2VsZWN0T3B0aW9uc1wiXG4gICAgICAgICAgW2VkaXRhYmxlXT1cImVkaXRNb2RlXCJcbiAgICAgICAgPjwvdGFwLXZhcmlhYmxlLXNlbGVjdD5cbiAgICAgICAgPHNwYW4gc2xvdD1cImVuZFwiICpuZ0lmPVwidW5pdFwiIGNsYXNzPVwidW5pdFwiPnt7IHVuaXQgfX08L3NwYW4+XG4gICAgICA8L2lvbi1pdGVtPlxuICAgICAgPHRhcC12YXJpYWJsZS10b2dnbGVcbiAgICAgICAgKm5nU3dpdGNoQ2FzZT1cIidzd2l0Y2gnXCJcbiAgICAgICAgW3ZhcmlhYmxlXT1cIl92YXJpYWJsZVwiXG4gICAgICA+PC90YXAtdmFyaWFibGUtdG9nZ2xlPlxuICAgICAgPHRhcC12YXJpYWJsZS1idXR0b25zXG4gICAgICAgICpuZ1N3aXRjaENhc2U9XCInYnV0dG9ucydcIlxuICAgICAgICBbdmFyaWFibGVdPVwidmFyaWFibGVcIlxuICAgICAgICBbYnV0dG9uc109XCJtb25pdG9yaW5nQnV0dG9uc1wiXG4gICAgICA+PC90YXAtdmFyaWFibGUtYnV0dG9ucz5cbiAgICAgIDx0YXAtdmFyaWFibGUtcmFuZ2VcbiAgICAgICAgKm5nU3dpdGNoQ2FzZT1cIidyYW5nZSdcIlxuICAgICAgICBbdmFyaWFibGVdPVwiX3ZhcmlhYmxlXCJcbiAgICAgICAgW3Bpbl09XCJ0cnVlXCJcbiAgICAgICAgW3NuYXBzXT1cInRydWVcIlxuICAgICAgICBbdGlja3NdPVwidHJ1ZVwiXG4gICAgICAgIFttaW5dPVwiMFwiXG4gICAgICAgIFttYXhdPVwiMTAwXCJcbiAgICAgID48L3RhcC12YXJpYWJsZS1yYW5nZT5cbiAgICAgIDxpb24tdGV4dCBjb2xvcj1cImRhbmdlclwiICpuZ1N3aXRjaERlZmF1bHQ+XG4gICAgICAgIDxpb24taWNvbiBuYW1lPVwiYWxlcnRcIj48L2lvbi1pY29uPiBVbmtub3duIGNhcmQgdHlwZSB7eyBjYXJkVHlwZSB9fVxuICAgICAgPC9pb24tdGV4dD5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9pb24tY2FyZC1jb250ZW50PlxuICA8aW9uLWNhcmQtY29udGVudCAqbmdJZj1cImVycm9yXCI+XG4gICAgPGlvbi10ZXh0IGNvbG9yPVwiZGFuZ2VyXCI+e3sgZXJyb3IgfX08L2lvbi10ZXh0PlxuICA8L2lvbi1jYXJkLWNvbnRlbnQ+XG4gIDwhLS1cbiAgPGlvbi1pdGVtPlxuICAgIDxpb24tc2VsZWN0XG4gICAgICBbKG5nTW9kZWwpXT1cImNhcmRUeXBlXCJcbiAgICAgIG9rVGV4dD1cIlNlbGVjdFwiXG4gICAgICBjYW5jZWxUZXh0PVwiRGlzbWlzc1wiXG4gICAgICAoaW9uQ2hhbmdlKT1cIm9uQ2FyZFR5cGVDaGFuZ2UoJGV2ZW50KVwiXG4gICAgPlxuICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uXG4gICAgICAgICpuZ0Zvcj1cImxldCBjYXJkVHlwZSBvZiBjYXJkVHlwZXNcIlxuICAgICAgICB2YWx1ZT1cInt7IGNhcmRUeXBlIH19XCJcbiAgICAgICAgPnt7IGNhcmRUeXBlIH19PC9pb24tc2VsZWN0LW9wdGlvblxuICAgICAgPlxuICAgIDwvaW9uLXNlbGVjdD5cbiAgICA8aW9uLWJ1dHRvbnMgc2xvdD1cImVuZFwiPlxuICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cInRvZ2dsZU1vbml0b3JpbmcoKVwiICpuZ0lmPVwic2hvd1N0YXJ0U3RvcE1vbml0b3JpbmdcIj5cbiAgICAgICAgPGlvbi1pY29uICpuZ0lmPVwiIXBsYXlNb25pdG9yaW5nXCIgbmFtZT1cInBsYXlcIj48L2lvbi1pY29uPlxuICAgICAgICA8aW9uLWljb24gKm5nSWY9XCJwbGF5TW9uaXRvcmluZ1wiIG5hbWU9XCJwYXVzZVwiPjwvaW9uLWljb24+XG4gICAgICA8L2lvbi1idXR0b24+XG4gICAgICA8aW9uLWJ1dHRvbiAoY2xpY2spPVwiZWRpdE1vZGUgPSAhZWRpdE1vZGVcIj5cbiAgICAgICAgPGlvbi1pY29uICpuZ0lmPVwiIWVkaXRNb2RlXCIgbmFtZT1cImNyZWF0ZVwiPjwvaW9uLWljb24+IDxzcGFuICpuZ0lmPVwiIWVkaXRNb2RlXCI+PC9zcGFuPlxuICAgICAgICA8aW9uLWljb24gKm5nSWY9XCJlZGl0TW9kZVwiIG5hbWU9XCJjbG9zZVwiPjwvaW9uLWljb24+IFxuICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cImVkaXRDb25maWcoKVwiPlxuICAgICAgICBcbiAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJjb2dcIj48L2lvbi1pY29uPiBcbiAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICA8L2lvbi1idXR0b25zPlxuICA8L2lvbi1pdGVtPlxuICAtLT5cbjwvaW9uLWNhcmQ+XG4iXX0=