UNPKG

ngx-img-zoom-viewer

Version:

The NGX IMG Zoom Viewer is a Angular library that can help to create a magnified preview of any image in any kind of angular app

210 lines (206 loc) 34.8 kB
import { DOCUMENT } from '@angular/common'; import { Component, HostListener, Input, Inject, } from '@angular/core'; import * as i0 from "@angular/core"; export class NGXImgZoomViewerComponent { constructor(el, renderer, document) { this.el = el; this.renderer = renderer; this.providedPreviewBox = { height: 350, width: 350 }; this.defaultConfigs = { imgHeight: 500, megnification: 2.5, priviewBoxSize: { height: 350, width: 350, }, }; this.cursorSize = { height: 0, width: 0 }; this._src = ''; this.cursorPosition = { x: 0, y: 0 }; this.host = this.renderer.createElement('div'); this.document = document; this.renderer.addClass(this.host, 'image_container'); this.renderer.appendChild(el.nativeElement, this.host); // assigning host } set src(srcValue) { if (typeof srcValue === 'string') { this._src = srcValue; this.createImage(); } else { console.error('src must be of type string, current type found ' + typeof srcValue); } } ngOnChanges(changes) { this.defaultConfigs.imgHeight = this.config?.imgHeight ?? this.defaultConfigs.imgHeight; this.defaultConfigs.megnification = this.config?.megnification ?? this.defaultConfigs.megnification; this.defaultConfigs.priviewBoxSize.height = this.config?.priviewBoxSize?.height ?? this.defaultConfigs.priviewBoxSize.height; if (this.defaultConfigs.priviewBoxSize.height + 20 > window.innerHeight) { this.defaultConfigs.priviewBoxSize.height = window.innerHeight - 20; } this.defaultConfigs.priviewBoxSize.width = this.defaultConfigs.priviewBoxSize.height; this.providedPreviewBox = { ...this.defaultConfigs.priviewBoxSize }; this.createImage(); } ngOnInit() { if (!this._src) console.error('unable to read src attribute'); } onMouseLeave(e) { if (this.cursorSize.width < 50 && this.cursorSize.height > 50) return; this.renderer.removeChild(this.host, this.cursor); this.renderer.removeChild(this.document, this.img_preview); } onMouseEnter(e) { this.checkwidth(); if (this.cursorSize.width < 50 && this.cursorSize.height > 50) return; if (this.host.children.length > 1) { this.onMouseLeave(e); } if (this.document.getElementById('ngx-img-zoom-viewer')) { this.renderer.removeChild(this.document, this.document.getElementById('ngx-img-zoom-viewer')); this.renderer.removeChild(this.document, this.document.getElementById('ngx-img-zoom-cursor')); } this.cursor = this.renderer.createElement('div'); this.renderer.addClass(this.cursor, 'cursor'); this.renderer.setStyle(this.cursor, `height`, `${this.cursorSize?.height}px`); this.renderer.setStyle(this.cursor, `width`, `${this.cursorSize?.width}px`); this.renderer.setAttribute(this.cursor, 'id', 'ngx-img-zoom-cursor'); this.renderer.appendChild(this.host, this.cursor); this.setCursorPosition(e); this.img_preview = this.renderer.createElement('div'); this.renderer.addClass(this.img_preview, 'img_preview'); this.renderer.setStyle(this.img_preview, 'height', `${this.defaultConfigs.priviewBoxSize.height}px`); this.renderer.setStyle(this.img_preview, 'width', `${this.defaultConfigs.priviewBoxSize.width}px`); this.renderer.setStyle(this.img_preview, 'left', `${window.innerWidth - 10 - this.defaultConfigs.priviewBoxSize.width}px`); this.renderer.setAttribute(this.img_preview, 'id', 'ngx-img-zoom-viewer'); this.renderer.appendChild(this.host.ownerDocument.lastChild?.lastChild, this.img_preview); } onMouseMove(e) { if (this.cursorSize.width < 50 && this.cursorSize.height > 50) return; this.setCursorPosition(e); this.setImgPreview(e); } setCursorPosition(e) { /* handling Left & top position for cursor box */ const imagex = this.image.getBoundingClientRect().x; const imagey = this.image.getBoundingClientRect().y; let cursorPosition = { x: e.pageX - this.cursorSize?.width / 2 - imagex >= 0 // checking if cursor box left is less then 0 ? e.pageX - this.cursorSize?.width / 2 - imagex : 0, y: e.pageY - this.cursorSize?.height / 2 - imagey >= 0 // checking if cursor box top is less then 0 ? e.pageY - this.cursorSize?.height / 2 - imagey : 0, // making sure if it is then only take 0 not negative value }; /* handling bottom & right position for cursor box */ if (cursorPosition.x + this.cursorSize?.width > this.image.offsetWidth) { // checking if cursor left + cursor width is greater then image width // making sure that any single pixel of cursor box can't go out from image respective on width cursorPosition.x = this.image.offsetWidth - this.cursorSize?.width; } if (cursorPosition.y + this.cursorSize?.height > this.image.offsetHeight) { // making sure that any single pixel of cursor box can't go out from image respective on height cursorPosition.y = this.image.offsetHeight - this.cursorSize?.height; } /* setting final value */ this.renderer.setStyle(this.cursor, 'top', `${cursorPosition.y}px`); // setting cursor box position for y axis this.renderer.setStyle(this.cursor, 'left', `${cursorPosition.x}px`); // setting cursor box position for x axis this.cursorPosition = cursorPosition; // saving data to global variable } setImgPreview(e) { const zoomedImage = this.renderer.createElement('img'); // created new local image element this.renderer.setAttribute(zoomedImage, 'src', this._src); // setting src for local image element this.renderer.setStyle(zoomedImage, 'height', `${this.image.offsetHeight * this.defaultConfigs.megnification}px`); // changed zoomed image height based on real image this.renderer.setStyle(zoomedImage, 'width', `${this.image.offsetWidth * this.defaultConfigs.megnification}px`); // changed zoomed image width based on real image this.renderer.setStyle(zoomedImage, 'top', `-${this.cursorPosition.y * this.defaultConfigs.megnification}px`); // changed zoomed image position based on cursor position this.renderer.setStyle(zoomedImage, 'left', `-${this.cursorPosition.x * this.defaultConfigs.megnification}px`); // changed zoomed image position based on cursor position this.img_preview.innerHTML = ''; this.renderer.appendChild(this.img_preview, zoomedImage); // added image into img_preview box } createImage() { this.host.innerHTML = ''; this.image = this.renderer.createElement('img'); this.renderer.setAttribute(this.image, 'src', this._src); this.renderer.addClass(this.image, 'main_image'); this.renderer.setStyle(this.image, 'max-height', this.defaultConfigs.imgHeight + 'px'); this.renderer.appendChild(this.host, this.image); } checkwidth() { this.defaultConfigs.priviewBoxSize.width = this.providedPreviewBox.width; const def = this.image.getBoundingClientRect().x + this.image.width + this.defaultConfigs.priviewBoxSize.width + 20 - window.innerWidth; if (def >= 0) { this.defaultConfigs.priviewBoxSize.width = this.defaultConfigs.priviewBoxSize.width - def - 30; } this.cursorSize.height = this.defaultConfigs.priviewBoxSize.height / this.defaultConfigs.megnification; this.cursorSize.width = this.defaultConfigs.priviewBoxSize.width / this.defaultConfigs.megnification; } } NGXImgZoomViewerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.3", ngImport: i0, type: NGXImgZoomViewerComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); NGXImgZoomViewerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.3", type: NGXImgZoomViewerComponent, selector: "ngx-img-zoom-viewer", inputs: { config: "config", src: "src" }, host: { listeners: { "mouseleave": "onMouseLeave($event)", "mouseenter": "onMouseEnter($event)", "mousemove": "onMouseMove($event)" } }, usesOnChanges: true, ngImport: i0, template: ``, isInline: true, styles: [".image_container{position:relative;display:inline-block}.image_container img{width:100%}.cursor{position:absolute;background-color:#ffffff80}.img_preview{position:fixed;z-index:1000;top:10px;right:10px;overflow:hidden}.img_preview img{position:absolute}\n"] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.3", ngImport: i0, type: NGXImgZoomViewerComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-img-zoom-viewer', template: ``, styles: [ ` .image_container { position: relative; display: inline-block; } .image_container img { width: 100%; } .cursor { position: absolute; background-color: rgba(255, 255, 255, 0.5); } .img_preview { position: fixed; z-index: 1000; top: 10px; right: 10px; overflow: hidden; } .img_preview img { position: absolute; } `, ], }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }]; }, propDecorators: { config: [{ type: Input }], src: [{ type: Input }], onMouseLeave: [{ type: HostListener, args: ['mouseleave', ['$event']] }], onMouseEnter: [{ type: HostListener, args: ['mouseenter', ['$event']] }], onMouseMove: [{ type: HostListener, args: ['mousemove', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltZy16b29tLXZpZXdlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtaW1nLXpvb20tdmlld2VyL3NyYy9saWIvbmd4LWltZy16b29tLXZpZXdlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFDTCxTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFLTCxNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7O0FBMkN2QixNQUFNLE9BQU8seUJBQXlCO0lBMkNwQyxZQUNVLEVBQWMsRUFDZCxRQUFtQixFQUNULFFBQWtCO1FBRjVCLE9BQUUsR0FBRixFQUFFLENBQVk7UUFDZCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBM0JyQix1QkFBa0IsR0FHdEIsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUV4QixtQkFBYyxHQUFHO1lBQ3ZCLFNBQVMsRUFBRSxHQUFHO1lBQ2QsYUFBYSxFQUFFLEdBQUc7WUFDbEIsY0FBYyxFQUFFO2dCQUNkLE1BQU0sRUFBRSxHQUFHO2dCQUNYLEtBQUssRUFBRSxHQUFHO2FBQ1g7U0FDRixDQUFDO1FBSU0sZUFBVSxHQUdkLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFFcEIsU0FBSSxHQUFXLEVBQUUsQ0FBQztRQUVsQixtQkFBYyxHQUE2QixFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBT2hFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFD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c0JBRG5CLFlBQVk7dUJBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVE5QixZQUFZO3NCQURuQixZQUFZO3VCQUFDLFlBQVksRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFxRDlCLFdBQVc7c0JBRGxCLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBPbkluaXQsXG4gIFJlbmRlcmVyMixcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBJbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIGltZ1pvb21WaWV3ZXJDb25maWcge1xuICBpbWdIZWlnaHQ/OiBudW1iZXI7XG4gIG1lZ25pZmljYXRpb24/OiBudW1iZXI7XG4gIHByaXZpZXdCb3hTaXplPzoge1xuICAgIGhlaWdodD86IG51bWJlcjtcbiAgfTtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWltZy16b29tLXZpZXdlcicsXG4gIHRlbXBsYXRlOiBgYCxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgLmltYWdlX2NvbnRhaW5lciB7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgICAgfVxuXG4gICAgICAuaW1hZ2VfY29udGFpbmVyIGltZyB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgfVxuXG4gICAgICAuY3Vyc29yIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSk7XG4gICAgICB9XG5cbiAgICAgIC5pbWdfcHJldmlldyB7XG4gICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgICAgei1pbmRleDogMTAwMDtcbiAgICAgICAgdG9wOiAxMHB4O1xuICAgICAgICByaWdodDogMTBweDtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIH1cblxuICAgICAgLmltZ19wcmV2aWV3IGltZyB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIH1cbiAgICBgLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBOR1hJbWdab29tVmlld2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBwcml2YXRlIGhvc3Q6IEhUTUxFbGVtZW50OyAvLyBBY2Nlc3MgZm9yIEhvc3QgRWxlbWVudFxuICBwcml2YXRlIGltYWdlITogSFRNTEltYWdlRWxlbWVudDsgLy8gSW1hZ2UgRWxlbWVudFxuICBwcml2YXRlIGN1cnNvciE6IEhUTUxEaXZFbGVtZW50OyAvLyBDdXJzb3IgRWxlbWVudFxuICBwcml2YXRlIGltZ19wcmV2aWV3ITogSFRNTERpdkVsZW1lbnQ7IC8vIEltYWdlIFByZXZpZXcgRWxlbWVudFxuXG4gIEBJbnB1dCgpIGNvbmZpZz86IGltZ1pvb21WaWV3ZXJDb25maWc7XG4gIEBJbnB1dCgpIHNldCBzcmMoc3JjVmFsdWU6IHN0cmluZykge1xuICAgIGlmICh0eXBlb2Ygc3JjVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLl9zcmMgPSBzcmNWYWx1ZTtcbiAgICAgIHRoaXMuY3JlYXRlSW1hZ2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgJ3NyYyBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLCBjdXJyZW50IHR5cGUgZm91bmQgJyArIHR5cGVvZiBzcmNWYWx1ZVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByb3ZpZGVkUHJldmlld0JveDoge1xuICAgIGhlaWdodDogbnVtYmVyO1xuICAgIHdpZHRoOiBudW1iZXI7XG4gIH0gPSB7IGhlaWdodDogMzUwLCB3aWR0aDogMzUwIH07XG5cbiAgcHJpdmF0ZSBkZWZhdWx0Q29uZmlncyA9IHtcbiAgICBpbWdIZWlnaHQ6IDUwMCxcbiAgICBtZWduaWZpY2F0aW9uOiAyLjUsXG4gICAgcHJpdmlld0JveFNpemU6IHtcbiAgICAgIGhlaWdodDogMzUwLFxuICAgICAgd2lkdGg6IDM1MCxcbiAgICB9LFxuICB9O1xuXG4gIGRvY3VtZW50OiBEb2N1bWVudDtcblxuICBwcml2YXRlIGN1cnNvclNpemU6IHtcbiAgICBoZWlnaHQ6IG51bWJlcjtcbiAgICB3aWR0aDogbnVtYmVyO1xuICB9ID0geyBoZWlnaHQ6IDAsIHdpZHRoOiAwIH07XG5cbiAgcHJpdmF0ZSBfc3JjOiBzdHJpbmcgPSAnJztcblxuICBwcml2YXRlIGN1cnNvclBvc2l0aW9uOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gPSB7IHg6IDAsIHk6IDAgfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBkb2N1bWVudDogRG9jdW1lbnRcbiAgKSB7XG4gICAgdGhpcy5ob3N0ID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmhvc3QsICdpbWFnZV9jb250YWluZXInKTtcbiAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKGVsLm5hdGl2ZUVsZW1lbnQsIHRoaXMuaG9zdCk7IC8vIGFzc2lnbmluZyBob3N0XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgdGhpcy5kZWZhdWx0Q29uZmlncy5pbWdIZWlnaHQgPVxuICAgICAgdGhpcy5jb25maWc/LmltZ0hlaWdodCA/PyB0aGlzLmRlZmF1bHRDb25maWdzLmltZ0hlaWdodDtcblxuICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MubWVnbmlmaWNhdGlvbiA9XG4gICAgICB0aGlzLmNvbmZpZz8ubWVnbmlmaWNhdGlvbiA/PyB0aGlzLmRlZmF1bHRDb25maWdzLm1lZ25pZmljYXRpb247XG5cbiAgICB0aGlzLmRlZmF1bHRDb25maWdzLnByaXZpZXdCb3hTaXplLmhlaWdodCA9XG4gICAgICB0aGlzLmNvbmZpZz8ucHJpdmlld0JveFNpemU/LmhlaWdodCA/P1xuICAgICAgdGhpcy5kZWZhdWx0Q29uZmlncy5wcml2aWV3Qm94U2l6ZS5oZWlnaHQ7XG5cbiAgICBpZiAodGhpcy5kZWZhdWx0Q29uZmlncy5wcml2aWV3Qm94U2l6ZS5oZWlnaHQgKyAyMCA+IHdpbmRvdy5pbm5lckhlaWdodCkge1xuICAgICAgdGhpcy5kZWZhdWx0Q29uZmlncy5wcml2aWV3Qm94U2l6ZS5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgLSAyMDtcbiAgICB9XG5cbiAgICB0aGlzLmRlZmF1bHRDb25maWdzLnByaXZpZXdCb3hTaXplLndpZHRoID1cbiAgICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MucHJpdmlld0JveFNpemUuaGVpZ2h0O1xuICAgIHRoaXMucHJvdmlkZWRQcmV2aWV3Qm94ID0geyAuLi50aGlzLmRlZmF1bHRDb25maWdzLnByaXZpZXdCb3hTaXplIH07XG4gICAgdGhpcy5jcmVhdGVJbWFnZSgpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl9zcmMpIGNvbnNvbGUuZXJyb3IoJ3VuYWJsZSB0byByZWFkIHNyYyBhdHRyaWJ1dGUnKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBbJyRldmVudCddKVxuICBwcml2YXRlIG9uTW91c2VMZWF2ZShlOiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKHRoaXMuY3Vyc29yU2l6ZS53aWR0aCA8IDUwICYmIHRoaXMuY3Vyc29yU2l6ZS5oZWlnaHQgPiA1MCkgcmV0dXJuO1xuICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2hpbGQodGhpcy5ob3N0LCB0aGlzLmN1cnNvcik7XG4gICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDaGlsZCh0aGlzLmRvY3VtZW50LCB0aGlzLmltZ19wcmV2aWV3KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBbJyRldmVudCddKVxuICBwcml2YXRlIG9uTW91c2VFbnRlcihlOiBNb3VzZUV2ZW50KSB7XG4gICAgdGhpcy5jaGVja3dpZHRoKCk7XG4gICAgaWYgKHRoaXMuY3Vyc29yU2l6ZS53aWR0aCA8IDUwICYmIHRoaXMuY3Vyc29yU2l6ZS5oZWlnaHQgPiA1MCkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmhvc3QuY2hpbGRyZW4ubGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5vbk1vdXNlTGVhdmUoZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZ3gtaW1nLXpvb20tdmlld2VyJykpIHtcbiAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2hpbGQoXG4gICAgICAgIHRoaXMuZG9jdW1lbnQsXG4gICAgICAgIHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25neC1pbWctem9vbS12aWV3ZXInKVxuICAgICAgKTtcbiAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2hpbGQoXG4gICAgICAgIHRoaXMuZG9jdW1lbnQsXG4gICAgICAgIHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25neC1pbWctem9vbS1jdXJzb3InKVxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5jdXJzb3IgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5jdXJzb3IsICdjdXJzb3InKTtcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgdGhpcy5jdXJzb3IsXG4gICAgICBgaGVpZ2h0YCxcbiAgICAgIGAke3RoaXMuY3Vyc29yU2l6ZT8uaGVpZ2h0fXB4YFxuICAgICk7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmN1cnNvciwgYHdpZHRoYCwgYCR7dGhpcy5jdXJzb3JTaXplPy53aWR0aH1weGApO1xuICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMuY3Vyc29yLCAnaWQnLCAnbmd4LWltZy16b29tLWN1cnNvcicpO1xuICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5ob3N0LCB0aGlzLmN1cnNvcik7XG4gICAgdGhpcy5zZXRDdXJzb3JQb3NpdGlvbihlKTtcblxuICAgIHRoaXMuaW1nX3ByZXZpZXcgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5pbWdfcHJldmlldywgJ2ltZ19wcmV2aWV3Jyk7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgIHRoaXMuaW1nX3ByZXZpZXcsXG4gICAgICAnaGVpZ2h0JyxcbiAgICAgIGAke3RoaXMuZGVmYXVsdENvbmZpZ3MucHJpdmlld0JveFNpemUuaGVpZ2h0fXB4YFxuICAgICk7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgIHRoaXMuaW1nX3ByZXZpZXcsXG4gICAgICAnd2lkdGgnLFxuICAgICAgYCR7dGhpcy5kZWZhdWx0Q29uZmlncy5wcml2aWV3Qm94U2l6ZS53aWR0aH1weGBcbiAgICApO1xuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICB0aGlzLmltZ19wcmV2aWV3LFxuICAgICAgJ2xlZnQnLFxuICAgICAgYCR7d2luZG93LmlubmVyV2lkdGggLSAxMCAtIHRoaXMuZGVmYXVsdENvbmZpZ3MucHJpdmlld0JveFNpemUud2lkdGh9cHhgXG4gICAgKTtcbiAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0aGlzLmltZ19wcmV2aWV3LCAnaWQnLCAnbmd4LWltZy16b29tLXZpZXdlcicpO1xuICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQoXG4gICAgICB0aGlzLmhvc3Qub3duZXJEb2N1bWVudC5sYXN0Q2hpbGQ/Lmxhc3RDaGlsZCxcbiAgICAgIHRoaXMuaW1nX3ByZXZpZXdcbiAgICApO1xuICB9XG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbW92ZScsIFsnJGV2ZW50J10pXG4gIHByaXZhdGUgb25Nb3VzZU1vdmUoZTogTW91c2VFdmVudCkge1xuICAgIGlmICh0aGlzLmN1cnNvclNpemUud2lkdGggPCA1MCAmJiB0aGlzLmN1cnNvclNpemUuaGVpZ2h0ID4gNTApIHJldHVybjtcbiAgICB0aGlzLnNldEN1cnNvclBvc2l0aW9uKGUpO1xuICAgIHRoaXMuc2V0SW1nUHJldmlldyhlKTtcbiAgfVxuICBwcml2YXRlIHNldEN1cnNvclBvc2l0aW9uKGU6IE1vdXNlRXZlbnQpIHtcbiAgICAvKiBoYW5kbGluZyBMZWZ0ICYgdG9wIHBvc2l0aW9uIGZvciBjdXJzb3IgYm94ICovXG4gICAgY29uc3QgaW1hZ2V4ID0gdGhpcy5pbWFnZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS54O1xuICAgIGNvbnN0IGltYWdleSA9IHRoaXMuaW1hZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkueTtcbiAgICBsZXQgY3Vyc29yUG9zaXRpb24gPSB7XG4gICAgICB4OlxuICAgICAgICBlLnBhZ2VYIC0gdGhpcy5jdXJzb3JTaXplPy53aWR0aCAvIDIgLSBpbWFnZXggPj0gMCAvLyBjaGVja2luZyBpZiBjdXJzb3IgYm94IGxlZnQgaXMgbGVzcyB0aGVuIDBcbiAgICAgICAgICA/IGUucGFnZVggLSB0aGlzLmN1cnNvclNpemU/LndpZHRoIC8gMiAtIGltYWdleFxuICAgICAgICAgIDogMCwgLy8gbWFraW5nIHN1cmUgaWYgaXQgaXMgdGhlbiBvbmx5IHRha2UgMCBub3QgbmVnYXRpdmUgdmFsdWVcbiAgICAgIHk6XG4gICAgICAgIGUucGFnZVkgLSB0aGlzLmN1cnNvclNpemU/LmhlaWdodCAvIDIgLSBpbWFnZXkgPj0gMCAvLyBjaGVja2luZyBpZiBjdXJzb3IgYm94IHRvcCBpcyBsZXNzIHRoZW4gMFxuICAgICAgICAgID8gZS5wYWdlWSAtIHRoaXMuY3Vyc29yU2l6ZT8uaGVpZ2h0IC8gMiAtIGltYWdleVxuICAgICAgICAgIDogMCwgLy8gbWFraW5nIHN1cmUgaWYgaXQgaXMgdGhlbiBvbmx5IHRha2UgMCBub3QgbmVnYXRpdmUgdmFsdWVcbiAgICB9O1xuXG4gICAgLyogaGFuZGxpbmcgYm90dG9tICYgcmlnaHQgcG9zaXRpb24gZm9yIGN1cnNvciBib3ggKi9cbiAgICBpZiAoY3Vyc29yUG9zaXRpb24ueCArIHRoaXMuY3Vyc29yU2l6ZT8ud2lkdGggPiB0aGlzLmltYWdlLm9mZnNldFdpZHRoKSB7XG4gICAgICAvLyBjaGVja2luZyBpZiBjdXJzb3IgbGVmdCArIGN1cnNvciB3aWR0aCBpcyBncmVhdGVyIHRoZW4gaW1hZ2Ugd2lkdGhcbiAgICAgIC8vIG1ha2luZyBzdXJlIHRoYXQgYW55IHNpbmdsZSBwaXhlbCBvZiBjdXJzb3IgYm94IGNhbid0IGdvIG91dCBmcm9tIGltYWdlIHJlc3BlY3RpdmUgb24gd2lkdGhcbiAgICAgIGN1cnNvclBvc2l0aW9uLnggPSB0aGlzLmltYWdlLm9mZnNldFdpZHRoIC0gdGhpcy5jdXJzb3JTaXplPy53aWR0aDtcbiAgICB9XG4gICAgaWYgKGN1cnNvclBvc2l0aW9uLnkgKyB0aGlzLmN1cnNvclNpemU/LmhlaWdodCA+IHRoaXMuaW1hZ2Uub2Zmc2V0SGVpZ2h0KSB7XG4gICAgICAvLyBtYWtpbmcgc3VyZSB0aGF0IGFueSBzaW5nbGUgcGl4ZWwgb2YgY3Vyc29yIGJveCBjYW4ndCBnbyBvdXQgZnJvbSBpbWFnZSByZXNwZWN0aXZlIG9uIGhlaWdodFxuICAgICAgY3Vyc29yUG9zaXRpb24ueSA9IHRoaXMuaW1hZ2Uub2Zmc2V0SGVpZ2h0IC0gdGhpcy5jdXJzb3JTaXplPy5oZWlnaHQ7XG4gICAgfVxuXG4gICAgLyogc2V0dGluZyBmaW5hbCB2YWx1ZSAqL1xuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5jdXJzb3IsICd0b3AnLCBgJHtjdXJzb3JQb3NpdGlvbi55fXB4YCk7IC8vIHNldHRpbmcgY3Vyc29yIGJveCBwb3NpdGlvbiBmb3IgeSBheGlzXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmN1cnNvciwgJ2xlZnQnLCBgJHtjdXJzb3JQb3NpdGlvbi54fXB4YCk7IC8vIHNldHRpbmcgY3Vyc29yIGJveCBwb3NpdGlvbiBmb3IgeCBheGlzXG5cbiAgICB0aGlzLmN1cnNvclBvc2l0aW9uID0gY3Vyc29yUG9zaXRpb247IC8vIHNhdmluZyBkYXRhIHRvIGdsb2JhbCB2YXJpYWJsZVxuICB9XG4gIHByaXZhdGUgc2V0SW1nUHJldmlldyhlOiBNb3VzZUV2ZW50KSB7XG4gICAgY29uc3Qgem9vbWVkSW1hZ2UgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ2ltZycpOyAvLyBjcmVhdGVkIG5ldyBsb2NhbCBpbWFnZSBlbGVtZW50XG4gICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoem9vbWVkSW1hZ2UsICdzcmMnLCB0aGlzLl9zcmMpOyAvLyBzZXR0aW5nIHNyYyBmb3IgbG9jYWwgaW1hZ2UgZWxlbWVudFxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICB6b29tZWRJbWFnZSxcbiAgICAgICdoZWlnaHQnLFxuICAgICAgYCR7dGhpcy5pbWFnZS5vZmZzZXRIZWlnaHQgKiB0aGlzLmRlZmF1bHRDb25maWdzLm1lZ25pZmljYXRpb259cHhgXG4gICAgKTsgLy8gY2hhbmdlZCB6b29tZWQgaW1hZ2UgaGVpZ2h0IGJhc2VkIG9uIHJlYWwgaW1hZ2VcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgem9vbWVkSW1hZ2UsXG4gICAgICAnd2lkdGgnLFxuICAgICAgYCR7dGhpcy5pbWFnZS5vZmZzZXRXaWR0aCAqIHRoaXMuZGVmYXVsdENvbmZpZ3MubWVnbmlmaWNhdGlvbn1weGBcbiAgICApOyAvLyBjaGFuZ2VkIHpvb21lZCBpbWFnZSB3aWR0aCBiYXNlZCBvbiByZWFsIGltYWdlXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgIHpvb21lZEltYWdlLFxuICAgICAgJ3RvcCcsXG4gICAgICBgLSR7dGhpcy5jdXJzb3JQb3NpdGlvbi55ICogdGhpcy5kZWZhdWx0Q29uZmlncy5tZWduaWZpY2F0aW9ufXB4YFxuICAgICk7IC8vIGNoYW5nZWQgem9vbWVkIGltYWdlIHBvc2l0aW9uIGJhc2VkIG9uIGN1cnNvciBwb3NpdGlvblxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICB6b29tZWRJbWFnZSxcbiAgICAgICdsZWZ0JyxcbiAgICAgIGAtJHt0aGlzLmN1cnNvclBvc2l0aW9uLnggKiB0aGlzLmRlZmF1bHRDb25maWdzLm1lZ25pZmljYXRpb259cHhgXG4gICAgKTsgLy8gY2hhbmdlZCB6b29tZWQgaW1hZ2UgcG9zaXRpb24gYmFzZWQgb24gY3Vyc29yIHBvc2l0aW9uXG4gICAgdGhpcy5pbWdfcHJldmlldy5pbm5lckhUTUwgPSAnJztcbiAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHRoaXMuaW1nX3ByZXZpZXcsIHpvb21lZEltYWdlKTsgLy8gYWRkZWQgaW1hZ2UgaW50byBpbWdfcHJldmlldyBib3hcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlSW1hZ2UoKSB7XG4gICAgdGhpcy5ob3N0LmlubmVySFRNTCA9ICcnO1xuICAgIHRoaXMuaW1hZ2UgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMuaW1hZ2UsICdzcmMnLCB0aGlzLl9zcmMpO1xuICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5pbWFnZSwgJ21haW5faW1hZ2UnKTtcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgdGhpcy5pbWFnZSxcbiAgICAgICdtYXgtaGVpZ2h0JyxcbiAgICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MuaW1nSGVpZ2h0ICsgJ3B4J1xuICAgICk7XG4gICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmhvc3QsIHRoaXMuaW1hZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja3dpZHRoKCkge1xuICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MucHJpdmlld0JveFNpemUud2lkdGggPSB0aGlzLnByb3ZpZGVkUHJldmlld0JveC53aWR0aDtcbiAgICBjb25zdCBkZWYgPVxuICAgICAgdGhpcy5pbWFnZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS54ICtcbiAgICAgIHRoaXMuaW1hZ2Uud2lkdGggK1xuICAgICAgdGhpcy5kZWZhdWx0Q29uZmlncy5wcml2aWV3Qm94U2l6ZS53aWR0aCArXG4gICAgICAyMCAtXG4gICAgICB3aW5kb3cuaW5uZXJXaWR0aDtcblxuICAgIGlmIChkZWYgPj0gMCkge1xuICAgICAgdGhpcy5kZWZhdWx0Q29uZmlncy5wcml2aWV3Qm94U2l6ZS53aWR0aCA9XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MucHJpdmlld0JveFNpemUud2lkdGggLSBkZWYgLSAzMDtcbiAgICB9XG5cbiAgICB0aGlzLmN1cnNvclNpemUuaGVpZ2h0ID1cbiAgICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MucHJpdmlld0JveFNpemUuaGVpZ2h0IC9cbiAgICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MubWVnbmlmaWNhdGlvbjtcblxuICAgIHRoaXMuY3Vyc29yU2l6ZS53aWR0aCA9XG4gICAgICB0aGlzLmRlZmF1bHRDb25maWdzLnByaXZpZXdCb3hTaXplLndpZHRoIC9cbiAgICAgIHRoaXMuZGVmYXVsdENvbmZpZ3MubWVnbmlmaWNhdGlvbjtcbiAgfVxufVxuIl19