UNPKG

@iotize/ionic

Version:

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

262 lines 31.4 kB
import { Component, ContentChild, Directive, ElementRef, EventEmitter, HostListener, Input, Output, } from '@angular/core'; import { TapError } from '@iotize/tap'; import { ResultCode } from '@iotize/tap/client/api'; import { TapClientError } from '@iotize/tap/client/impl'; import { debug } from '../logger'; import { TaskManagerService } from '../task-manager/task-manager.service'; import * as i0 from "@angular/core"; import * as i1 from "../task-manager/task-manager.service"; import * as i2 from "@angular/common"; const TAG = 'TaskManagerComponent'; export class TaskManagerActionCancelDirective { elementRef; onClick = new EventEmitter(); constructor(elementRef) { this.elementRef = elementRef; } // disable(value: boolean) { // // this.elementRef. // } onClickListener() { debug('app-task-manager-action-cancel clicked'); this.onClick.emit(); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerActionCancelDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: TaskManagerActionCancelDirective, selector: "[app-task-manager-action-cancel]", outputs: { onClick: "onClick" }, host: { listeners: { "click": "onClickListener()" } }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerActionCancelDirective, decorators: [{ type: Directive, args: [{ selector: '[app-task-manager-action-cancel]', }] }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { onClick: [{ type: Output }], onClickListener: [{ type: HostListener, args: ['click'] }] } }); export class TaskManagerActionExecDirective { onClick = new EventEmitter(); constructor() { } // public tpl: TemplateRef<any> onClickListener() { this.onClick.emit(); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerActionExecDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: TaskManagerActionExecDirective, selector: "[app-task-manager-action-exec]", outputs: { onClick: "onClick" }, host: { listeners: { "click": "onClickListener()" } }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerActionExecDirective, decorators: [{ type: Directive, args: [{ selector: '[app-task-manager-action-exec]', }] }], ctorParameters: () => [], propDecorators: { onClick: [{ type: Output }], onClickListener: [{ type: HostListener, args: ['click'] }] } }); export class TaskManagerRunningComponent { taskManager; /** Template inside the MatTab view that contains an `<ng-content>`. */ // @ViewChild(TemplateRef, { static: true }) _implicitContent: TemplateRef<any>; context; constructor(taskManager) { this.taskManager = taskManager; } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerRunningComponent, deps: [{ token: i1.TaskManagerService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TaskManagerRunningComponent, selector: "app-task-manager-running", inputs: { context: "context" }, ngImport: i0, template: ' <ng-content></ng-content> ', isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerRunningComponent, decorators: [{ type: Component, args: [{ selector: 'app-task-manager-running', template: ' <ng-content></ng-content> ', }] }], ctorParameters: () => [{ type: i1.TaskManagerService }], propDecorators: { context: [{ type: Input }] } }); export class TaskManagerDelayedComponent { taskManager; /** Template inside the MatTab view that contains an `<ng-content>`. */ // @ViewChild(TemplateRef, { static: true }) _implicitContent: TemplateRef<any>; context; constructor(taskManager) { this.taskManager = taskManager; } cancelTask() { debug(TAG, 'Cancel task click'); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerDelayedComponent, deps: [{ token: i1.TaskManagerService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TaskManagerDelayedComponent, selector: "app-task-manager-delayed", inputs: { context: "context" }, ngImport: i0, template: ' <ng-content></ng-content> ', isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerDelayedComponent, decorators: [{ type: Component, args: [{ selector: 'app-task-manager-delayed', template: ' <ng-content></ng-content> ', }] }], ctorParameters: () => [{ type: i1.TaskManagerService }], propDecorators: { context: [{ type: Input }] } }); export class TaskManagerActionComponent { taskManager; context; /** Template inside the MatTab view that contains an `<ng-content>`. */ // @ViewChild(TemplateRef, { static: true }) _implicitContent: TemplateRef<any>; // @ContentChildren(TaskManagerActionExecDirective) execButton!: TaskManagerActionExecDirective; constructor(taskManager) { this.taskManager = taskManager; } performTask() { debug(TAG, 'Perform task click'); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerActionComponent, deps: [{ token: i1.TaskManagerService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TaskManagerActionComponent, selector: "app-task-manager-action", inputs: { context: "context" }, ngImport: i0, template: ' <ng-content></ng-content> ', isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerActionComponent, decorators: [{ type: Component, args: [{ selector: 'app-task-manager-action', template: ' <ng-content></ng-content> ', }] }], ctorParameters: () => [{ type: i1.TaskManagerService }], propDecorators: { context: [{ type: Input }] } }); export class TaskManagerComponent { taskManager; taskContainer; set task(taskContainerOrString) { let taskContainer; taskContainer = taskContainerOrString; debug(TAG, 'set task ', taskContainer?.task?.id); this.taskContainer = taskContainer; } get taskId() { return this.taskContainer?.task?.id; } cancelDirective; execDirective; // @ContentChild(TaskManagerActionComponent, {}) actionComponent: TaskManagerActionComponent; constructor(taskManager) { this.taskManager = taskManager; } get loading() { return false; } get taskState() { return this.taskContainer?.meta?.state; } get actionTemplateContext() { const cont = this._createContext(); if ('execTask' in cont) { cont['execTask'] = (...context) => { this.execTask(context); }; } return { $implicit: cont }; } get delayedTemplateContext() { const context = this._createContext(); if ('execTask' in this) { context['execTask'] = () => { if (this.taskId && this.taskManager.hasTask(this.taskId)) { this.taskManager.cancel(this.taskId); } }; } return { $implicit: context }; } _createContext() { return this; } ngAfterViewInit() { if (this.cancelDirective) { this.cancelDirective.onClick.subscribe(() => { this.cancelTask(); }); } else { debug(TAG, 'cancel button is not set yet'); } if (this.execDirective) { this.execDirective.onClick.subscribe(() => { this.execTask(); }); } } ngOnDestroy() { debug(TAG, 'Task', this.taskId, 'component ngOnDestroy'); this.cancelTask(); } cancelTask() { debug(TAG, 'cancelTask clicked!'); if (!this.taskId) { return; } if (this.taskManager.hasTask(this.taskId)) { this.taskManager.cancel(this.taskId); } else { debug(TAG, 'cannot cancel task ', this.taskId, 'it does not exist'); } } explainDelayReason() { const err = this.taskContainer?.meta.error; if (err) { const codeError = err; switch (codeError.code) { case TapError.Code.ResponseStatusError: switch (err.response.status) { case ResultCode.UNAUTHORIZED: return 'Waiting for user login'; } break; case TapError.Code.ExecuteRequestError: const cause = err.cause; if (cause) { switch (cause.code) { case TapClientError.Code.NotConnectedError: case 'NfcTagLostError': case 'NfcNotConnectedError': return 'Waiting for Tap reconnection'; } } } return 'Unknown reason'; } } execTask(context) { const container = this.taskContainer; if (!container) { return; } debug(TAG, 'execTask ', container.task.id); this.taskManager.addTaskContainer(container); // this.execDirective.disable(true); this.taskManager.exec(container.task.id, context).subscribe({ error: (err) => { debug(`Task ${container.task.id} error: ${err.message}`); console.warn(err); // this.execDirective.disable(false); }, complete: () => { debug(`Task ${container.task.id} COMPLETED`); }, }); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerComponent, deps: [{ token: i1.TaskManagerService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TaskManagerComponent, selector: "app-task-manager", inputs: { task: "task" }, queries: [{ propertyName: "cancelDirective", first: true, predicate: TaskManagerActionCancelDirective, descendants: true, static: true }, { propertyName: "execDirective", first: true, predicate: TaskManagerActionExecDirective, descendants: true, static: true }], ngImport: i0, template: "<ng-container [ngSwitch]=\"taskState\">\n <ng-content\n select=\"app-task-manager-delayed\"\n *ngSwitchCase=\"'delayed'\"\n ></ng-content>\n <ng-content\n select=\"app-task-manager-running\"\n *ngSwitchCase=\"'running'\"\n ></ng-content>\n <ng-content select=\"app-task-manager-action\" *ngSwitchDefault></ng-content>\n</ng-container>\n", styles: [""], dependencies: [{ 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]" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TaskManagerComponent, decorators: [{ type: Component, args: [{ selector: 'app-task-manager', template: "<ng-container [ngSwitch]=\"taskState\">\n <ng-content\n select=\"app-task-manager-delayed\"\n *ngSwitchCase=\"'delayed'\"\n ></ng-content>\n <ng-content\n select=\"app-task-manager-running\"\n *ngSwitchCase=\"'running'\"\n ></ng-content>\n <ng-content select=\"app-task-manager-action\" *ngSwitchDefault></ng-content>\n</ng-container>\n" }] }], ctorParameters: () => [{ type: i1.TaskManagerService }], propDecorators: { task: [{ type: Input }], cancelDirective: [{ type: ContentChild, args: [TaskManagerActionCancelDirective, { static: true }] }], execDirective: [{ type: ContentChild, args: [TaskManagerActionExecDirective, { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay1tYW5hZ2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9zcmMvbGliL3Rhc2stbWFuYWdlci11aS90YXNrLW1hbmFnZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL3NyYy9saWIvdGFzay1tYW5hZ2VyLXVpL3Rhc2stbWFuYWdlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsUUFBUSxFQUEwQixNQUFNLGFBQWEsQ0FBQztBQUMvRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFbEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7Ozs7QUFFMUUsTUFBTSxHQUFHLEdBQUcsc0JBQXNCLENBQUM7QUFLbkMsTUFBTSxPQUFPLGdDQUFnQztJQUd0QjtJQUZYLE9BQU8sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBRTdDLFlBQXFCLFVBQXNCO1FBQXRCLGVBQVUsR0FBVixVQUFVLENBQVk7SUFBRyxDQUFDO0lBRS9DLDRCQUE0QjtJQUM1Qix3QkFBd0I7SUFDeEIsSUFBSTtJQUVtQixlQUFlO1FBQ3BDLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQzsySEFa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RSxFQUFFLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUMxRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDYixLQUFLLENBQUMsUUFBUSxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsV0FBVyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDekQsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDbEIscUNBQXFDO1lBQ3ZDLENBQUM7WUFDRCxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUNiLEtBQUssQ0FBQyxRQUFRLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUMvQyxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzsySEF2SVUsb0JBQW9COytHQUFwQixvQkFBb0IsK0hBZ0JqQixnQ0FBZ0MsOEZBRWhDLDhCQUE4Qiw4REM3SDlDLG1XQVdBOzs0RkRnR2Esb0JBQW9CO2tCQUxoQyxTQUFTOytCQUNFLGtCQUFrQjt1RkFPZixJQUFJO3NCQUFoQixLQUFLO2dCQWNOLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQ0FBZ0MsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBR2hFLGFBQWE7c0JBRFosWUFBWTt1QkFBQyw4QkFBOEIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvZGVFcnJvciB9IGZyb20gJ0Bpb3RpemUvY29tbW9uL2Vycm9yJztcbmltcG9ydCB7IFRhcEVycm9yLCBUYXBSZXNwb25zZVN0YXR1c0Vycm9yIH0gZnJvbSAnQGlvdGl6ZS90YXAnO1xuaW1wb3J0IHsgUmVzdWx0Q29kZSB9IGZyb20gJ0Bpb3RpemUvdGFwL2NsaWVudC9hcGknO1xuaW1wb3J0IHsgVGFwQ2xpZW50RXJyb3IgfSBmcm9tICdAaW90aXplL3RhcC9jbGllbnQvaW1wbCc7XG5pbXBvcnQgeyBkZWJ1ZyB9IGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBUYXNrTWFuYWdlciB9IGZyb20gJy4uL3Rhc2stbWFuYWdlci9kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBUYXNrTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLi90YXNrLW1hbmFnZXIvdGFzay1tYW5hZ2VyLnNlcnZpY2UnO1xuXG5jb25zdCBUQUcgPSAnVGFza01hbmFnZXJDb21wb25lbnQnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbYXBwLXRhc2stbWFuYWdlci1hY3Rpb24tY2FuY2VsXScsXG59KVxuZXhwb3J0IGNsYXNzIFRhc2tNYW5hZ2VyQWN0aW9uQ2FuY2VsRGlyZWN0aXZlIHtcbiAgQE91dHB1dCgpIG9uQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IocmVhZG9ubHkgZWxlbWVudFJlZjogRWxlbWVudFJlZikge31cblxuICAvLyBkaXNhYmxlKHZhbHVlOiBib29sZWFuKSB7XG4gIC8vICAgLy8gdGhpcy5lbGVtZW50UmVmLlxuICAvLyB9XG5cbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snKSBvbkNsaWNrTGlzdGVuZXIoKSB7XG4gICAgZGVidWcoJ2FwcC10YXNrLW1hbmFnZXItYWN0aW9uLWNhbmNlbCBjbGlja2VkJyk7XG4gICAgdGhpcy5vbkNsaWNrLmVtaXQoKTtcbiAgfVxufVxuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbYXBwLXRhc2stbWFuYWdlci1hY3Rpb24tZXhlY10nLFxufSlcbmV4cG9ydCBjbGFzcyBUYXNrTWFuYWdlckFjdGlvbkV4ZWNEaXJlY3RpdmUge1xuICBAT3V0cHV0KCkgb25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBjb25zdHJ1Y3RvcigpIHt9IC8vIHB1YmxpYyB0cGw6IFRlbXBsYXRlUmVmPGFueT5cblxuICBASG9zdExpc3RlbmVyKCdjbGljaycpIG9uQ2xpY2tMaXN0ZW5lcigpIHtcbiAgICB0aGlzLm9uQ2xpY2suZW1pdCgpO1xuICB9XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC10YXNrLW1hbmFnZXItcnVubmluZycsXG4gIHRlbXBsYXRlOiAnIDxuZy1jb250ZW50PjwvbmctY29udGVudD4gJyxcbn0pXG5leHBvcnQgY2xhc3MgVGFza01hbmFnZXJSdW5uaW5nQ29tcG9uZW50IHtcbiAgLyoqIFRlbXBsYXRlIGluc2lkZSB0aGUgTWF0VGFiIHZpZXcgdGhhdCBjb250YWlucyBhbiBgPG5nLWNvbnRlbnQ+YC4gKi9cbiAgLy8gQFZpZXdDaGlsZChUZW1wbGF0ZVJlZiwgeyBzdGF0aWM6IHRydWUgfSkgX2ltcGxpY2l0Q29udGVudDogVGVtcGxhdGVSZWY8YW55PjtcblxuICBASW5wdXQoKSBjb250ZXh0OiBhbnk7XG5cbiAgY29uc3RydWN0b3IocHVibGljIHRhc2tNYW5hZ2VyOiBUYXNrTWFuYWdlclNlcnZpY2UpIHt9XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC10YXNrLW1hbmFnZXItZGVsYXllZCcsXG4gIHRlbXBsYXRlOiAnIDxuZy1jb250ZW50PjwvbmctY29udGVudD4gJyxcbn0pXG5leHBvcnQgY2xhc3MgVGFza01hbmFnZXJEZWxheWVkQ29tcG9uZW50IHtcbiAgLyoqIFRlbXBsYXRlIGluc2lkZSB0aGUgTWF0VGFiIHZpZXcgdGhhdCBjb250YWlucyBhbiBgPG5nLWNvbnRlbnQ+YC4gKi9cbiAgLy8gQFZpZXdDaGlsZChUZW1wbGF0ZVJlZiwgeyBzdGF0aWM6IHRydWUgfSkgX2ltcGxpY2l0Q29udGVudDogVGVtcGxhdGVSZWY8YW55PjtcblxuICBASW5wdXQoKSBjb250ZXh0OiBhbnk7XG5cbiAgY29uc3RydWN0b3IocHVibGljIHRhc2tNYW5hZ2VyOiBUYXNrTWFuYWdlclNlcnZpY2UpIHt9XG5cbiAgY2FuY2VsVGFzaygpIHtcbiAgICBkZWJ1ZyhUQUcsICdDYW5jZWwgdGFzayBjbGljaycpO1xuICB9XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC10YXNrLW1hbmFnZXItYWN0aW9uJyxcbiAgdGVtcGxhdGU6ICcgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PiAnLFxufSlcbmV4cG9ydCBjbGFzcyBUYXNrTWFuYWdlckFjdGlvbkNvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGNvbnRleHQ6IGFueTtcblxuICAvKiogVGVtcGxhdGUgaW5zaWRlIHRoZSBNYXRUYWIgdmlldyB0aGF0IGNvbnRhaW5zIGFuIGA8bmctY29udGVudD5gLiAqL1xuICAvLyBAVmlld0NoaWxkKFRlbXBsYXRlUmVmLCB7IHN0YXRpYzogdHJ1ZSB9KSBfaW1wbGljaXRDb250ZW50OiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIC8vIEBDb250ZW50Q2hpbGRyZW4oVGFza01hbmFnZXJBY3Rpb25FeGVjRGlyZWN0aXZlKSBleGVjQnV0dG9uITogVGFza01hbmFnZXJBY3Rpb25FeGVjRGlyZWN0aXZlO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyB0YXNrTWFuYWdlcjogVGFza01hbmFnZXJTZXJ2aWNlKSB7fVxuXG4gIHBlcmZvcm1UYXNrKCkge1xuICAgIGRlYnVnKFRBRywgJ1BlcmZvcm0gdGFzayBjbGljaycpO1xuICB9XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC10YXNrLW1hbmFnZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFzay1tYW5hZ2VyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGFzay1tYW5hZ2VyLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFRhc2tNYW5hZ2VyQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgdGFza0NvbnRhaW5lcj86IFRhc2tNYW5hZ2VyLlRhc2tDb250YWluZXI8dW5rbm93bj47XG5cbiAgQElucHV0KCkgc2V0IHRhc2soXG4gICAgdGFza0NvbnRhaW5lck9yU3RyaW5nOiBUYXNrTWFuYWdlci5UYXNrQ29udGFpbmVyPHVua25vd24+IHwgc3RyaW5nXG4gICkge1xuICAgIGxldCB0YXNrQ29udGFpbmVyOiBUYXNrTWFuYWdlci5UYXNrQ29udGFpbmVyPHVua25vd24+IHwgdW5kZWZpbmVkO1xuICAgIHRhc2tDb250YWluZXIgPSB0YXNrQ29udGFpbmVyT3JTdHJpbmcgYXMgVGFza01hbmFnZXIuVGFza0NvbnRhaW5lcjx1bmtub3duPjtcbiAgICBkZWJ1ZyhUQUcsICdzZXQgdGFzayAnLCB0YXNrQ29udGFpbmVyPy50YXNrPy5pZCk7XG4gICAgdGhpcy50YXNrQ29udGFpbmVyID0gdGFza0NvbnRhaW5lcjtcbiAgfVxuXG4gIGdldCB0YXNrSWQoKSB7XG4gICAgcmV0dXJuIHRoaXMudGFza0NvbnRhaW5lcj8udGFzaz8uaWQ7XG4gIH1cblxuICBAQ29udGVudENoaWxkKFRhc2tNYW5hZ2VyQWN0aW9uQ2FuY2VsRGlyZWN0aXZlLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICBjYW5jZWxEaXJlY3RpdmU/OiBUYXNrTWFuYWdlckFjdGlvbkNhbmNlbERpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChUYXNrTWFuYWdlckFjdGlvbkV4ZWNEaXJlY3RpdmUsIHsgc3RhdGljOiB0cnVlIH0pXG4gIGV4ZWNEaXJlY3RpdmU/OiBUYXNrTWFuYWdlckFjdGlvbkNhbmNlbERpcmVjdGl2ZTtcblxuICAvLyBAQ29udGVudENoaWxkKFRhc2tNYW5hZ2VyQWN0aW9uQ29tcG9uZW50LCB7fSkgYWN0aW9uQ29tcG9uZW50OiBUYXNrTWFuYWdlckFjdGlvbkNvbXBvbmVudDtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgdGFza01hbmFnZXI6IFRhc2tNYW5hZ2VyU2VydmljZSkge31cblxuICBnZXQgbG9hZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBnZXQgdGFza1N0YXRlKCkge1xuICAgIHJldHVybiB0aGlzLnRhc2tDb250YWluZXI/Lm1ldGE/LnN0YXRlO1xuICB9XG5cbiAgZ2V0IGFjdGlvblRlbXBsYXRlQ29udGV4dCgpIHtcbiAgICBjb25zdCBjb250ID0gdGhpcy5fY3JlYXRlQ29udGV4dCgpO1xuICAgIGlmICgnZXhlY1Rhc2snIGluIGNvbnQpIHtcbiAgICAgIGNvbnRbJ2V4ZWNUYXNrJ10gPSAoLi4uY29udGV4dDogYW55W10pID0+IHtcbiAgICAgICAgdGhpcy5leGVjVGFzayhjb250ZXh0KTtcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7ICRpbXBsaWNpdDogY29udCB9O1xuICB9XG5cbiAgZ2V0IGRlbGF5ZWRUZW1wbGF0ZUNvbnRleHQoKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NyZWF0ZUNvbnRleHQoKTtcbiAgICBpZiAoJ2V4ZWNUYXNrJyBpbiB0aGlzKSB7XG4gICAgICBjb250ZXh0WydleGVjVGFzayddID0gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy50YXNrSWQgJiYgdGhpcy50YXNrTWFuYWdlci5oYXNUYXNrKHRoaXMudGFza0lkKSkge1xuICAgICAgICAgIHRoaXMudGFza01hbmFnZXIuY2FuY2VsKHRoaXMudGFza0lkKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgJGltcGxpY2l0OiBjb250ZXh0IH07XG4gIH1cblxuICBwcml2YXRlIF9jcmVhdGVDb250ZXh0KCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2FuY2VsRGlyZWN0aXZlKSB7XG4gICAgICB0aGlzLmNhbmNlbERpcmVjdGl2ZS5vbkNsaWNrLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2FuY2VsVGFzaygpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKFRBRywgJ2NhbmNlbCBidXR0b24gaXMgbm90IHNldCB5ZXQnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZXhlY0RpcmVjdGl2ZSkge1xuICAgICAgdGhpcy5leGVjRGlyZWN0aXZlLm9uQ2xpY2suc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5leGVjVGFzaygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgZGVidWcoVEFHLCAnVGFzaycsIHRoaXMudGFza0lkLCAnY29tcG9uZW50IG5nT25EZXN0cm95Jyk7XG4gICAgdGhpcy5jYW5jZWxUYXNrKCk7XG4gIH1cblxuICBjYW5jZWxUYXNrKCkge1xuICAgIGRlYnVnKFRBRywgJ2NhbmNlbFRhc2sgY2xpY2tlZCEnKTtcbiAgICBpZiAoIXRoaXMudGFza0lkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLnRhc2tNYW5hZ2VyLmhhc1Rhc2sodGhpcy50YXNrSWQpKSB7XG4gICAgICB0aGlzLnRhc2tNYW5hZ2VyLmNhbmNlbCh0aGlzLnRhc2tJZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKFRBRywgJ2Nhbm5vdCBjYW5jZWwgdGFzayAnLCB0aGlzLnRhc2tJZCwgJ2l0IGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgfVxuICB9XG5cbiAgZXhwbGFpbkRlbGF5UmVhc29uKCkge1xuICAgIGNvbnN0IGVyciA9IHRoaXMudGFza0NvbnRhaW5lcj8ubWV0YS5lcnJvcjtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBjb25zdCBjb2RlRXJyb3IgPSBlcnIgYXMgQ29kZUVycm9yO1xuICAgICAgc3dpdGNoIChjb2RlRXJyb3IuY29kZSkge1xuICAgICAgICBjYXNlIFRhcEVycm9yLkNvZGUuUmVzcG9uc2VTdGF0dXNFcnJvcjpcbiAgICAgICAgICBzd2l0Y2ggKChlcnIgYXMgVGFwUmVzcG9uc2VTdGF0dXNFcnJvcikucmVzcG9uc2Uuc3RhdHVzKSB7XG4gICAgICAgICAgICBjYXNlIFJlc3VsdENvZGUuVU5BVVRIT1JJWkVEOlxuICAgICAgICAgICAgICByZXR1cm4gJ1dhaXRpbmcgZm9yIHVzZXIgbG9naW4nO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBUYXBFcnJvci5Db2RlLkV4ZWN1dGVSZXF1ZXN0RXJyb3I6XG4gICAgICAgICAgY29uc3QgY2F1c2UgPSAoZXJyIGFzIFRhcEVycm9yKS5jYXVzZSBhcyBDb2RlRXJyb3I7XG4gICAgICAgICAgaWYgKGNhdXNlKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNhdXNlLmNvZGUpIHtcbiAgICAgICAgICAgICAgY2FzZSBUYXBDbGllbnRFcnJvci5Db2RlLk5vdENvbm5lY3RlZEVycm9yOlxuICAgICAgICAgICAgICBjYXNlICdOZmNUYWdMb3N0RXJyb3InOlxuICAgICAgICAgICAgICBjYXNlICdOZmNOb3RDb25uZWN0ZWRFcnJvcic6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdXYWl0aW5nIGZvciBUYXAgcmVjb25uZWN0aW9uJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gJ1Vua25vd24gcmVhc29uJztcbiAgICB9XG4gIH1cblxuICBleGVjVGFzayhjb250ZXh0PzogYW55KSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy50YXNrQ29udGFpbmVyO1xuICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRlYnVnKFRBRywgJ2V4ZWNUYXNrICcsIGNvbnRhaW5lci50YXNrLmlkKTtcbiAgICB0aGlzLnRhc2tNYW5hZ2VyLmFkZFRhc2tDb250YWluZXIoY29udGFpbmVyKTtcbiAgICAvLyB0aGlzLmV4ZWNEaXJlY3RpdmUuZGlzYWJsZSh0cnVlKTtcbiAgICB0aGlzLnRhc2tNYW5hZ2VyLmV4ZWMoY29udGFpbmVyLnRhc2suaWQsIGNvbnRleHQpLnN1YnNjcmliZSh7XG4gICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICBkZWJ1ZyhgVGFzayAke2NvbnRhaW5lci50YXNrLmlkfSBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgY29uc29sZS53YXJuKGVycik7XG4gICAgICAgIC8vIHRoaXMuZXhlY0RpcmVjdGl2ZS5kaXNhYmxlKGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICBkZWJ1ZyhgVGFzayAke2NvbnRhaW5lci50YXNrLmlkfSBDT01QTEVURURgKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInRhc2tTdGF0ZVwiPlxuICA8bmctY29udGVudFxuICAgIHNlbGVjdD1cImFwcC10YXNrLW1hbmFnZXItZGVsYXllZFwiXG4gICAgKm5nU3dpdGNoQ2FzZT1cIidkZWxheWVkJ1wiXG4gID48L25nLWNvbnRlbnQ+XG4gIDxuZy1jb250ZW50XG4gICAgc2VsZWN0PVwiYXBwLXRhc2stbWFuYWdlci1ydW5uaW5nXCJcbiAgICAqbmdTd2l0Y2hDYXNlPVwiJ3J1bm5pbmcnXCJcbiAgPjwvbmctY29udGVudD5cbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiYXBwLXRhc2stbWFuYWdlci1hY3Rpb25cIiAqbmdTd2l0Y2hEZWZhdWx0PjwvbmctY29udGVudD5cbjwvbmctY29udGFpbmVyPlxuIl19