UNPKG

@nakedobjects/gemini

Version:

Single Page Application client for a Naked Objects application.

136 lines 24.6 kB
import { Component, HostListener, Input } from '@angular/core'; import { copy } from '@nakedobjects/view-models'; import { safeUnsubscribe } from '../helpers-components'; import * as i0 from "@angular/core"; import * as i1 from "@nakedobjects/view-models"; import * as i2 from "@angular/router"; import * as i3 from "@angular/common"; import * as i4 from "@angular/cdk/drag-drop"; import * as i5 from "../click.directive"; import * as i6 from "../attachment-property/attachment-property.component"; export class ViewPropertyComponent { dragAndDrop; router; ddSub; constructor(dragAndDrop, router) { this.dragAndDrop = dragAndDrop; this.router = router; } dropZones = []; // template inputs property; propertyName; // template listeners onEnter(event) { this.copy(event); } onEnter1(event) { this.copy(event); } // template API get title() { return this.property?.title ?? this.propertyName; } get propertyType() { return this.property?.type ?? 'scalar'; } get propertyRefType() { return this.property?.refType; } get propertyReturnType() { return this.property?.returnType ?? ''; } get formattedValue() { return this.property?.formattedValue ?? ''; } get value() { return this.property?.value; } get format() { return this.property?.format; } get isBlob() { return this.property?.format === 'blob'; } get isMultiline() { return !(this.property?.multipleLines === 1); } get multilineHeight() { return `${(this.property?.multipleLines ?? 1) * 20}px`; } get color() { return this.property?.color; } get attachment() { return this.property?.attachment ?? null; } get isEditByAction() { return this.property?.isEditByAction ?? false; } get editActionTooltip() { return this.property?.editActionTooltip; } get isLink() { return this.property?.isLink; } get linkValue() { const lp = this.property?.linkProperties(); return lp?.[1] || this.value; } doLinkClick(newPane) { const href = this.value; if (newPane || this.property?.linkProperties()?.[0]) { window.open(href, '_blank'); } else if (href.startsWith('http')) { window.location.href = href; } else { const tree = this.router.createUrlTree([href]); this.router.navigateByUrl(tree); } } doClick = (right) => this.property?.doClick(right); doEdit = () => { if (!this.property?.isEditActionDisabled) { this.property?.doEditByAction(); } }; copy(event) { const prop = this.property; if (prop) { copy(event, prop, this.dragAndDrop); } } setDropZones(ids) { setTimeout(() => this.dropZones = ids); } get editActionClass() { return ({ tempdisabled: this.property?.isEditActionDisabled, }); } ngOnInit() { this.ddSub = this.dragAndDrop.dropZoneIds$.subscribe(ids => this.setDropZones(ids || [])); } ngOnDestroy() { safeUnsubscribe(this.ddSub); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: ViewPropertyComponent, deps: [{ token: i1.DragAndDropService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: ViewPropertyComponent, selector: "nof-view-property", inputs: { property: "property", propertyName: "propertyName" }, host: { listeners: { "keydown": "onEnter($event)", "keypress": "onEnter1($event)" } }, ngImport: i0, template: "<div class=\"name\">{{title}}:</div>\n\n<ng-container *ngIf=\"propertyType === 'ref'\">\n <ng-container [ngSwitch]=\"propertyRefType\" >\n <div *ngSwitchCase=\"null\"></div>\n <div *ngSwitchCase=\"'notNavigable'\">\n <div class=\"value\">{{formattedValue}}</div>\n </div>\n <div cdkDropList [cdkDropListConnectedTo]=\"dropZones\">\n <div *ngSwitchDefault class=\"reference\" [ngClass]=\"color\" nofClick (leftClick)=\"doClick()\"\n (rightClick)=\"doClick(true)\" cdkDrag [cdkDragData]=\"property\" tabindex=\"0\">\n {{formattedValue}}\n </div>\n </div>\n </ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"propertyType === 'scalar'\">\n <ng-container [ngSwitch]=\"propertyReturnType\">\n <ng-container *ngSwitchCase=\"'string'\">\n\n <nof-attachment-property *ngIf=\"isBlob\" [attachment]=\"attachment\"></nof-attachment-property>\n <ng-container *ngIf=\"!isBlob\">\n <div *ngIf=\"isLink\" class=\"reference url-link\" nofClick (leftClick)=\"doLinkClick()\" (rightClick)=\"doLinkClick(true)\">{{linkValue}}</div> \n <div *ngIf=\"!isMultiline && !isLink\" class=\"value\">\n {{formattedValue}}\n </div>\n <div *ngIf=\"isMultiline && !isLink\" class=\"value multiline\" [ngStyle]=\"{height : multilineHeight}\">\n <pre>{{formattedValue}}</pre>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input type=\"checkbox\" [checked]=\"value\" disabled=\"disabled\" />\n </ng-container>\n\n <ng-container *ngSwitchDefault>\n <div class=\"value\">{{formattedValue}}</div>\n </ng-container>\n </ng-container>\n</ng-container>\n<div *ngIf=\"isEditByAction\" class=\"icon edit\" [ngClass]=\"editActionClass\" [title]=\"editActionTooltip\" (click)=\"doEdit()\"></div>", styles: [":host{overflow:hidden;display:block}:host:not(:last-child){margin-bottom:var(--space-3)}.name{display:block;float:left;width:var(--field-name-width);padding-right:var(--space-3);font-weight:var(--font-weight-2)er}.reference,.value{display:block;float:left;width:var(--field-value-width);padding-left:var(--space-3);padding-right:var(--space-3);margin:var(--space-1)}.reference:hover{outline-style:solid;outline-width:1px;outline-color:var(--default-outline-color)}.reference{cursor:pointer}.multiline{overflow:auto}.icon{display:block;cursor:pointer;float:right;width:20px;height:var(--field-value-height);padding-left:var(--space-3);padding-top:var(--space-3);margin-right:var(--space-3)}.icon.edit{background:var(--pencil-icon);background-size:cover;margin-left:2px}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.ClickDirective, selector: "[nofClick]", outputs: ["leftClick", "rightClick"] }, { kind: "component", type: i6.AttachmentPropertyComponent, selector: "nof-attachment-property", inputs: ["attachment"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: ViewPropertyComponent, decorators: [{ type: Component, args: [{ selector: 'nof-view-property', template: "<div class=\"name\">{{title}}:</div>\n\n<ng-container *ngIf=\"propertyType === 'ref'\">\n <ng-container [ngSwitch]=\"propertyRefType\" >\n <div *ngSwitchCase=\"null\"></div>\n <div *ngSwitchCase=\"'notNavigable'\">\n <div class=\"value\">{{formattedValue}}</div>\n </div>\n <div cdkDropList [cdkDropListConnectedTo]=\"dropZones\">\n <div *ngSwitchDefault class=\"reference\" [ngClass]=\"color\" nofClick (leftClick)=\"doClick()\"\n (rightClick)=\"doClick(true)\" cdkDrag [cdkDragData]=\"property\" tabindex=\"0\">\n {{formattedValue}}\n </div>\n </div>\n </ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"propertyType === 'scalar'\">\n <ng-container [ngSwitch]=\"propertyReturnType\">\n <ng-container *ngSwitchCase=\"'string'\">\n\n <nof-attachment-property *ngIf=\"isBlob\" [attachment]=\"attachment\"></nof-attachment-property>\n <ng-container *ngIf=\"!isBlob\">\n <div *ngIf=\"isLink\" class=\"reference url-link\" nofClick (leftClick)=\"doLinkClick()\" (rightClick)=\"doLinkClick(true)\">{{linkValue}}</div> \n <div *ngIf=\"!isMultiline && !isLink\" class=\"value\">\n {{formattedValue}}\n </div>\n <div *ngIf=\"isMultiline && !isLink\" class=\"value multiline\" [ngStyle]=\"{height : multilineHeight}\">\n <pre>{{formattedValue}}</pre>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'boolean'\">\n <input type=\"checkbox\" [checked]=\"value\" disabled=\"disabled\" />\n </ng-container>\n\n <ng-container *ngSwitchDefault>\n <div class=\"value\">{{formattedValue}}</div>\n </ng-container>\n </ng-container>\n</ng-container>\n<div *ngIf=\"isEditByAction\" class=\"icon edit\" [ngClass]=\"editActionClass\" [title]=\"editActionTooltip\" (click)=\"doEdit()\"></div>", styles: [":host{overflow:hidden;display:block}:host:not(:last-child){margin-bottom:var(--space-3)}.name{display:block;float:left;width:var(--field-name-width);padding-right:var(--space-3);font-weight:var(--font-weight-2)er}.reference,.value{display:block;float:left;width:var(--field-value-width);padding-left:var(--space-3);padding-right:var(--space-3);margin:var(--space-1)}.reference:hover{outline-style:solid;outline-width:1px;outline-color:var(--default-outline-color)}.reference{cursor:pointer}.multiline{overflow:auto}.icon{display:block;cursor:pointer;float:right;width:20px;height:var(--field-value-height);padding-left:var(--space-3);padding-top:var(--space-3);margin-right:var(--space-3)}.icon.edit{background:var(--pencil-icon);background-size:cover;margin-left:2px}\n"] }] }], ctorParameters: () => [{ type: i1.DragAndDropService }, { type: i2.Router }], propDecorators: { property: [{ type: Input }], propertyName: [{ type: Input }], onEnter: [{ type: HostListener, args: ['keydown', ['$event']] }], onEnter1: [{ type: HostListener, args: ['keypress', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlldy1wcm9wZXJ0eS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9nZW1pbmkvc3JjL3ZpZXctcHJvcGVydHkvdmlldy1wcm9wZXJ0eS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9nZW1pbmkvc3JjL3ZpZXctcHJvcGVydHkvdmlldy1wcm9wZXJ0eS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBRWxGLE9BQU8sRUFBRSxJQUFJLEVBQThELE1BQU0sMkJBQTJCLENBQUM7QUFFN0csT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7OztBQU94RCxNQUFNLE9BQU8scUJBQXFCO0lBS1Q7SUFDQTtJQUpiLEtBQUssQ0FBaUI7SUFFOUIsWUFDcUIsV0FBK0IsRUFDL0IsTUFBYztRQURkLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUMvQixXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQy9CLENBQUM7SUFFTCxTQUFTLEdBQWEsRUFBRSxDQUFDO0lBRXpCLGtCQUFrQjtJQUdsQixRQUFRLENBQXFCO0lBRzdCLFlBQVksQ0FBVTtJQUV0QixxQkFBcUI7SUFHckIsT0FBTyxDQUFDLEtBQW9CO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckIsQ0FBQztJQUdELFFBQVEsQ0FBQyxLQUFvQjtRQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxlQUFlO0lBRWYsSUFBSSxLQUFLO1FBQ0wsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQ3JELENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDWixPQUFPLElBQUksQ0FBQyxRQUFRLEVB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dCB7IENvbXBvbmVudCwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25Jbml0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBjb3B5LCBEcmFnQW5kRHJvcFNlcnZpY2UsIEF0dGFjaG1lbnRWaWV3TW9kZWwsIFByb3BlcnR5Vmlld01vZGVsIH0gZnJvbSAnQG5ha2Vkb2JqZWN0cy92aWV3LW1vZGVscyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb25MaWtlIGFzIElTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHNhZmVVbnN1YnNjcmliZSB9IGZyb20gJy4uL2hlbHBlcnMtY29tcG9uZW50cyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbm9mLXZpZXctcHJvcGVydHknLFxuICAgIHRlbXBsYXRlVXJsOiAndmlldy1wcm9wZXJ0eS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJ3ZpZXctcHJvcGVydHkuY29tcG9uZW50LmNzcyddXG59KVxuZXhwb3J0IGNsYXNzIFZpZXdQcm9wZXJ0eUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICAgIHByaXZhdGUgZGRTdWI/OiBJU3Vic2NyaXB0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZHJhZ0FuZERyb3A6IERyYWdBbmREcm9wU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXI6IFJvdXRlcixcbiAgICApIHsgfVxuXG4gICAgZHJvcFpvbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gdGVtcGxhdGUgaW5wdXRzXG5cbiAgICBASW5wdXQoKVxuICAgIHByb3BlcnR5PzogUHJvcGVydHlWaWV3TW9kZWw7XG5cbiAgICBASW5wdXQoKVxuICAgIHByb3BlcnR5TmFtZT86IHN0cmluZztcblxuICAgIC8vIHRlbXBsYXRlIGxpc3RlbmVyc1xuXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50J10pXG4gICAgb25FbnRlcihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLmNvcHkoZXZlbnQpO1xuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ2tleXByZXNzJywgWyckZXZlbnQnXSlcbiAgICBvbkVudGVyMShldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLmNvcHkoZXZlbnQpO1xuICAgIH1cblxuICAgIC8vIHRlbXBsYXRlIEFQSVxuXG4gICAgZ2V0IHRpdGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eT8udGl0bGUgPz8gdGhpcy5wcm9wZXJ0eU5hbWU7XG4gICAgfVxuXG4gICAgZ2V0IHByb3BlcnR5VHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHk/LnR5cGUgPz8gJ3NjYWxhcic7XG4gICAgfVxuXG4gICAgZ2V0IHByb3BlcnR5UmVmVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHk/LnJlZlR5cGU7XG4gICAgfVxuXG4gICAgZ2V0IHByb3BlcnR5UmV0dXJuVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHk/LnJldHVyblR5cGUgPz8gJyc7XG4gICAgfVxuXG4gICAgZ2V0IGZvcm1hdHRlZFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eT8uZm9ybWF0dGVkVmFsdWUgPz8gJyc7XG4gICAgfVxuXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eT8udmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IGZvcm1hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHk/LmZvcm1hdDtcbiAgICB9XG5cbiAgICBnZXQgaXNCbG9iKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eT8uZm9ybWF0ID09PSAnYmxvYic7XG4gICAgfVxuXG4gICAgZ2V0IGlzTXVsdGlsaW5lKCkge1xuICAgICAgICByZXR1cm4gISh0aGlzLnByb3BlcnR5Py5tdWx0aXBsZUxpbmVzID09PSAxKTtcbiAgICB9XG5cbiAgICBnZXQgbXVsdGlsaW5lSGVpZ2h0KCkge1xuICAgICAgICByZXR1cm4gYCR7KHRoaXMucHJvcGVydHk/Lm11bHRpcGxlTGluZXMgPz8gMSkgKiAyMH1weGA7XG4gICAgfVxuXG4gICAgZ2V0IGNvbG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eT8uY29sb3I7XG4gICAgfVxuXG4gICAgZ2V0IGF0dGFjaG1lbnQoKTogQXR0YWNobWVudFZpZXdNb2RlbCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eT8uYXR0YWNobWVudCA/PyBudWxsO1xuICAgIH1cblxuICAgIGdldCBpc0VkaXRCeUFjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHk/LmlzRWRpdEJ5QWN0aW9uID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGdldCBlZGl0QWN0aW9uVG9vbHRpcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcGVydHk/LmVkaXRBY3Rpb25Ub29sdGlwO1xuICAgIH1cblxuICAgIGdldCBpc0xpbmsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BlcnR5Py5pc0xpbms7XG4gICAgfVxuXG4gICAgZ2V0IGxpbmtWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgbHAgPSB0aGlzLnByb3BlcnR5Py5saW5rUHJvcGVydGllcygpO1xuICAgICAgICByZXR1cm4gbHA/LlsxXSB8fCB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIGRvTGlua0NsaWNrKG5ld1BhbmU/OiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IGhyZWYgPSB0aGlzLnZhbHVlIGFzIHN0cmluZztcbiAgICAgICAgaWYgKG5ld1BhbmUgfHwgdGhpcy5wcm9wZXJ0eT8ubGlua1Byb3BlcnRpZXMoKT8uWzBdKSB7XG4gICAgICAgICAgICB3aW5kb3cub3BlbihocmVmLCAnX2JsYW5rJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaHJlZi5zdGFydHNXaXRoKCdodHRwJykpIHtcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gaHJlZjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHsgIFxuICAgICAgICAgICAgY29uc3QgdHJlZSA9IHRoaXMucm91dGVyLmNyZWF0ZVVybFRyZWUoW2hyZWZdKTtcbiAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwodHJlZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkb0NsaWNrID0gKHJpZ2h0PzogYm9vbGVhbikgPT4gdGhpcy5wcm9wZXJ0eT8uZG9DbGljayhyaWdodCk7XG5cbiAgICBkb0VkaXQgPSAoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wZXJ0eT8uaXNFZGl0QWN0aW9uRGlzYWJsZWQpIHtcbiAgICAgICAgICB0aGlzLnByb3BlcnR5Py5kb0VkaXRCeUFjdGlvbigpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGNvcHkoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgY29uc3QgcHJvcCA9IHRoaXMucHJvcGVydHk7XG4gICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICBjb3B5KGV2ZW50LCBwcm9wLCB0aGlzLmRyYWdBbmREcm9wKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldERyb3Bab25lcyhpZHM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5kcm9wWm9uZXMgPSBpZHMpO1xuICAgIH1cblxuICAgIGdldCBlZGl0QWN0aW9uQ2xhc3MoKSB7XG4gICAgICAgIHJldHVybiAoe1xuICAgICAgICAgICAgdGVtcGRpc2FibGVkOiB0aGlzLnByb3BlcnR5Py5pc0VkaXRBY3Rpb25EaXNhYmxlZCxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGRTdWIgPSB0aGlzLmRyYWdBbmREcm9wLmRyb3Bab25lSWRzJC5zdWJzY3JpYmUoaWRzID0+IHRoaXMuc2V0RHJvcFpvbmVzKGlkcyB8fCBbXSkpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBzYWZlVW5zdWJzY3JpYmUodGhpcy5kZFN1Yik7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm5hbWVcIj57e3RpdGxlfX06PC9kaXY+XG5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJwcm9wZXJ0eVR5cGUgPT09ICdyZWYnXCI+XG4gICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwicHJvcGVydHlSZWZUeXBlXCIgPlxuICAgICAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJudWxsXCI+PC9kaXY+XG4gICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIidub3ROYXZpZ2FibGUnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmFsdWVcIj57e2Zvcm1hdHRlZFZhbHVlfX08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2RrRHJvcExpc3QgW2Nka0Ryb3BMaXN0Q29ubmVjdGVkVG9dPVwiZHJvcFpvbmVzXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ1N3aXRjaERlZmF1bHQgY2xhc3M9XCJyZWZlcmVuY2VcIiBbbmdDbGFzc109XCJjb2xvclwiIG5vZkNsaWNrIChsZWZ0Q2xpY2spPVwiZG9DbGljaygpXCJcbiAgICAgICAgICAgICAgICAocmlnaHRDbGljayk9XCJkb0NsaWNrKHRydWUpXCIgY2RrRHJhZyBbY2RrRHJhZ0RhdGFdPVwicHJvcGVydHlcIiB0YWJpbmRleD1cIjBcIj5cbiAgICAgICAgICAgICAgICB7e2Zvcm1hdHRlZFZhbHVlfX1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbjwvbmctY29udGFpbmVyPlxuXG48bmctY29udGFpbmVyICpuZ0lmPVwicHJvcGVydHlUeXBlID09PSAnc2NhbGFyJ1wiPlxuICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInByb3BlcnR5UmV0dXJuVHlwZVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc3RyaW5nJ1wiPlxuXG4gICAgICAgICAgICA8bm9mLWF0dGFjaG1lbnQtcHJvcGVydHkgKm5nSWY9XCJpc0Jsb2JcIiBbYXR0YWNobWVudF09XCJhdHRhY2htZW50XCI+PC9ub2YtYXR0YWNobWVudC1wcm9wZXJ0eT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNCbG9iXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzTGlua1wiIGNsYXNzPVwicmVmZXJlbmNlIHVybC1saW5rXCIgbm9mQ2xpY2sgKGxlZnRDbGljayk9XCJkb0xpbmtDbGljaygpXCIgKHJpZ2h0Q2xpY2spPVwiZG9MaW5rQ2xpY2sodHJ1ZSlcIj57e2xpbmtWYWx1ZX19PC9kaXY+IFxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhaXNNdWx0aWxpbmUgJiYgIWlzTGlua1wiIGNsYXNzPVwidmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAge3tmb3JtYXR0ZWRWYWx1ZX19XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzTXVsdGlsaW5lICYmICFpc0xpbmtcIiBjbGFzcz1cInZhbHVlIG11bHRpbGluZVwiIFtuZ1N0eWxlXT1cIntoZWlnaHQgOiBtdWx0aWxpbmVIZWlnaHR9XCI+XG4gICAgICAgICAgICAgICAgICAgIDxwcmU+e3tmb3JtYXR0ZWRWYWx1ZX19PC9wcmU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2Jvb2xlYW4nXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwidmFsdWVcIiBkaXNhYmxlZD1cImRpc2FibGVkXCIgLz5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZhbHVlXCI+e3tmb3JtYXR0ZWRWYWx1ZX19PC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuPC9uZy1jb250YWluZXI+XG48ZGl2ICpuZ0lmPVwiaXNFZGl0QnlBY3Rpb25cIiBjbGFzcz1cImljb24gZWRpdFwiIFtuZ0NsYXNzXT1cImVkaXRBY3Rpb25DbGFzc1wiICBbdGl0bGVdPVwiZWRpdEFjdGlvblRvb2x0aXBcIiAoY2xpY2spPVwiZG9FZGl0KClcIj48L2Rpdj4iXX0=