UNPKG

ng-image-slider-v17

Version:

Angular Image slider with lightbox. An Angular responsive image slider with lightbox popup. Also support youtube url, image base64 string and mp4 video urls and base64 string.

240 lines 41.6 kB
import { Component, Inject, Input, Output, EventEmitter, ViewChild, HostListener } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; import * as i2 from "@angular/common"; import * as i3 from "../slider-custom-image/slider-custom-image.component"; const LIGHTBOX_NEXT_ARROW_CLICK_MESSAGE = 'lightbox next', LIGHTBOX_PREV_ARROW_CLICK_MESSAGE = 'lightbox previous'; export class SliderLightboxComponent { set imageIndex(index) { if (index !== undefined && index > -1 && index < this.images.length) { this.currentImageIndex = index; } this.nextPrevDisable(); } set show(visiableFlag) { this.imageFullscreenView = visiableFlag; this.elRef.nativeElement.ownerDocument.body.style.overflow = ''; if (visiableFlag === true) { this.elRef.nativeElement.ownerDocument.body.style.overflow = 'hidden'; // this.getImageData(); this.setPopupSliderWidth(); } } set animationSpeed(data) { if (data && typeof (data) === 'number' && data >= 0.1 && data <= 5) { this.speed = data; } } onResize(event) { this.effectStyle = 'none'; this.setPopupSliderWidth(); } handleKeyboardEvent(event) { if (event && event.key && this.arrowKeyMove) { if (event.key.toLowerCase() === 'arrowright') { this.nextImageLightbox(); } if (event.key.toLowerCase() === 'arrowleft') { this.prevImageLightbox(); } if (event.key.toLowerCase() === 'escape') { this.closeLightbox(); } } } constructor(cdRef, sanitizer, elRef, document) { this.cdRef = cdRef; this.sanitizer = sanitizer; this.elRef = elRef; this.document = document; this.totalImages = 0; this.nextImageIndex = -1; this.popupWidth = 1200; this.marginLeft = 0; this.imageFullscreenView = false; this.lightboxPrevDisable = false; this.lightboxNextDisable = false; this.showLoading = true; this.effectStyle = 'none'; this.speed = 1; // default speed in second this.title = ''; this.currentImageIndex = 0; // @Inputs this.images = []; this.videoAutoPlay = false; this.direction = 'ltr'; this.paginationShow = false; this.infinite = false; this.arrowKeyMove = true; this.showVideoControls = true; // @Output this.close = new EventEmitter(); this.prevImage = new EventEmitter(); this.nextImage = new EventEmitter(); } ngOnInit() { } ngAfterViewInit() { } ngOnDestroy() { this.resetState(); } setPopupSliderWidth() { if (window && window.innerWidth) { this.popupWidth = window.innerWidth; this.totalImages = this.images.length; if (typeof (this.currentImageIndex) === 'number' && this.currentImageIndex !== undefined) { this.marginLeft = -1 * this.popupWidth * this.currentImageIndex; this.getImageData(); this.nextPrevDisable(); setTimeout(() => { this.showLoading = false; }, 500); } } } closeLightbox() { this.close.emit(); } prevImageLightbox() { this.effectStyle = `all ${this.speed}s ease-in-out`; if (this.currentImageIndex > 0 && !this.lightboxPrevDisable) { this.currentImageIndex--; this.prevImage.emit(LIGHTBOX_PREV_ARROW_CLICK_MESSAGE); this.marginLeft = -1 * this.popupWidth * this.currentImageIndex; this.getImageData(); this.nextPrevDisable(); } } nextImageLightbox() { this.effectStyle = `all ${this.speed}s ease-in-out`; if (this.currentImageIndex < this.images.length - 1 && !this.lightboxNextDisable) { this.currentImageIndex++; this.nextImage.emit(LIGHTBOX_NEXT_ARROW_CLICK_MESSAGE); this.marginLeft = -1 * this.popupWidth * this.currentImageIndex; this.getImageData(); this.nextPrevDisable(); } } nextPrevDisable() { this.lightboxNextDisable = true; this.lightboxPrevDisable = true; setTimeout(() => { this.applyButtonDisableCondition(); }, this.speed * 1000); } applyButtonDisableCondition() { this.lightboxNextDisable = false; this.lightboxPrevDisable = false; if (!this.infinite && this.currentImageIndex >= this.images.length - 1) { this.lightboxNextDisable = true; } if (!this.infinite && this.currentImageIndex <= 0) { this.lightboxPrevDisable = true; } } getImageData() { if (this.images && this.images.length && typeof (this.currentImageIndex) === 'number' && this.currentImageIndex !== undefined && this.images[this.currentImageIndex] && (this.images[this.currentImageIndex]['image'] || this.images[this.currentImageIndex]['video'])) { this.title = this.images[this.currentImageIndex]['title'] || ''; this.totalImages = this.images.length; for (const iframeI in this.document.getElementsByTagName('iframe')) { if (this.document.getElementsByTagName('iframe')[iframeI] && this.document.getElementsByTagName('iframe')[iframeI].contentWindow && this.document.getElementsByTagName('iframe')[iframeI].contentWindow.postMessage) { this.document.getElementsByTagName('iframe')[iframeI].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*'); } } for (const videoI in this.document.getElementsByTagName('video')) { if (this.document.getElementsByTagName('video')[videoI] && this.document.getElementsByTagName('video')[videoI].pause) { this.document.getElementsByTagName('video')[videoI].pause(); } } } } resetState() { this.images = []; } /** * Swipe event handler * Reference from https://stackoverflow.com/a/44511007/2067646 */ swipeLightboxImg(e, when) { const coord = [e.changedTouches[0].pageX, e.changedTouches[0].pageY]; const time = new Date().getTime(); if (when === 'start') { this.swipeLightboxImgCoord = coord; this.swipeLightboxImgTime = time; } else if (when === 'end') { const direction = [coord[0] - this.swipeLightboxImgCoord[0], coord[1] - this.swipeLightboxImgCoord[1]]; const duration = time - this.swipeLightboxImgTime; if (duration < 1000 // && Math.abs(direction[0]) > 30 // Long enough && Math.abs(direction[0]) > Math.abs(direction[1] * 3)) { // Horizontal enough if (direction[0] < 0) { this.nextImageLightbox(); } else { this.prevImageLightbox(); } } } } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SliderLightboxComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.DomSanitizer }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); } /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: SliderLightboxComponent, selector: "slider-lightbox", inputs: { images: "images", imageIndex: "imageIndex", show: "show", videoAutoPlay: "videoAutoPlay", direction: "direction", paginationShow: "paginationShow", animationSpeed: "animationSpeed", infinite: "infinite", arrowKeyMove: "arrowKeyMove", showVideoControls: "showVideoControls" }, outputs: { close: "close", prevImage: "prevImage", nextImage: "nextImage" }, host: { listeners: { "window:resize": "onResize($event)", "document:keyup": "handleKeyboardEvent($event)" } }, viewQueries: [{ propertyName: "lightboxDiv", first: true, predicate: ["lightboxDiv"], descendants: true }, { propertyName: "lightboxImageDiv", first: true, predicate: ["lightboxImageDiv"], descendants: true }], ngImport: i0, template: "<div *ngIf=\"imageFullscreenView\" class=\"ng-image-fullscreen-view\">\r\n <div class=\"lightbox-wrapper\">\r\n <a class=\"close\" (click)=\"closeLightbox()\"></a>\r\n <div class=\"lightbox-div\" #lightboxDiv>\r\n <div *ngIf=\"showLoading\" class=\"pre-loader\">\r\n <div class=\"mnml-spinner\"></div>\r\n </div>\r\n <div class=\"lightbox-image-main\"\r\n [ngStyle]=\"{'margin-left': marginLeft + 'px', 'grid-template-columns': 'repeat('+images.length+',1fr)', 'transition': effectStyle}\">\r\n <div class=\"lightbox-image\"\r\n [ngStyle]=\"{'width': popupWidth + 'px'}\"\r\n *ngFor=\"let img of images; let i = index\"\r\n [attr.id]=\"'ng-lightbox-image-' + i\"\r\n (touchstart)=\"swipeLightboxImg($event, 'start')\"\r\n (touchend)=\"swipeLightboxImg($event, 'end')\"\r\n #lightboxImageDiv>\r\n <div class=\"close-outside\" (click)=\"!img?.video && closeLightbox()\"></div>\r\n <custom-img\r\n [imageUrl]=\"img?.image || img?.video\"\r\n [isVideo]=\"!!(img?.posterImage || img?.video)\"\r\n [currentImageIndex]=\"currentImageIndex\"\r\n [imageIndex]=\"i\"\r\n [speed]=\"speed\"\r\n [videoAutoPlay]=\"videoAutoPlay && i == currentImageIndex\"\r\n [showVideoControls]=\"showVideoControls ? 1 : 0\"\r\n [alt]=\"img?.alt || img?.title || ''\"\r\n [title]=\"img?.title || img?.alt || ''\"\r\n [showVideo]=\"true\"\r\n [direction]=\"direction\">\r\n </custom-img>\r\n </div>\r\n </div>\r\n <div [dir]=\"direction\" [ngClass]=\"{'show': title, 'hide': !title}\" class=\"caption\">{{ title }}</div>\r\n <a *ngIf=\"images.length > 1\" [ngClass]=\"{'disable': lightboxPrevDisable}\" class=\"prev icons prev-icon\" (click)=\"prevImageLightbox()\">&lsaquo;</a>\r\n <a *ngIf=\"images.length > 1\" [ngClass]=\"{'disable': lightboxNextDisable}\" class=\"next icons next-icon\" (click)=\"nextImageLightbox()\">&rsaquo;</a>\r\n </div>\r\n </div>\r\n <div *ngIf=\"paginationShow\" class=\"popup-pagination\">{{currentImageIndex + 1}} of {{totalImages}}</div>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.SliderCustomImageComponent, selector: "custom-img", inputs: ["showVideo", "videoAutoPlay", "showVideoControls", "currentImageIndex", "imageIndex", "speed", "imageUrl", "isVideo", "alt", "title", "direction", "ratio", "lazy"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: SliderLightboxComponent, decorators: [{ type: Component, args: [{ selector: 'slider-lightbox', template: "<div *ngIf=\"imageFullscreenView\" class=\"ng-image-fullscreen-view\">\r\n <div class=\"lightbox-wrapper\">\r\n <a class=\"close\" (click)=\"closeLightbox()\"></a>\r\n <div class=\"lightbox-div\" #lightboxDiv>\r\n <div *ngIf=\"showLoading\" class=\"pre-loader\">\r\n <div class=\"mnml-spinner\"></div>\r\n </div>\r\n <div class=\"lightbox-image-main\"\r\n [ngStyle]=\"{'margin-left': marginLeft + 'px', 'grid-template-columns': 'repeat('+images.length+',1fr)', 'transition': effectStyle}\">\r\n <div class=\"lightbox-image\"\r\n [ngStyle]=\"{'width': popupWidth + 'px'}\"\r\n *ngFor=\"let img of images; let i = index\"\r\n [attr.id]=\"'ng-lightbox-image-' + i\"\r\n (touchstart)=\"swipeLightboxImg($event, 'start')\"\r\n (touchend)=\"swipeLightboxImg($event, 'end')\"\r\n #lightboxImageDiv>\r\n <div class=\"close-outside\" (click)=\"!img?.video && closeLightbox()\"></div>\r\n <custom-img\r\n [imageUrl]=\"img?.image || img?.video\"\r\n [isVideo]=\"!!(img?.posterImage || img?.video)\"\r\n [currentImageIndex]=\"currentImageIndex\"\r\n [imageIndex]=\"i\"\r\n [speed]=\"speed\"\r\n [videoAutoPlay]=\"videoAutoPlay && i == currentImageIndex\"\r\n [showVideoControls]=\"showVideoControls ? 1 : 0\"\r\n [alt]=\"img?.alt || img?.title || ''\"\r\n [title]=\"img?.title || img?.alt || ''\"\r\n [showVideo]=\"true\"\r\n [direction]=\"direction\">\r\n </custom-img>\r\n </div>\r\n </div>\r\n <div [dir]=\"direction\" [ngClass]=\"{'show': title, 'hide': !title}\" class=\"caption\">{{ title }}</div>\r\n <a *ngIf=\"images.length > 1\" [ngClass]=\"{'disable': lightboxPrevDisable}\" class=\"prev icons prev-icon\" (click)=\"prevImageLightbox()\">&lsaquo;</a>\r\n <a *ngIf=\"images.length > 1\" [ngClass]=\"{'disable': lightboxNextDisable}\" class=\"next icons next-icon\" (click)=\"nextImageLightbox()\">&rsaquo;</a>\r\n </div>\r\n </div>\r\n <div *ngIf=\"paginationShow\" class=\"popup-pagination\">{{currentImageIndex + 1}} of {{totalImages}}</div>\r\n</div>\r\n" }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.DomSanitizer }, { type: i0.ElementRef }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }], propDecorators: { lightboxDiv: [{ type: ViewChild, args: ['lightboxDiv', { static: false }] }], lightboxImageDiv: [{ type: ViewChild, args: ['lightboxImageDiv', { static: false }] }], images: [{ type: Input }], imageIndex: [{ type: Input }], show: [{ type: Input }], videoAutoPlay: [{ type: Input }], direction: [{ type: Input }], paginationShow: [{ type: Input }], animationSpeed: [{ type: Input }], infinite: [{ type: Input }], arrowKeyMove: [{ type: Input }], showVideoControls: [{ type: Input }], close: [{ type: Output }], prevImage: [{ type: Output }], nextImage: [{ type: Output }], onResize: [{ type: HostListener, args: ['window:resize', ['$event']] }], handleKeyboardEvent: [{ type: HostListener, args: ['document:keyup', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGVyLWxpZ2h0Ym94LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWltYWdlLXNsaWRlci9zcmMvbGliL3NsaWRlci1saWdodGJveC9zbGlkZXItbGlnaHRib3guY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctaW1hZ2Utc2xpZGVyL3NyYy9saWIvc2xpZGVyLWxpZ2h0Ym94L3NsaWRlci1saWdodGJveC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUgsU0FBUyxFQUlULE1BQU0sRUFHTixLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWixTQUFTLEVBQ1QsWUFBWSxFQUVmLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7QUFHM0MsTUFBTSxpQ0FBaUMsR0FBRyxlQUFlLEVBQ3JELGlDQUFpQyxHQUFHLG1CQUFtQixDQUFBO0FBTTNELE1BQU0sT0FBTyx1QkFBdUI7SUF1QmhDLElBQ0ksVUFBVSxDQUFDLEtBQWE7UUFDeEIsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDakUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQztTQUNsQztRQUNELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBQ0QsSUFDSSxJQUFJLENBQUMsWUFBcUI7UUFDMUIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFlBQVksQ0FBQztRQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2hFLElBQUksWUFBWSxLQUFL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O3NCQUF0QixLQUFLO2dCQUVGLGNBQWM7c0JBRGpCLEtBQUs7Z0JBU0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFHSSxLQUFLO3NCQUFkLE1BQU07Z0JBQ0csU0FBUztzQkFBbEIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQUdQLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyxlQUFlLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBTXpDLG1CQUFtQjtzQkFEbEIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIENvbXBvbmVudCxcclxuICAgIE9uSW5pdCxcclxuICAgIE9uQ2hhbmdlcyxcclxuICAgIFNpbXBsZUNoYW5nZXMsXHJcbiAgICBJbmplY3QsXHJcbiAgICBBZnRlclZpZXdJbml0LFxyXG4gICAgT25EZXN0cm95LFxyXG4gICAgSW5wdXQsXHJcbiAgICBPdXRwdXQsXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBWaWV3Q2hpbGQsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBFbGVtZW50UmVmXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcblxyXG5jb25zdCBMSUdIVEJPWF9ORVhUX0FSUk9XX0NMSUNLX01FU1NBR0UgPSAnbGlnaHRib3ggbmV4dCcsXHRcclxuICAgIExJR0hUQk9YX1BSRVZfQVJST1dfQ0xJQ0tfTUVTU0FHRSA9ICdsaWdodGJveCBwcmV2aW91cydcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdzbGlkZXItbGlnaHRib3gnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL3NsaWRlci1saWdodGJveC5jb21wb25lbnQuaHRtbCdcclxufSlcclxuZXhwb3J0IGNsYXNzIFNsaWRlckxpZ2h0Ym94Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xyXG4gICAgdG90YWxJbWFnZXM6IG51bWJlciA9IDA7XHJcbiAgICBuZXh0SW1hZ2VJbmRleDogbnVtYmVyID0gLTE7XHJcbiAgICBwb3B1cFdpZHRoOiBudW1iZXIgPSAxMjAwO1xyXG4gICAgbWFyZ2luTGVmdDogbnVtYmVyID0gMDtcclxuICAgIGltYWdlRnVsbHNjcmVlblZpZXc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGxpZ2h0Ym94UHJldkRpc2FibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGxpZ2h0Ym94TmV4dERpc2FibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIHNob3dMb2FkaW5nOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIGVmZmVjdFN0eWxlOiBzdHJpbmcgPSAnbm9uZSc7XHJcbiAgICBzcGVlZDogbnVtYmVyID0gMTsgLy8gZGVmYXVsdCBzcGVlZCBpbiBzZWNvbmRcclxuICAgIHRpdGxlOiBzdHJpbmcgPSAnJztcclxuICAgIGN1cnJlbnRJbWFnZUluZGV4OiBudW1iZXIgPSAwO1xyXG5cclxuICAgIC8vIGZvciBzd2lwZSBldmVudFxyXG4gICAgcHJpdmF0ZSBzd2lwZUxpZ2h0Ym94SW1nQ29vcmQ/OiBbbnVtYmVyLCBudW1iZXJdO1xyXG4gICAgcHJpdmF0ZSBzd2lwZUxpZ2h0Ym94SW1nVGltZT86IG51bWJlcjtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdsaWdodGJveERpdicsIHsgc3RhdGljOiBmYWxzZSB9KSBsaWdodGJveERpdjtcclxuICAgIEBWaWV3Q2hpbGQoJ2xpZ2h0Ym94SW1hZ2VEaXYnLCB7IHN0YXRpYzogZmFsc2UgfSkgbGlnaHRib3hJbWFnZURpdjtcclxuXHJcbiAgICAvLyBASW5wdXRzXHJcbiAgICBASW5wdXQoKSBpbWFnZXM6IEFycmF5PG9iamVjdD4gPSBbXTtcclxuICAgIEBJbnB1dCgpXHJcbiAgICBzZXQgaW1hZ2VJbmRleChpbmRleDogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKGluZGV4ICE9PSB1bmRlZmluZWQgJiYgaW5kZXggPiAtMSAmJiBpbmRleCA8IHRoaXMuaW1hZ2VzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZUluZGV4ID0gaW5kZXg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubmV4dFByZXZEaXNhYmxlKCk7XHJcbiAgICB9XHJcbiAgICBASW5wdXQoKVxyXG4gICAgc2V0IHNob3codmlzaWFibGVGbGFnOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5pbWFnZUZ1bGxzY3JlZW5WaWV3ID0gdmlzaWFibGVGbGFnO1xyXG4gICAgICAgIHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5vd25lckRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnJztcclxuICAgICAgICBpZiAodmlzaWFibGVGbGFnID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5vd25lckRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgLy8gdGhpcy5nZXRJbWFnZURhdGEoKTtcclxuICAgICAgICAgICAgdGhpcy5zZXRQb3B1cFNsaWRlcldpZHRoKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCkgdmlkZW9BdXRvUGxheTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgZGlyZWN0aW9uOiBzdHJpbmcgPSAnbHRyJztcclxuICAgIEBJbnB1dCgpIHBhZ2luYXRpb25TaG93OiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKVxyXG4gICAgc2V0IGFuaW1hdGlvblNwZWVkKGRhdGE6IG51bWJlcikge1xyXG4gICAgICAgIGlmIChkYXRhXHJcbiAgICAgICAgICAgICYmIHR5cGVvZiAoZGF0YSkgPT09ICdudW1iZXInXHJcbiAgICAgICAgICAgICYmIGRhdGEgPj0gMC4xXHJcbiAgICAgICAgICAgICYmIGRhdGEgPD0gNSkge1xyXG4gICAgICAgICAgICB0aGlzLnNwZWVkID0gZGF0YTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoKSBpbmZpbml0ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgYXJyb3dLZXlNb3ZlOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIHNob3dWaWRlb0NvbnRyb2xzOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgICAvLyBAT3V0cHV0XHJcbiAgICBAT3V0cHV0KCkgY2xvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIEBPdXRwdXQoKSBwcmV2SW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIEBPdXRwdXQoKSBuZXh0SW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcclxuICAgIG9uUmVzaXplKGV2ZW50KSB7XHJcbiAgICAgICAgdGhpcy5lZmZlY3RTdHlsZSA9ICdub25lJztcclxuICAgICAgICB0aGlzLnNldFBvcHVwU2xpZGVyV2lkdGgoKTtcclxuICAgIH1cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleXVwJywgWyckZXZlbnQnXSlcclxuICAgIGhhbmRsZUtleWJvYXJkRXZlbnQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoZXZlbnQgJiYgZXZlbnQua2V5ICYmIHRoaXMuYXJyb3dLZXlNb3ZlKSB7XHJcbiAgICAgICAgICAgIGlmIChldmVudC5rZXkudG9Mb3dlckNhc2UoKSA9PT0gJ2Fycm93cmlnaHQnKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5leHRJbWFnZUxpZ2h0Ym94KCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChldmVudC5rZXkudG9Mb3dlckNhc2UoKSA9PT0gJ2Fycm93bGVmdCcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucHJldkltYWdlTGlnaHRib3goKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGV2ZW50LmtleS50b0xvd2VyQ2FzZSgpID09PSAnZXNjYXBlJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZUxpZ2h0Ym94KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcclxuICAgICAgICBwcml2YXRlIGVsUmVmOiBFbGVtZW50UmVmLFxyXG4gICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IGFueSkgeyB9XHJcblxyXG4gICAgbmdPbkluaXQoKSB7XHJcbiAgICB9XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIHRoaXMucmVzZXRTdGF0ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFBvcHVwU2xpZGVyV2lkdGgoKSB7XHJcbiAgICAgICAgaWYgKHdpbmRvdyAmJiB3aW5kb3cuaW5uZXJXaWR0aCkge1xyXG4gICAgICAgICAgICB0aGlzLnBvcHVwV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcclxuICAgICAgICAgICAgdGhpcy50b3RhbEltYWdlcyA9IHRoaXMuaW1hZ2VzLmxlbmd0aDtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiAodGhpcy5jdXJyZW50SW1hZ2VJbmRleCkgPT09ICdudW1iZXInICYmIHRoaXMuY3VycmVudEltYWdlSW5kZXggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXJnaW5MZWZ0ID0gLTEgKiB0aGlzLnBvcHVwV2lkdGggKiB0aGlzLmN1cnJlbnRJbWFnZUluZGV4O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRJbWFnZURhdGEoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubmV4dFByZXZEaXNhYmxlKCk7XHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9LCA1MDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlTGlnaHRib3goKSB7XHJcbiAgICAgICAgdGhpcy5jbG9zZS5lbWl0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJldkltYWdlTGlnaHRib3goKSB7XHJcbiAgICAgICAgdGhpcy5lZmZlY3RTdHlsZSA9IGBhbGwgJHt0aGlzLnNwZWVkfXMgZWFzZS1pbi1vdXRgO1xyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRJbWFnZUluZGV4ID4gMCAmJiAhdGhpcy5saWdodGJveFByZXZEaXNhYmxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEltYWdlSW5kZXgtLTtcclxuICAgICAgICAgICAgdGhpcy5wcmV2SW1hZ2UuZW1pdChMSUdIVEJPWF9QUkVWX0FSUk9XX0NMSUNLX01FU1NBR0UpO1xyXG4gICAgICAgICAgICB0aGlzLm1hcmdpbkxlZnQgPSAtMSAqIHRoaXMucG9wdXBXaWR0aCAqIHRoaXMuY3VycmVudEltYWdlSW5kZXg7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0SW1hZ2VEYXRhKCk7XHJcbiAgICAgICAgICAgIHRoaXMubmV4dFByZXZEaXNhYmxlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5leHRJbWFnZUxpZ2h0Ym94KCkge1xyXG4gICAgICAgIHRoaXMuZWZmZWN0U3R5bGUgPSBgYWxsICR7dGhpcy5zcGVlZH1zIGVhc2UtaW4tb3V0YDtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50SW1hZ2VJbmRleCA8IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEgJiYgIXRoaXMubGlnaHRib3hOZXh0RGlzYWJsZSkge1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZUluZGV4Kys7XHJcbiAgICAgICAgICAgIHRoaXMubmV4dEltYWdlLmVtaXQoTElHSFRCT1hfTkVYVF9BUlJPV19DTElDS19NRVNTQUdFKTtcclxuICAgICAgICAgICAgdGhpcy5tYXJnaW5MZWZ0ID0gLTEgKiB0aGlzLnBvcHVwV2lkdGggKiB0aGlzLmN1cnJlbnRJbWFnZUluZGV4O1xyXG4gICAgICAgICAgICB0aGlzLmdldEltYWdlRGF0YSgpO1xyXG4gICAgICAgICAgICB0aGlzLm5leHRQcmV2RGlzYWJsZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBuZXh0UHJldkRpc2FibGUoKSB7XHJcbiAgICAgICAgdGhpcy5saWdodGJveE5leHREaXNhYmxlID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmxpZ2h0Ym94UHJldkRpc2FibGUgPSB0cnVlO1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmFwcGx5QnV0dG9uRGlzYWJsZUNvbmRpdGlvbigpO1xyXG4gICAgICAgIH0sIHRoaXMuc3BlZWQgKiAxMDAwKTtcclxuICAgIH1cclxuXHJcbiAgICBhcHBseUJ1dHRvbkRpc2FibGVDb25kaXRpb24oKSB7XHJcbiAgICAgICAgdGhpcy5saWdodGJveE5leHREaXNhYmxlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5saWdodGJveFByZXZEaXNhYmxlID0gZmFsc2U7XHJcbiAgICAgICAgaWYgKCF0aGlzLmluZmluaXRlICYmIHRoaXMuY3VycmVudEltYWdlSW5kZXggPj0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICB0aGlzLmxpZ2h0Ym94TmV4dERpc2FibGUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuaW5maW5pdGUgJiYgdGhpcy5jdXJyZW50SW1hZ2VJbmRleCA8PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGlnaHRib3hQcmV2RGlzYWJsZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldEltYWdlRGF0YSgpIHtcclxuICAgICAgICBpZiAodGhpcy5pbWFnZXNcclxuICAgICAgICAgICAgJiYgdGhpcy5pbWFnZXMubGVuZ3RoXHJcbiAgICAgICAgICAgICYmIHR5cGVvZiAodGhpcy5jdXJyZW50SW1hZ2VJbmRleCkgPT09ICdudW1iZXInXHJcbiAgICAgICAgICAgICYmIHRoaXMuY3VycmVudEltYWdlSW5kZXggIT09IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAmJiB0aGlzLmltYWdlc1t0aGlzLmN1cnJlbnRJbWFnZUluZGV4XVxyXG4gICAgICAgICAgICAmJiAodGhpcy5pbWFnZXNbdGhpcy5jdXJyZW50SW1hZ2VJbmRleF1bJ2ltYWdlJ10gfHwgdGhpcy5pbWFnZXNbdGhpcy5jdXJyZW50SW1hZ2VJbmRleF1bJ3ZpZGVvJ10pKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGl0bGUgPSB0aGlzLmltYWdlc1t0aGlzLmN1cnJlbnRJbWFnZUluZGV4XVsndGl0bGUnXSB8fCAnJztcclxuICAgICAgICAgICAgdGhpcy50b3RhbEltYWdlcyA9IHRoaXMuaW1hZ2VzLmxlbmd0aDtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBpZnJhbWVJIGluIHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lmcmFtZScpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaWZyYW1lJylbaWZyYW1lSV1cclxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpZnJhbWUnKVtpZnJhbWVJXS5jb250ZW50V2luZG93XHJcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaWZyYW1lJylbaWZyYW1lSV0uY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lmcmFtZScpW2lmcmFtZUldLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoJ3tcImV2ZW50XCI6XCJjb21tYW5kXCIsXCJmdW5jXCI6XCJwYXVzZVZpZGVvXCIsXCJhcmdzXCI6XCJcIn0nLCAnKicpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgdmlkZW9JIGluIHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3ZpZGVvJykpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCd2aWRlbycpW3ZpZGVvSV0gJiYgdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndmlkZW8nKVt2aWRlb0ldLnBhdXNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndmlkZW8nKVt2aWRlb0ldLnBhdXNlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmVzZXRTdGF0ZSgpIHtcclxuICAgICAgICB0aGlzLmltYWdlcyA9IFtdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3dpcGUgZXZlbnQgaGFuZGxlclxyXG4gICAgICogUmVmZXJlbmNlIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ0NTExMDA3LzIwNjc2NDZcclxuICAgICAqL1xyXG4gICAgc3dpcGVMaWdodGJveEltZyhlOiBUb3VjaEV2ZW50LCB3aGVuOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBjb29yZDogW251bWJlciwgbnVtYmVyXSA9IFtlLmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VYLCBlLmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VZXTtcclxuICAgICAgICBjb25zdCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcblxyXG4gICAgICAgIGlmICh3aGVuID09PSAnc3RhcnQnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3dpcGVMaWdodGJveEltZ0Nvb3JkID0gY29vcmQ7XHJcbiAgICAgICAgICAgIHRoaXMuc3dpcGVMaWdodGJveEltZ1RpbWUgPSB0aW1lO1xyXG4gICAgICAgIH0gZWxzZSBpZiAod2hlbiA9PT0gJ2VuZCcpIHtcclxuICAgICAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gW2Nvb3JkWzBdIC0gdGhpcy5zd2lwZUxpZ2h0Ym94SW1nQ29vcmRbMF0sIGNvb3JkWzFdIC0gdGhpcy5zd2lwZUxpZ2h0Ym94SW1nQ29vcmRbMV1dO1xyXG4gICAgICAgICAgICBjb25zdCBkdXJhdGlvbiA9IHRpbWUgLSB0aGlzLnN3aXBlTGlnaHRib3hJbWdUaW1lO1xyXG5cclxuICAgICAgICAgICAgaWYgKGR1cmF0aW9uIDwgMTAwMCAvL1xyXG4gICAgICAgICAgICAgICAgJiYgTWF0aC5hYnMoZGlyZWN0aW9uWzBdKSA+IDMwIC8vIExvbmcgZW5vdWdoXHJcbiAgICAgICAgICAgICAgICAmJiBNYXRoLmFicyhkaXJlY3Rpb25bMF0pID4gTWF0aC5hYnMoZGlyZWN0aW9uWzFdICogMykpIHsgLy8gSG9yaXpvbnRhbCBlbm91Z2hcclxuICAgICAgICAgICAgICAgIGlmIChkaXJlY3Rpb25bMF0gPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5uZXh0SW1hZ2VMaWdodGJveCgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZJbWFnZUxpZ2h0Ym94KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiPGRpdiAqbmdJZj1cImltYWdlRnVsbHNjcmVlblZpZXdcIiBjbGFzcz1cIm5nLWltYWdlLWZ1bGxzY3JlZW4tdmlld1wiPlxyXG4gICAgPGRpdiBjbGFzcz1cImxpZ2h0Ym94LXdyYXBwZXJcIj5cclxuICAgICAgICA8YSBjbGFzcz1cImNsb3NlXCIgKGNsaWNrKT1cImNsb3NlTGlnaHRib3goKVwiPjwvYT5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibGlnaHRib3gtZGl2XCIgI2xpZ2h0Ym94RGl2PlxyXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2hvd0xvYWRpbmdcIiBjbGFzcz1cInByZS1sb2FkZXJcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtbm1sLXNwaW5uZXJcIj48L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaWdodGJveC1pbWFnZS1tYWluXCJcclxuICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsnbWFyZ2luLWxlZnQnOiBtYXJnaW5MZWZ0ICsgJ3B4JywgJ2dyaWQtdGVtcGxhdGUtY29sdW1ucyc6ICdyZXBlYXQoJytpbWFnZXMubGVuZ3RoKycsMWZyKScsICd0cmFuc2l0aW9uJzogZWZmZWN0U3R5bGV9XCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGlnaHRib3gtaW1hZ2VcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsnd2lkdGgnOiBwb3B1cFdpZHRoICsgJ3B4J31cIlxyXG4gICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBpbWcgb2YgaW1hZ2VzOyBsZXQgaSA9IGluZGV4XCJcclxuICAgICAgICAgICAgICAgICAgICBbYXR0ci5pZF09XCInbmctbGlnaHRib3gtaW1hZ2UtJyArIGlcIlxyXG4gICAgICAgICAgICAgICAgICAgICh0b3VjaHN0YXJ0KT1cInN3aXBlTGlnaHRib3hJbWcoJGV2ZW50LCAnc3RhcnQnKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKHRvdWNoZW5kKT1cInN3aXBlTGlnaHRib3hJbWcoJGV2ZW50LCAnZW5kJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICNsaWdodGJveEltYWdlRGl2PlxyXG4gICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNsb3NlLW91dHNpZGVcIiAoY2xpY2spPVwiIWltZz8udmlkZW8gJiYgY2xvc2VMaWdodGJveCgpXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGN1c3RvbS1pbWdcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlVXJsXT1cImltZz8uaW1hZ2UgfHwgaW1nPy52aWRlb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpc1ZpZGVvXT1cIiEhKGltZz8ucG9zdGVySW1hZ2UgfHwgaW1nPy52aWRlbylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbY3VycmVudEltYWdlSW5kZXhdPVwiY3VycmVudEltYWdlSW5kZXhcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VJbmRleF09XCJpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3NwZWVkXT1cInNwZWVkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3ZpZGVvQXV0b1BsYXldPVwidmlkZW9BdXRvUGxheSAmJiBpID09IGN1cnJlbnRJbWFnZUluZGV4XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dWaWRlb0NvbnRyb2xzXT1cInNob3dWaWRlb0NvbnRyb2xzID8gMSA6IDBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbYWx0XT1cImltZz8uYWx0IHx8IGltZz8udGl0bGUgfHwgJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiaW1nPy50aXRsZSB8fCBpbWc/LmFsdCB8fCAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VmlkZW9dPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXJlY3Rpb25dPVwiZGlyZWN0aW9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9jdXN0b20taW1nPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IFtkaXJdPVwiZGlyZWN0aW9uXCIgW25nQ2xhc3NdPVwieydzaG93JzogdGl0bGUsICdoaWRlJzogIXRpdGxlfVwiIGNsYXNzPVwiY2FwdGlvblwiPnt7IHRpdGxlIH19PC9kaXY+XHJcbiAgICAgICAgICAgIDxhICpuZ0lmPVwiaW1hZ2VzLmxlbmd0aCA+IDFcIiBbbmdDbGFzc109XCJ7J2Rpc2FibGUnOiBsaWdodGJveFByZXZEaXNhYmxlfVwiIGNsYXNzPVwicHJldiBpY29ucyBwcmV2LWljb25cIiAoY2xpY2spPVwicHJldkltYWdlTGlnaHRib3goKVwiPiZsc2FxdW87PC9hPlxyXG4gICAgICAgICAgICA8YSAqbmdJZj1cImltYWdlcy5sZW5ndGggPiAxXCIgW25nQ2xhc3NdPVwieydkaXNhYmxlJzogbGlnaHRib3hOZXh0RGlzYWJsZX1cIiBjbGFzcz1cIm5leHQgaWNvbnMgbmV4dC1pY29uXCIgKGNsaWNrKT1cIm5leHRJbWFnZUxpZ2h0Ym94KClcIj4mcnNhcXVvOzwvYT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiAqbmdJZj1cInBhZ2luYXRpb25TaG93XCIgY2xhc3M9XCJwb3B1cC1wYWdpbmF0aW9uXCI+e3tjdXJyZW50SW1hZ2VJbmRleCArIDF9fSBvZiB7e3RvdGFsSW1hZ2VzfX08L2Rpdj5cclxuPC9kaXY+XHJcbiJdfQ==