truly-ui
Version:
Web Components for Desktop Applications.
104 lines (102 loc) • 28.9 kB
JavaScript
/*
MIT License
Copyright (c) 2018 Temainfo Software
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import { Component, EventEmitter, Input, Output } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "../lightbox/services/lightbox.service";
import * as i2 from "./thumbnail.service";
import * as i3 from "../dialog/dialog.service";
import * as i4 from "@angular/common";
import * as i5 from "../icons/icons";
export class TlThumbnail {
constructor(lightboxService, thumbnailService, dialogService) {
this.lightboxService = lightboxService;
this.thumbnailService = thumbnailService;
this.dialogService = dialogService;
this.data = [];
this.bordered = true;
this.shape = 'square';
this.size = { width: '80px', height: '80px' };
this.showDeleteButton = false;
this.confirmationDeleteMessage = 'Do you want to delete the Thumbnail?';
this.showConfirmationOnDelete = false;
this.clickThumbnail = new EventEmitter();
this.clickDeleteThumbail = new EventEmitter();
}
ngOnInit() { }
ngOnChanges(changes) {
if (changes['data'] && changes['data'].currentValue) {
if (changes['data'].currentValue.length > 0) {
this.data = changes['data'].currentValue.map((file) => {
file.type = !file.type ? this.thumbnailService.getMimeType(file.file) : file.type;
return file;
});
}
}
}
get isCircle() {
return this.shape === 'circle';
}
onViewImage(image) {
this.lightboxService.create(this.data, image);
}
onDeleteThumb(image) {
if (this.showConfirmationOnDelete) {
return this.dialogService.confirmation(this.confirmationDeleteMessage, ({
isYes: () => this.clickDeleteThumbail.emit(image),
}), {}, this.modalDeleteOptions);
}
this.clickDeleteThumbail.emit(image);
}
}
/** @nocollapse */ TlThumbnail.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlThumbnail, deps: [{ token: i1.LightboxService }, { token: i2.ThumbnailService }, { token: i3.DialogService }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ TlThumbnail.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TlThumbnail, selector: "tl-thumbnail", inputs: { image: "image", mimeType: "mimeType", data: "data", bordered: "bordered", shape: "shape", size: "size", showDeleteButton: "showDeleteButton", confirmationDeleteMessage: "confirmationDeleteMessage", showConfirmationOnDelete: "showConfirmationOnDelete", modalDeleteOptions: "modalDeleteOptions", overlayTemplate: "overlayTemplate", emptyTemplate: "emptyTemplate" }, outputs: { clickThumbnail: "clickThumbnail", clickDeleteThumbail: "clickDeleteThumbail" }, usesOnChanges: true, ngImport: i0, template: "\n<div class=\"thumbnail-container\">\n <ng-container *ngIf=\"data.length > 0; else thumbTemplate\">\n <ng-container *ngFor=\"let item of data\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item }\"></ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #thumbTemplate let-item>\n <div class=\"thumbnail\" (click)=\"clickThumbnail.emit($event)\"\n [style.width]=\"size.width\"\n [style.height]=\"size.height\"\n [class.circle-shape]=\"isCircle\"\n [class.borderLess]=\"!bordered\">\n <ng-container *ngIf=\"!item && !image; else imageTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate\"></ng-container>\n </ng-container>\n <ng-template #imageTemplate>\n <div *ngIf=\"item.type === 'image/png' || item.type === 'image/jpeg' || item.type === 'image/bmp' || item.type === 'image/jpg' || item.type === 'image' ||\n mimeType === 'image/png' || mimeType === 'image/jpeg' || mimeType === 'image/bmp' || mimeType === 'image/jpg' || mimeType === 'image'\"\n class=\"thumbnail-image-wrapper\" [class.circle-shape]=\"isCircle\">\n <img class=\"thumbnail-image\" [class.circle-shape]=\"isCircle\" alt=\"image\" [src]=\"item.file || image\">\n <div class=\"thumbnail-controls\" *ngIf=\"!overlayTemplate\">\n <div class=\"view-button\" [style.width]=\"size.width\" [style.height]=\"size.height\" (click)=\"onViewImage( image )\">\n <tl-icon [lib]=\"'dx'\">find</tl-icon>\n </div>\n <div class=\"trash-button\" (click)=\"onDeleteThumb(item)\">\n <tl-icon *ngIf=\"showDeleteButton\" [lib]=\"'dx'\">trash</tl-icon>\n </div>\n </div>\n <div class=\"thumbnail-controls\" *ngIf=\"overlayTemplate\">\n <ng-container *ngTemplateOutlet=\"overlayTemplate; context: { $implicit: item || image }\"></ng-container>\n </div>\n </div>\n\n <div *ngIf=\"item.type === 'application/pdf' || mimeType === 'application/pdf'\" class=\"thumbnail-image-wrapper\" [class.circle-shape]=\"isCircle\">\n <tl-icon style=\"margin-right: 5px\" [lib]=\"'fa'\" [style]=\"'fas'\" [color]=\"'#ec7e7e'\" [size]=\"'40px'\">file-pdf</tl-icon>\n <div class=\"thumbnail-controls\" *ngIf=\"!overlayTemplate\">\n <div class=\"view-button\" [style.width]=\"size.width\" [style.height]=\"size.height\" (click)=\"onViewImage( image )\">\n <tl-icon [lib]=\"'dx'\">find</tl-icon>\n </div>\n <div class=\"trash-button\" (click)=\"onDeleteThumb(item)\">\n <tl-icon *ngIf=\"showDeleteButton\" [lib]=\"'dx'\">trash</tl-icon>\n </div>\n </div>\n <div class=\"thumbnail-controls\" *ngIf=\"overlayTemplate\">\n <ng-container *ngTemplateOutlet=\"overlayTemplate; context: { $implicit: item || image }\"></ng-container>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n", styles: [".thumbnail-container{display:flex}.thumbnail-container>.thumbnail{display:flex;align-items:center;justify-content:center;flex-flow:column;position:relative;width:100px;height:80px;background-color:#fafafa;border:1px dashed #d9d9d9;transition:border-color .3s ease;cursor:pointer;margin:0 5px;padding:2px;box-sizing:border-box}.thumbnail-container>.thumbnail>.icon{color:#e6e6e6;cursor:pointer;font-size:22px}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper{height:100%;width:100%;border-radius:5px;overflow:hidden;display:flex;align-items:center;justify-content:center}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper.circle-shape:before{border-radius:50%}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper:hover .thumbnail-controls{opacity:1}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper:before{position:absolute;z-index:1;width:100%;height:100%;background-color:#00000080;opacity:0;transition:all .3s;content:\" \";top:0;left:0}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-image{position:static;display:block;width:100%;height:100%;object-fit:cover}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-image.circle-shape{border-radius:50%}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls{position:absolute;width:100%;top:0;height:100%;color:#fff;font-size:22px;z-index:1000;left:0;opacity:0;cursor:pointer;display:flex;align-items:center;justify-content:center}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.view-button{margin-top:10px;display:flex;align-content:center;align-items:center;justify-content:center}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.view-button>tl-icon{margin-bottom:10px}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.trash-button{cursor:pointer;position:absolute;top:0;right:0;height:15px;display:flex;justify-content:center;align-items:center;background-color:#ec7e7e}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.trash-button>tl-icon{font-size:10px}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls .icon{cursor:pointer}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls .icon:last-child{padding-left:10px}.thumbnail-container>.thumbnail:hover .thumbnail-image-wrapper:before{opacity:1}.thumbnail-container>.thumbnail.borderLess{border:0}.thumbnail-container>.thumbnail.circle-shape{border-radius:50%}.thumbnail-container>.thumbnail.marginLess{margin-left:0!important}.thumbnail-container>.thumbnail:first-child{margin-left:8px}.thumbnail-container>.thumbnail:hover{border-color:#6c9}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i5.TlIcons, selector: "tl-icon", inputs: ["icon", "lib", "style", "size", "animation", "color", "align"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlThumbnail, decorators: [{
type: Component,
args: [{ selector: 'tl-thumbnail', template: "\n<div class=\"thumbnail-container\">\n <ng-container *ngIf=\"data.length > 0; else thumbTemplate\">\n <ng-container *ngFor=\"let item of data\">\n <ng-container *ngTemplateOutlet=\"thumbTemplate; context: { $implicit: item }\"></ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #thumbTemplate let-item>\n <div class=\"thumbnail\" (click)=\"clickThumbnail.emit($event)\"\n [style.width]=\"size.width\"\n [style.height]=\"size.height\"\n [class.circle-shape]=\"isCircle\"\n [class.borderLess]=\"!bordered\">\n <ng-container *ngIf=\"!item && !image; else imageTemplate\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate\"></ng-container>\n </ng-container>\n <ng-template #imageTemplate>\n <div *ngIf=\"item.type === 'image/png' || item.type === 'image/jpeg' || item.type === 'image/bmp' || item.type === 'image/jpg' || item.type === 'image' ||\n mimeType === 'image/png' || mimeType === 'image/jpeg' || mimeType === 'image/bmp' || mimeType === 'image/jpg' || mimeType === 'image'\"\n class=\"thumbnail-image-wrapper\" [class.circle-shape]=\"isCircle\">\n <img class=\"thumbnail-image\" [class.circle-shape]=\"isCircle\" alt=\"image\" [src]=\"item.file || image\">\n <div class=\"thumbnail-controls\" *ngIf=\"!overlayTemplate\">\n <div class=\"view-button\" [style.width]=\"size.width\" [style.height]=\"size.height\" (click)=\"onViewImage( image )\">\n <tl-icon [lib]=\"'dx'\">find</tl-icon>\n </div>\n <div class=\"trash-button\" (click)=\"onDeleteThumb(item)\">\n <tl-icon *ngIf=\"showDeleteButton\" [lib]=\"'dx'\">trash</tl-icon>\n </div>\n </div>\n <div class=\"thumbnail-controls\" *ngIf=\"overlayTemplate\">\n <ng-container *ngTemplateOutlet=\"overlayTemplate; context: { $implicit: item || image }\"></ng-container>\n </div>\n </div>\n\n <div *ngIf=\"item.type === 'application/pdf' || mimeType === 'application/pdf'\" class=\"thumbnail-image-wrapper\" [class.circle-shape]=\"isCircle\">\n <tl-icon style=\"margin-right: 5px\" [lib]=\"'fa'\" [style]=\"'fas'\" [color]=\"'#ec7e7e'\" [size]=\"'40px'\">file-pdf</tl-icon>\n <div class=\"thumbnail-controls\" *ngIf=\"!overlayTemplate\">\n <div class=\"view-button\" [style.width]=\"size.width\" [style.height]=\"size.height\" (click)=\"onViewImage( image )\">\n <tl-icon [lib]=\"'dx'\">find</tl-icon>\n </div>\n <div class=\"trash-button\" (click)=\"onDeleteThumb(item)\">\n <tl-icon *ngIf=\"showDeleteButton\" [lib]=\"'dx'\">trash</tl-icon>\n </div>\n </div>\n <div class=\"thumbnail-controls\" *ngIf=\"overlayTemplate\">\n <ng-container *ngTemplateOutlet=\"overlayTemplate; context: { $implicit: item || image }\"></ng-container>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n", styles: [".thumbnail-container{display:flex}.thumbnail-container>.thumbnail{display:flex;align-items:center;justify-content:center;flex-flow:column;position:relative;width:100px;height:80px;background-color:#fafafa;border:1px dashed #d9d9d9;transition:border-color .3s ease;cursor:pointer;margin:0 5px;padding:2px;box-sizing:border-box}.thumbnail-container>.thumbnail>.icon{color:#e6e6e6;cursor:pointer;font-size:22px}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper{height:100%;width:100%;border-radius:5px;overflow:hidden;display:flex;align-items:center;justify-content:center}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper.circle-shape:before{border-radius:50%}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper:hover .thumbnail-controls{opacity:1}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper:before{position:absolute;z-index:1;width:100%;height:100%;background-color:#00000080;opacity:0;transition:all .3s;content:\" \";top:0;left:0}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-image{position:static;display:block;width:100%;height:100%;object-fit:cover}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-image.circle-shape{border-radius:50%}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls{position:absolute;width:100%;top:0;height:100%;color:#fff;font-size:22px;z-index:1000;left:0;opacity:0;cursor:pointer;display:flex;align-items:center;justify-content:center}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.view-button{margin-top:10px;display:flex;align-content:center;align-items:center;justify-content:center}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.view-button>tl-icon{margin-bottom:10px}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.trash-button{cursor:pointer;position:absolute;top:0;right:0;height:15px;display:flex;justify-content:center;align-items:center;background-color:#ec7e7e}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls>.trash-button>tl-icon{font-size:10px}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls .icon{cursor:pointer}.thumbnail-container>.thumbnail>.thumbnail-image-wrapper>.thumbnail-controls .icon:last-child{padding-left:10px}.thumbnail-container>.thumbnail:hover .thumbnail-image-wrapper:before{opacity:1}.thumbnail-container>.thumbnail.borderLess{border:0}.thumbnail-container>.thumbnail.circle-shape{border-radius:50%}.thumbnail-container>.thumbnail.marginLess{margin-left:0!important}.thumbnail-container>.thumbnail:first-child{margin-left:8px}.thumbnail-container>.thumbnail:hover{border-color:#6c9}\n"] }]
}], ctorParameters: function () { return [{ type: i1.LightboxService }, { type: i2.ThumbnailService }, { type: i3.DialogService }]; }, propDecorators: { image: [{
type: Input
}], mimeType: [{
type: Input
}], data: [{
type: Input
}], bordered: [{
type: Input
}], shape: [{
type: Input
}], size: [{
type: Input
}], showDeleteButton: [{
type: Input
}], confirmationDeleteMessage: [{
type: Input
}], showConfirmationOnDelete: [{
type: Input
}], modalDeleteOptions: [{
type: Input
}], overlayTemplate: [{
type: Input
}], emptyTemplate: [{
type: Input
}], clickThumbnail: [{
type: Output
}], clickDeleteThumbail: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGh1bWJuYWlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdHJ1bHktdWkvc3JjL2NvbXBvbmVudHMvdGh1bWJuYWlsL3RodW1ibmFpbC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL3RodW1ibmFpbC90aHVtYm5haWwuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFvQkU7QUFFRixPQUFPLEVBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBNkIsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7QUFXcEgsTUFBTSxPQUFPLFdBQVc7SUE4QnRCLFlBQ1UsZUFBZ0MsRUFDaEMsZ0JBQWtDLEVBQ2xDLGFBQTRCO1FBRjVCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNoQyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBM0I3QixTQUFJLEdBQTJFLEVBQUUsQ0FBQztRQUVsRixhQUFRLEdBQUcsSUFBSSxDQUFDO1FBRWhCLFVBQUssR0FBd0IsUUFBUSxDQUFDO1FBRXRDLFNBQUksR0FBc0MsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUU1RSxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFFekIsOEJBQXlCLEdBQUcsc0NBQXNDLENBQUM7UUFFbkUsNkJBQXdCLEdBQUcsS0FBSyxDQUFDO1FBUWhDLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUVwQyx3QkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBTWhELENBQUM7SUFFSixRQUFRLEtBQUksQ0FBQztJQUViLFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxFQUFFO1lBQ25ELElBQUssT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFlBQTRGLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDNUgsSUFBSSxDQUFDLElBQUksR0FBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBMkIsQ0FBQyxHQUFHLENBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtvQkFDckUsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO29CQUNsRixPQUFPLElBQUksQ0FBQztnQkFDZCxDQUFDLENBQUMsQ0FBQzthQUNKO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsS0FBSyxLQUFLLFFBQVEsQ0FBQztJQUNqQyxDQUFDO0lBRUQsV0FBVyxDQUFFLEtBQUs7UUFDaEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQUs7UUFDakIsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUU7WUFDakMsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBRSxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztnQkFDdkUsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO2FBQ2xELENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7U0FDbEM7UUFDRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7OzRIQWhFVSxXQUFXO2dIQUFYLFdBQVcsMGhCQ2pDeEIsNjZGQXNEQTs0RkRyQmEsV0FBVztrQkFMdkIsU0FBUzsrQkFDRSxjQUFjO2lLQU1mLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUVHLHlCQUF5QjtzQkFBakMsS0FBSztnQkFFRyx3QkFBd0I7c0JBQWhDLEtBQUs7Z0JBRUcsa0JBQWtCO3NCQUExQixLQUFLO2dCQUVHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBRUcsYUFBYTtzQkFBckIsS0FBSztnQkFFSSxjQUFjO3NCQUF2QixNQUFNO2dCQUVHLG1CQUFtQjtzQkFBNUIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gICAgTUlUIExpY2Vuc2VcblxuICAgIENvcHlyaWdodCAoYykgMjAxOCBUZW1haW5mbyBTb2Z0d2FyZVxuXG4gICAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICAgIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAgICBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gICAgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICAgIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICAgIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gICAgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gICAgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gICAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gICAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gICAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbiAgICBTT0ZUV0FSRS5cbiovXG5cbmltcG9ydCB7Q29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uSW5pdCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBUZW1wbGF0ZVJlZn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaWdodGJveFNlcnZpY2UgfSBmcm9tICcuLi9saWdodGJveC9zZXJ2aWNlcy9saWdodGJveC5zZXJ2aWNlJztcbmltcG9ydCB7IFRodW1ibmFpbFNlcnZpY2UgfSBmcm9tICcuL3RodW1ibmFpbC5zZXJ2aWNlJztcbmltcG9ydCB7IERpYWxvZ1NlcnZpY2UgfSBmcm9tICcuLi9kaWFsb2cvZGlhbG9nLnNlcnZpY2UnO1xuaW1wb3J0IHsgTW9kYWxPcHRpb25zIH0gZnJvbSAnLi4vbW9kYWwvaW50ZXJmYWNlcy9tb2RhbC1vcHRpb25zJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndGwtdGh1bWJuYWlsJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RodW1ibmFpbC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGh1bWJuYWlsLnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgVGxUaHVtYm5haWwgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG5cbiAgQElucHV0KCkgaW1hZ2U7XG5cbiAgQElucHV0KCkgbWltZVR5cGU7XG5cbiAgQElucHV0KCkgZGF0YTogeyBpbmRleD86IG51bWJlcjsgZGVzY3JpcHRpb24/OiBzdHJpbmcsIGZpbGU6IHN0cmluZywgdHlwZTogc3RyaW5nIH1bXSA9IFtdO1xuXG4gIEBJbnB1dCgpIGJvcmRlcmVkID0gdHJ1ZTtcblxuICBASW5wdXQoKSBzaGFwZTogJ3NxdWFyZScgfCAnY2lyY2xlJyA9ICdzcXVhcmUnO1xuXG4gIEBJbnB1dCgpIHNpemU6IHsgd2lkdGg6IHN0cmluZywgaGVpZ2h0OiBzdHJpbmcgfSA9IHsgd2lkdGg6ICc4MHB4JywgaGVpZ2h0OiAnODBweCcgfTtcblxuICBASW5wdXQoKSBzaG93RGVsZXRlQnV0dG9uID0gZmFsc2U7XG5cbiAgQElucHV0KCkgY29uZmlybWF0aW9uRGVsZXRlTWVzc2FnZSA9ICdEbyB5b3Ugd2FudCB0byBkZWxldGUgdGhlIFRodW1ibmFpbD8nO1xuXG4gIEBJbnB1dCgpIHNob3dDb25maXJtYXRpb25PbkRlbGV0ZSA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIG1vZGFsRGVsZXRlT3B0aW9uczogTW9kYWxPcHRpb25zO1xuXG4gIEBJbnB1dCgpIG92ZXJsYXlUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBASW5wdXQoKSBlbXB0eVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIEBPdXRwdXQoKSBjbGlja1RodW1ibmFpbCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAT3V0cHV0KCkgY2xpY2tEZWxldGVUaHVtYmFpbCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGxpZ2h0Ym94U2VydmljZTogTGlnaHRib3hTZXJ2aWNlLFxuICAgIHByaXZhdGUgdGh1bWJuYWlsU2VydmljZTogVGh1bWJuYWlsU2VydmljZSxcbiAgICBwcml2YXRlIGRpYWxvZ1NlcnZpY2U6IERpYWxvZ1NlcnZpY2VcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCkge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKGNoYW5nZXNbJ2RhdGEnXSAmJiBjaGFuZ2VzWydkYXRhJ10uY3VycmVudFZhbHVlKSB7XG4gICAgICBpZiAoKGNoYW5nZXNbJ2RhdGEnXS5jdXJyZW50VmFsdWUgYXMgQXJyYXk8eyBpbmRleD86IG51bWJlcjsgZGVzY3JpcHRpb24/OiBzdHJpbmcsIGZpbGU6IHN0cmluZywgdHlwZTogc3RyaW5nIH0+KS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IChjaGFuZ2VzWydkYXRhJ10uY3VycmVudFZhbHVlIGFzIEFycmF5PGFueT4pLm1hcCggKGZpbGUpID0+IHtcbiAgICAgICAgICBmaWxlLnR5cGUgPSAhZmlsZS50eXBlID8gdGhpcy50aHVtYm5haWxTZXJ2aWNlLmdldE1pbWVUeXBlKGZpbGUuZmlsZSkgOiBmaWxlLnR5cGU7XG4gICAgICAgICAgcmV0dXJuIGZpbGU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBpc0NpcmNsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zaGFwZSA9PT0gJ2NpcmNsZSc7XG4gIH1cblxuICBvblZpZXdJbWFnZSggaW1hZ2UgKSB7XG4gICAgdGhpcy5saWdodGJveFNlcnZpY2UuY3JlYXRlKCB0aGlzLmRhdGEsIGltYWdlKTtcbiAgfVxuXG4gIG9uRGVsZXRlVGh1bWIoaW1hZ2UpIHtcbiAgICBpZiAodGhpcy5zaG93Q29uZmlybWF0aW9uT25EZWxldGUpIHtcbiAgICAgIHJldHVybiB0aGlzLmRpYWxvZ1NlcnZpY2UuY29uZmlybWF0aW9uKCB0aGlzLmNvbmZpcm1hdGlvbkRlbGV0ZU1lc3NhZ2UsICh7XG4gICAgICAgIGlzWWVzOiAoKSA9PiB0aGlzLmNsaWNrRGVsZXRlVGh1bWJhaWwuZW1pdChpbWFnZSksXG4gICAgICB9KSwge30sIHRoaXMubW9kYWxEZWxldGVPcHRpb25zKTtcbiAgICB9XG4gICAgdGhpcy5jbGlja0RlbGV0ZVRodW1iYWlsLmVtaXQoaW1hZ2UpO1xuICB9XG5cbn1cbiIsIlxuPGRpdiBjbGFzcz1cInRodW1ibmFpbC1jb250YWluZXJcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRhdGEubGVuZ3RoID4gMDsgZWxzZSB0aHVtYlRlbXBsYXRlXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBkYXRhXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGh1bWJUZW1wbGF0ZTsgY29udGV4dDogeyAkaW1wbGljaXQ6IGl0ZW0gfVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI3RodW1iVGVtcGxhdGUgbGV0LWl0ZW0+XG4gIDxkaXYgY2xhc3M9XCJ0aHVtYm5haWxcIiAoY2xpY2spPVwiY2xpY2tUaHVtYm5haWwuZW1pdCgkZXZlbnQpXCJcbiAgICAgICBbc3R5bGUud2lkdGhdPVwic2l6ZS53aWR0aFwiXG4gICAgICAgW3N0eWxlLmhlaWdodF09XCJzaXplLmhlaWdodFwiXG4gICAgICAgW2NsYXNzLmNpcmNsZS1zaGFwZV09XCJpc0NpcmNsZVwiXG4gICAgICAgW2NsYXNzLmJvcmRlckxlc3NdPVwiIWJvcmRlcmVkXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpdGVtICYmICFpbWFnZTsgZWxzZSBpbWFnZVRlbXBsYXRlXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZW1wdHlUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy10ZW1wbGF0ZSAjaW1hZ2VUZW1wbGF0ZT5cbiAgICAgIDxkaXYgKm5nSWY9XCJpdGVtLnR5cGUgPT09ICdpbWFnZS9wbmcnIHx8IGl0ZW0udHlwZSA9PT0gJ2ltYWdlL2pwZWcnIHx8IGl0ZW0udHlwZSA9PT0gJ2ltYWdlL2JtcCcgfHwgaXRlbS50eXBlID09PSAnaW1hZ2UvanBnJyB8fCBpdGVtLnR5cGUgPT09ICdpbWFnZScgfHxcbiAgICAgICAgICAgICAgICAgICBtaW1lVHlwZSA9PT0gJ2ltYWdlL3BuZycgfHwgIG1pbWVUeXBlID09PSAnaW1hZ2UvanBlZycgfHwgIG1pbWVUeXBlID09PSAnaW1hZ2UvYm1wJyB8fCAgbWltZVR5cGUgPT09ICdpbWFnZS9qcGcnIHx8ICBtaW1lVHlwZSA9PT0gJ2ltYWdlJ1wiXG4gICAgICAgICAgIGNsYXNzPVwidGh1bWJuYWlsLWltYWdlLXdyYXBwZXJcIiBbY2xhc3MuY2lyY2xlLXNoYXBlXT1cImlzQ2lyY2xlXCI+XG4gICAgICAgIDxpbWcgY2xhc3M9XCJ0aHVtYm5haWwtaW1hZ2VcIiBbY2xhc3MuY2lyY2xlLXNoYXBlXT1cImlzQ2lyY2xlXCIgYWx0PVwiaW1hZ2VcIiBbc3JjXT1cIml0ZW0uZmlsZSB8fCBpbWFnZVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGh1bWJuYWlsLWNvbnRyb2xzXCIgKm5nSWY9XCIhb3ZlcmxheVRlbXBsYXRlXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInZpZXctYnV0dG9uXCIgW3N0eWxlLndpZHRoXT1cInNpemUud2lkdGhcIiBbc3R5bGUuaGVpZ2h0XT1cInNpemUuaGVpZ2h0XCIgKGNsaWNrKT1cIm9uVmlld0ltYWdlKCBpbWFnZSApXCI+XG4gICAgICAgICAgICA8dGwtaWNvbiBbbGliXT1cIidkeCdcIj5maW5kPC90bC1pY29uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0cmFzaC1idXR0b25cIiAoY2xpY2spPVwib25EZWxldGVUaHVtYihpdGVtKVwiPlxuICAgICAgICAgICAgPHRsLWljb24gKm5nSWY9XCJzaG93RGVsZXRlQnV0dG9uXCIgIFtsaWJdPVwiJ2R4J1wiPnRyYXNoPC90bC1pY29uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRodW1ibmFpbC1jb250cm9sc1wiICpuZ0lmPVwib3ZlcmxheVRlbXBsYXRlXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm92ZXJsYXlUZW1wbGF0ZTsgY29udGV4dDogeyAkaW1wbGljaXQ6IGl0ZW0gfHwgaW1hZ2UgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2ICpuZ0lmPVwiaXRlbS50eXBlID09PSAnYXBwbGljYXRpb24vcGRmJyB8fCBtaW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIiBjbGFzcz1cInRodW1ibmFpbC1pbWFnZS13cmFwcGVyXCIgW2NsYXNzLmNpcmNsZS1zaGFwZV09XCJpc0NpcmNsZVwiPlxuICAgICAgICA8dGwtaWNvbiBzdHlsZT1cIm1hcmdpbi1yaWdodDogNXB4XCIgW2xpYl09XCInZmEnXCIgW3N0eWxlXT1cIidmYXMnXCIgW2NvbG9yXT1cIicjZWM3ZTdlJ1wiIFtzaXplXT1cIic0MHB4J1wiPmZpbGUtcGRmPC90bC1pY29uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGh1bWJuYWlsLWNvbnRyb2xzXCIgKm5nSWY9XCIhb3ZlcmxheVRlbXBsYXRlXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInZpZXctYnV0dG9uXCIgW3N0eWxlLndpZHRoXT1cInNpemUud2lkdGhcIiBbc3R5bGUuaGVpZ2h0XT1cInNpemUuaGVpZ2h0XCIgKGNsaWNrKT1cIm9uVmlld0ltYWdlKCBpbWFnZSApXCI+XG4gICAgICAgICAgICA8dGwtaWNvbiBbbGliXT1cIidkeCdcIj5maW5kPC90bC1pY29uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0cmFzaC1idXR0b25cIiAoY2xpY2spPVwib25EZWxldGVUaHVtYihpdGVtKVwiPlxuICAgICAgICAgICAgPHRsLWljb24gKm5nSWY9XCJzaG93RGVsZXRlQnV0dG9uXCIgIFtsaWJdPVwiJ2R4J1wiPnRyYXNoPC90bC1pY29uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRodW1ibmFpbC1jb250cm9sc1wiICpuZ0lmPVwib3ZlcmxheVRlbXBsYXRlXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm92ZXJsYXlUZW1wbGF0ZTsgY29udGV4dDogeyAkaW1wbGljaXQ6IGl0ZW0gfHwgaW1hZ2UgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuIl19