UNPKG

ngx-extended-pdf-viewer

Version:

Embedding PDF files in your Angular application. Highly configurable viewer including the toolbar, sidebar, and all the features you're used to.

1,012 lines 178 kB
export class RelativeCoordsSupport {
    constructor(_zone, component, options) {
        this._zone = _zone;
        this.component = component;
        this.options = {
            debug: false,
            moveEnabled: true,
            disableEventHandling: false,
        };
        this.startX = 0;
        this.startY = 0;
        this.moveX = 0;
        this.moveY = 0;
        this.startLeft = 0;
        this.startTop = 0;
        this.state = "idle";
        this.initialPinchDistance = 0;
        this.currentScale = 1.0;
        this.pointEnd = {};
        this.debug = {
            enabled: false,
            nf: new Intl.NumberFormat('en-US', { style: 'decimal', maximumFractionDigits: 2 }),
            x: 0,
            y: 0
        };
        options = options || {};
        Object.keys(this.options).forEach(attribut => {
            if (options[attribut] === undefined)
                options[attribut] = this.options[attribut];
        });
        this.options = options;
        this.debug.enabled = this.options.debug;
        if (this.debug.enabled)
            console.log("RelativeCoordsSupport.constructor");
        this.boundOnViewerTouchStart = this.onViewerTouchStart.bind(this);
        this.boundOnViewerTouchMove = this.onViewerTouchMove.bind(this);
        this.boundOnViewerTouchEnd = this.onViewerTouchEnd.bind(this);
        this.boundOnViewerMouseDown = this.onViewerMouseDown.bind(this);
        this.boundOnViewerMouseMove = this.onViewerMouseMove.bind(this);
        this.boundOnViewerMouseUp = this.onViewerMouseUp.bind(this);
        this.boundOnViewerWheel = this.onViewerWheel.bind(this);
        this.initializeRelativeCoords();
    }
    isMobile() {
        return (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0); // ('ontouchstart' in window) || 
    }
    onViewerTouchStart(event) {
        if (this.options.disableEventHandling)
            return;
        this.initialPinchDistance = 0;
        if (event.touches.length === 2) {
            const container = document.getElementById('viewerContainer');
            const rect = container.getBoundingClientRect();
            if (event.touches[0].pageX >= rect.left && event.touches[0].pageX <= rect.right) {
                if (event.touches[0].pageY >= (rect.top + window.scrollY) && event.touches[0].pageY <= (rect.bottom + window.scrollY)) {
                    if (event.touches[1].pageX >= rect.left && event.touches[1].pageX <= rect.right) {
                        if (event.touches[1].pageY >= (rect.top + window.scrollY) && event.touches[1].pageY <= (rect.bottom + window.scrollY)) {
                            this.startX = (event.touches[0].pageX + event.touches[1].pageX) / 2;
                            this.startY = (event.touches[0].pageY + event.touches[1].pageY) / 2;
                            this.initialPinchDistance = Math.hypot(event.touches[1].pageX - event.touches[0].pageX, event.touches[1].pageY - event.touches[0].pageY);
                            this.startLeft = parseFloat(getComputedStyle(this.viewer).left) || 0;
                            this.startTop = parseFloat(getComputedStyle(this.viewer).top) || 0;
                            this.state = "zoom";
                            if (event.cancelable) {
                                event.preventDefault();
                            }
                            event.stopPropagation();
                        }
                    }
                }
            }
        }
        if (event.touches.length === 1) {
            let touch = event.touches[0];
            if (this.options.moveEnabled && this.isInsideContainer([touch]) && this.state == "idle") {
                const viewerContainer = document.getElementById('viewerContainer');
                const rect = viewerContainer.getBoundingClientRect();
                let pageX = touch.pageX - rect.left;
                let pageY = touch.pageY - rect.top;
                if (this.debug.enabled)
                    this.debugPoint(pageX, pageY);
                this.startX = pageX;
                this.startY = pageY;
                let left = parseFloat(getComputedStyle(this.viewer).left) || 0;
                let top = parseFloat(getComputedStyle(this.viewer).top) || 0;
                if (this.debug.enabled) {
                    console.log("TouchStart: "
                        + this.debug.nf.format(pageX) + " / " + this.debug.nf.format(pageY)
                        + ", startX/Y: " + this.debug.nf.format(this.startX) + " / " + this.debug.nf.format(this.startY)
                        + ", startLeft/Top: " + this.debug.nf.format(this.startLeft) + " -> " + this.debug.nf.format(left) + " / " + this.debug.nf.format(this.startTop) + " -> " + this.debug.nf.format(top)
                        + ", state: " + this.state, ", dims: ", this.getDimensions(this.viewer));
                }
                this.startLeft = left;
                this.startTop = top;
                this.state = "move";
                if (event.cancelable) {
                    event.preventDefault();
                }
                event.stopPropagation();
            }
            else {
                // console.log("TouchStart: isInside: " +  this.isInsideContainer([ touch ]) + ", state: " + this.state);
            }
        }
    }
    // private getCurrentPagesInView():number[] {
    //   const PDFViewerApplication: any = (window as any).PDFViewerApplication;
    //   let page = PDFViewerApplication.page;
    //   let pageCount = PDFViewerApplication.pdfViewer._pages.length;
    //   let spreadMode = PDFViewerApplication.pdfViewer.spreadMode as SpreadModeType;
    //   let pages = [ page ];
    //   if (page == 1) return pages;
    //   let isSpread = spreadMode == SpreadModeType.EVEN || SpreadModeType.ODD;
    //   // console.log("isSpread: " + isSpread+ ", pages: " + pages.join(","));
    //   if (!isSpread) return pages;
    //   if (page % 2 == 1) {
    //     page--;
    //     pages = [ page ];
    //   }
    //   // if (page % 2 == 1)
    //   let nextPage = page + 1;
    //   if (nextPage <= pageCount) pages.push(nextPage);
    //   // console.log("nextPage: " + nextPage + ", pageCount: " + pageCount+ ", pages: " + pages.join(","));
    //   return  pages;
    // }
    debugPoint(x, y, viewer = false) {
        if (!this.options.debugPoint)
            return;
        const viewerContainer = document.getElementById('viewerContainer');
        let id = 'debug-point' + (viewer ? "-viewer" : "");
        let point = document.getElementById(id);
        let size = viewer ? 10 : 5;
        if (!point) {
            point = document.createElement("div");
            point.id = id;
            point.style.position = "absolute";
            point.style.width = size + "px";
            point.style.height = size + "px";
            point.style.borderRadius = "100px";
            point.style.backgroundColor = viewer ? "red" : "blue";
            if (!viewer)
                viewerContainer.appendChild(point);
            else
                this.viewer.appendChild(point);
        }
        let dims = this.getDimensions(this.viewer);
        if (viewer) {
            // this.debug.xv = x;
            // this.debug.yv = y;
            // console.log("debugPoint.viewer: " + this.debug.nf.format(x) + " / " + this.debug.nf.format(y) + ", | " + this.debug.nf.format(x / dims.elem.width * 100) + " % / " + this.debug.nf.format(y / dims.elem.height * 100) + " %, dims: ", dims.elem);
            // let vts = this.getViewerTransformScale();
            // if(vts != 1.0) {
            //   x /= vts;
            //   y /= vts;
            //   console.log("debugPoint.viewer: " + this.debug.nf.format(x) + " / " + this.debug.nf.format(y));
            // }
        }
        else {
            this.debug.x = x;
            this.debug.y = y;
            // console.log("debugPoint.cont: " + this.debug.nf.format(x) + " / " + this.debug.nf.format(y) + " | " + this.debug.nf.format(x / dims.parent.width * 100) + " % /  " + this.debug.nf.format(y / dims.parent.height * 100) + " %, dims: ", dims.parent);
        }
        point.style.left = (x - (size / 2)) + "px";
        point.style.top = (y - (size / 2)) + "px";
    }
    onViewerTouchMove(event) {
        if (this.options.disableEventHandling)
            return;
        const PDFViewerApplicationOptions = window.PDFViewerApplicationOptions;
        const PDFViewerApplication = window.PDFViewerApplication;
        const viewerContainer = document.getElementById('viewerContainer');
        const rect = viewerContainer.getBoundingClientRect();
        const vr = this.viewer.getBoundingClientRect();
        if (this.initialPinchDistance <= 0 || event.touches.length !== 2) {
            if (event.touches.length == 1 && this.state == "move") {
                const touch = event.touches[0];
                let pageX = touch.pageX - rect.left + viewerContainer.scrollLeft;
                let pageY = touch.pageY - rect.top + viewerContainer.scrollTop;
                if (this.debug.enabled)
                    this.debugPoint(pageX, pageY);
                let diffX = pageX - this.startX;
                let diffY = pageY - this.startY;
                let left = this.startLeft + diffX;
                let top = this.startTop + diffY;
                let constrain = this.constrain({ left: left, top: top });
                left = constrain.left;
                top = constrain.top;
                if (this.debug.enabled) {
                    console.log("TouchMove: "
                        + this.debug.nf.format(pageX) + " / " + this.debug.nf.format(pageY)
                        + ", startX/Y: " + this.debug.nf.format(this.startX) + " / " + this.debug.nf.format(this.startY)
                        + ", diff: " + this.debug.nf.format(diffX) + " / " + this.debug.nf.format(diffY)
                        + ", l/t: " + this.debug.nf.format(left) + " / " + this.debug.nf.format(top)
                        + ", viewer.w/h: " + this.debug.nf.format(vr.width) + " / " + this.debug.nf.format(vr.height));
                }
                this.viewer.style.left = left + "px";
                this.viewer.style.top = top + "px";
                if (event.cancelable) {
                    event.preventDefault();
                }
                event.stopPropagation();
            }
            return;
        }
        const pinchDistance = Math.hypot(event.touches[1].pageX - event.touches[0].pageX, event.touches[1].pageY - event.touches[0].pageY);
        // const container = document.getElementById('viewerContainer') as HTMLDivElement;
        // const containerRect = container.getBoundingClientRect();
        let pageX = (event.touches[1].pageX + event.touches[0].pageX) / 2;
        let pageY = (event.touches[1].pageY + event.touches[0].pageY) / 2;
        this.moveX = pageX;
        this.moveY = pageY;
        let dims = this.getDimensions(this.viewer, { pageX: pageX, pageY: pageY });
        // //const viewerRect = this.viewer.getBoundingClientRect();
        // pageX -= rect.left;
        // pageY -= rect.top;
        // pageX -= vr.left;
        // pageY -= vr.top;
        // pageX = dims.scaled.width * dims.point.v.xp;
        // pageY = dims.scaled.height * dims.point.v.yp;
        // let originX = pageX; // + viewerContainer.scrollLeft; // this.startX + container.scrollLeft;
        // let originY = pageY; // + viewerContainer.scrollTop ; //this.startY + container.scrollTop;
        const originX = dims.scaled.width * dims.point.v.xp;
        const originY = dims.scaled.height * dims.point.v.yp;
        if (this.debug.enabled)
            this.debugPoint(this.moveX - rect.left, this.moveY - rect.top);
        let prevScale = this.currentScale;
        this.currentScale = pinchDistance / this.initialPinchDistance;
        let minZoom = Number(PDFViewerApplicationOptions.get('minZoom'));
        if (!minZoom) {
            minZoom = 0.1;
        }
        const currentZoom = PDFViewerApplication.pdfViewer._currentScale;
        if (currentZoom * this.currentScale < minZoom) {
            this.currentScale = minZoom / currentZoom;
        }
        let maxZoom = Number(PDFViewerApplicationOptions.get('maxZoom'));
        if (!maxZoom) {
            maxZoom = 10;
        }
        if (currentZoom * this.currentScale > maxZoom) {
            this.currentScale = maxZoom / currentZoom;
        }
        if (this.debug.enabled) {
            console.log("TouchMove PINCH: "
                + ", startX/Y: " + this.debug.nf.format(this.startX) + " / " + this.debug.nf.format(this.startY)
                + ", moveX/Y: " + +this.debug.nf.format(this.moveX) + " / " + this.debug.nf.format(this.moveY)
                + ", rect.l/t: " + this.debug.nf.format(rect.left) + " / " + this.debug.nf.format(rect.top)
                + ", viewer.l/t: " + this.debug.nf.format(vr.left) + " / " + this.debug.nf.format(vr.top)
                // + ", viewerContainer.sl/st: " + this.debug.nf.format(viewerContainer.scrollLeft) + " / " + this.debug.nf.format(viewerContainer.scrollTop)
                + ", originX/Y: " + this.debug.nf.format(originX) + " / " + this.debug.nf.format(originY)
                + ", viewer.w/h: " + this.debug.nf.format(vr.width) + " / " + this.debug.nf.format(vr.height)
                + ", currentScale: " + this.debug.nf.format(prevScale) + " -> " + this.debug.nf.format(this.currentScale)
                + ", dims: ", dims);
        }
        this.viewer.style.transform = `scale(${this.currentScale})`;
        this.viewer.style.transformOrigin = `${originX}px ${originY}px`;
        // this.transformScale = this.currentScale;
        if (event.cancelable) {
            event.preventDefault();
        }
        event.stopPropagation();
    }
    onViewerTouchEnd(event) {
        if (this.options.disableEventHandling)
            return;
        if (this.debug.enabled)
            console.log("onViewerTouchEnd"
                + ", vts: " + this.getViewerTransformScale("onViewerTouchEnd")
                + ', state: ' + this.state
                + ", initialPinchDistance: " + this.initialPinchDistance);
        const PDFViewerApplication = window.PDFViewerApplication;
        // let to = this.viewer.style.transformOrigin;
        // this.viewer.style.transform = `none`;
        // this.viewer.style.transformOrigin = `unset`;
        let dimsStart = this.getDimensions(this.viewer);
        let tl = event.changedTouches.length;
        let pageX = this.moveX;
        let pageY = this.moveY;
        if (tl > 1) {
            pageX = (event.changedTouches[1].pageX + event.changedTouches[0].pageX) / 2;
            pageY = (event.changedTouches[1].pageY + event.changedTouches[0].pageY) / 2;
        }
        else {
            if (this.debug.enabled)
                console.log("end.moveX/Y: " + this.moveX + " -> " + pageX + ", moveY: " + this.moveY + " -> " + pageY + ", tl: " + tl);
        }
        // this.currentScale = 1;
        let now = new Date().getTime();
        if (this.pointEnd.time) {
            let pe = this.pointEnd;
            let diff = now - pe.time;
            // console.log("pointEnd.diff: " + diff);
            if (pe.pageX == pageX && pe.pageY == pageY && diff < 300) {
                let PDFViewerApplication = window.PDFViewerApplication;
                let currentScale = PDFViewerApplication.pdfViewer.currentScale;
                let scaleFactor = 1.4;
                let newScale = this.isZooming() ? (currentScale / scaleFactor) : (currentScale * scaleFactor);
                // let newScale = currentScale * 1.2;
                // if (this.debug.enabled) console.log("pointEnd.point mateches, new scale: " + newScale);
                if (this.initialPinchDistance <= 0 || this.state == "move") {
                    if (event.cancelable) {
                        event.preventDefault();
                    }
                    event.stopPropagation();
                }
                setTimeout(() => {
                    this.setViewerScale(newScale);
                    this.pointEnd = {};
                }, 5);
                return;
            }
        }
        this.pointEnd = {
            time: now,
            pageX: pageX,
            pageY: pageY
        };
        if (this.state == "move") {
            this.resetPinchZoomParams();
            return;
        }
        if (this.initialPinchDistance <= 0) {
            this.resetPinchZoomParams();
            return;
        }
        let currentScale = PDFViewerApplication.pdfViewer.currentScale;
        let newScale = currentScale * this.currentScale;
        // let scaleChange = 1 + (newScale - currentScale) / currentScale;
        const container = document.getElementById('viewerContainer');
        const rect = container.getBoundingClientRect();
        const viewerRect = this.viewer.getBoundingClientRect();
        let dims = this.getDimensions(this.viewer);
        if (this.debug.enabled)
            this.debugPoint(pageX, pageY);
        if (this.debug.enabled) {
            console.log("TouchEnd: "
                + ", scale: " + this.debug.nf.format(currentScale) + " -> " + this.debug.nf.format(newScale) + ", cs: " + this.currentScale
                + ", pageX/Y: " + this.debug.nf.format(pageX) + " / " + this.debug.nf.format(pageY)
                + ", startX/Y: " + this.debug.nf.format(this.startX) + " / " + this.debug.nf.format(this.startY)
                // + ", diff: " + this.debug.nf.format(diffX) + " / " + this.debug.nf.format(diffY)
                // + ", diffs: " + this.debug.nf.format(diffXs) + " / " + this.debug.nf.format(diffYs)
                // + ", l/t: " + this.debug.nf.format(viewerRect.left) + " -> " +this.debug.nf.format(left) + " / " + this.debug.nf.format(viewerRect.top) + " -> " +this.debug.nf.format(top)
                + ", viewer.w/h: " + this.debug.nf.format(viewerRect.width) + " / " + this.debug.nf.format(viewerRect.height)
                + ", dims: ", dims);
        }
        this.setViewerScale(newScale, { resetTransform: true });
        this.resetPinchZoomParams();
        // }, 50);
        if (event.cancelable) {
            event.preventDefault();
        }
        event.stopPropagation();
        // if (tl == 1) {
        // let pageX = event.changedTouches[0].pageX;
        // let pageY = event.changedTouches[0].pageY;
        // }
    }
    onViewerMouseDown(event) {
        if (this.options.disableEventHandling)
            return;
        let isInside = this.isInsideContainer([event]);
        if (!isInside)
            return;
        if (!this.options.moveEnabled)
            return;
        let dims = this.getDimensions(this.viewer, event);
        // this.zoomToPoint(event, event.pageX, event.pageY);
        if (this.debug.enabled) {
            this.debugPoint(dims.point.c.x, dims.point.c.y);
            this.debugPoint(dims.point.v.x, dims.point.v.x, true);
        }
        this.startX = dims.point.c.x;
        this.startY = dims.point.c.y;
        this.startLeft = parseFloat(getComputedStyle(this.viewer).left) || 0;
        this.startTop = parseFloat(getComputedStyle(this.viewer).top) || 0;
        this.state = "move";
        if (event.cancelable) {
            event.preventDefault();
        }
        event.stopPropagation();
    }
    onViewerMouseMove(event) {
        if (this.options.disableEventHandling)
            return;
        if (this.state != "move") {
            // console.log("mousemove: state!=move: " + this.state);
            return;
        }
        let dims = this.getDimensions(this.viewer, event);
        if (this.debug.enabled)
            this.debugPoint(dims.point.c.x, dims.point.c.y);
        let diffX = dims.point.c.x - this.startX;
        let diffY = dims.point.c.y - this.startY;
        let left = this.startLeft + diffX;
        let top = this.startTop + diffY;
        let constrain = this.constrain({ left: left, top: top });
        left = constrain.left;
        top = constrain.top;
        this.viewer.style.left = left + "px";
        this.viewer.style.top = top + "px";
        if (this.debug.enabled) {
            console.log("mousemove: "
                + this.debug.nf.format(dims.point.c.x) + " / " + this.debug.nf.format(dims.point.c.y)
                + ", diff: " + this.debug.nf.format(diffX) + " / " + this.debug.nf.format(diffY)
                + ", l/t: " + this.debug.nf.format(left) + " / " + this.debug.nf.format(top));
        }
        if (event.cancelable) {
            event.preventDefault();
        }
        event.stopPropagation();
    }
    onViewerMouseUp(event) {
        if (this.options.disableEventHandling)
            return;
        let isInside = this.isInsideContainer([event]);
        if (this.debug.enabled)
            console.log("mouseup: " + this.debug.nf.format(event.pageX) + " / " + this.debug.nf.format(event.pageY) + "; inside: " + isInside);
        // document.removeEventListener("mousemove", event);
        if (!isInside)
            return;
        this.resetPinchZoomParams();
        //TODO: kan ikke bruke preventDefault hvis vi skal kunne støtte dobbeltklikk
        if (event.cancelable) {
            event.preventDefault();
        }
        event.stopPropagation();
        let pageX = event.pageX;
        let pageY = event.pageY;
        let now = new Date().getTime();
        if (this.pointEnd.time) {
            let pe = this.pointEnd;
            let diff = now - pe.time;
            // console.log("pointEnd.diff: " + diff);
            if (pe.pageX == pageX && pe.pageY == pageY && diff < 300) {
                let PDFViewerApplication = window.PDFViewerApplication;
                let currentScale = PDFViewerApplication.pdfViewer.currentScale;
                let scaleFactor = 1.4;
                let newScale = this.isZooming() ? (currentScale / scaleFactor) : (currentScale * scaleFactor);
                // if (this.debug.enabled) console.log("pointEnd.point mateches, isZ: "+this.isZooming() +", new scale: " + currentScale + " -> " + newScale);
                setTimeout(() => {
                    this.setViewerScale(newScale);
                    this.pointEnd = {};
                }, 5);
                return;
            }
        }
        this.pointEnd = {
            time: now,
            pageX: pageX,
            pageY: pageY
        };
        // console.log("updateing pointEnd: ", this.pointEnd);
    }
    resetPinchZoomParams() {
        this.startX = this.startY = this.moveX = this.moveY = this.startLeft = this.startTop = this.initialPinchDistance = 0;
        this.currentScale = 1;
        this.state = "idle";
    }
    getBoxStyle(elem, name, style = window.getComputedStyle(elem)) {
        const suffix = name === 'border' ? 'Width' : '';
        return {
            left: parseFloat(style[`${name}Left${suffix}`]) || 0,
            right: parseFloat(style[`${name}Right${suffix}`]) || 0,
            top: parseFloat(style[`${name}Top${suffix}`]) || 0,
            bottom: parseFloat(style[`${name}Bottom${suffix}`]) || 0,
        };
    }
    getDimensions(elem, point) {
        const parent = elem.parentNode;
        const style = window.getComputedStyle(elem);
        const parentStyle = window.getComputedStyle(parent);
        const rectElem = elem.getBoundingClientRect();
        const rectParent = parent.getBoundingClientRect();
        const vts = this.getViewerTransformScale("getDimensions");
        const vto = this.getViewerTransformOrigin();
        let res = {
            elem: {
                style,
                width: rectElem.width,
                height: rectElem.height,
                top: rectElem.top,
                bottom: rectElem.bottom,
                left: rectElem.left,
                right: rectElem.right,
                margin: this.getBoxStyle(elem, 'margin', style),
                border: this.getBoxStyle(elem, 'border', style)
            },
            rel: {
                width: rectElem.width,
                height: rectElem.height,
                top: rectElem.top - rectParent.top,
                left: rectElem.left - rectParent.left,
                bottom: rectElem.bottom - rectParent.top,
                right: rectElem.right - rectParent.left,
            },
            parent: {
                style: parentStyle,
                width: rectParent.width,
                height: rectParent.height,
                top: rectParent.top,
                bottom: rectParent.bottom,
                left: rectParent.left,
                right: rectParent.right,
                padding: this.getBoxStyle(parent, 'padding', parentStyle),
                border: this.getBoxStyle(parent, 'border', parentStyle)
            }
        };
        if (vts == 1.0)
            res.scaled = res.rel;
        else {
            let sw = res.rel.width / vts;
            let sh = res.rel.height / vts;
            let wd = res.rel.width - sw; // 118
            let hd = res.rel.height - sh;
            res.scaled = {
                vts: vts,
                vto: vto,
                width: sw,
                height: sh,
                left: res.rel.left + wd / 2,
                right: res.rel.right - wd / 2,
                top: res.rel.top + hd / 2,
                bottom: res.rel.bottom - hd / 2,
                wd: wd,
                hd: hd,
            };
        }
        let vx = point ? point.pageX - rectElem.left : rectElem.width / 2;
        let vy = point ? point.pageY - rectElem.top : rectElem.height / 2;
        let cx = point ? point.pageX - rectParent.left : vx + res.rel.left;
        let cy = point ? point.pageY - rectParent.top : vy + res.rel.top;
        let vxp = vx / rectElem.width;
        let vyp = vy / rectElem.height;
        let cxp = cx / rectParent.width;
        let cyp = cy / rectParent.height;
        res.point = {
            src: point,
            v: {
                x: vx,
                y: vy,
                xp: vxp,
                yp: vyp
            },
            c: {
                x: cx,
                y: cy,
                xp: cxp,
                yp: cyp
            }
        };
        return res;
    }
    //   return res;
    // }
    getDimDiff(start, end) {
        // let se = start.elem;
        // let ee = end.elem;
        // let sp = start.parent;
        // let ep = end.parent;
        let input = {
            elem: {
                start: start.elem,
                end: end.elem
            },
            parent: {
                start: start.parent,
                end: end.parent
            },
            rel: {
                start: start.rel,
                end: end.rel
            },
            scaled: {
                start: start.scaled,
                end: end.scaled
            },
        };
        let res = {};
        for (let type of ["elem", "parent", "rel", "scaled"]) {
            let s = input[type].start;
            let e = input[type].end;
            res[type] = {};
            for (let prop of ["width", "height", "top", "bottom", "left", "right"]) {
                let sv = s[prop];
                let ev = e[prop];
                let diff = ev - sv;
                res[type][prop + "Label"] = this.debug.nf.format(sv) + " -> " + this.debug.nf.format(ev) + ", diff: " + this.debug.nf.format(diff) + " (" + this.debug.nf.format(diff / sv * 100.0) + " %)";
                res[type][prop] = diff;
            }
        }
        return res;
    }
    constrain(p) {
        const dims = this.getDimensions(this.viewer);
        let isScaled = dims.scaled.vts !== undefined && dims.scaled.vts != 1.0;
        let minX = p.left, maxX = p.left, minY = p.top, maxY = p.top;
        if (dims.elem.width <= dims.parent.width) {
            // inside
            minX = 0;
            maxX = (dims.parent.width - dims.elem.width);
        }
        else {
            // outside
            minX = -(dims.elem.width - dims.parent.width);
            maxX = 0;
        }
        if (dims.elem.height <= dims.parent.height) {
            // inside
            minY = 0;
            maxY = (dims.parent.height - dims.elem.height);
        }
        else {
            // outside
            minY = -(dims.elem.height - dims.parent.height);
            maxY = 0;
        }
        if (isScaled) {
            let vto = dims.scaled.vto;
            let xp = vto ? vto.x / dims.scaled.width : 0.5;
            let yp = vto ? vto.y / dims.scaled.height : 0.5;
            minX += dims.scaled.wd * xp;
            maxX += dims.scaled.wd * xp;
            minY += dims.scaled.hd * yp;
            maxY += dims.scaled.hd * yp;
        }
        let cLeft = Math.max(Math.min(p.left, maxX), minX);
        let cTop = Math.max(Math.min(p.top, maxY), minY);
        // if (this.debug.enabled) console.log("constrain, left:  " + p.left + " -> " + cLeft + " ("+minX + "-"+maxX+")" + ", top: " + p.top + " -> " + cTop + " ("+minY + "-"+maxY+"), dims: ", dims);
        return { left: cLeft, top: cTop };
    }
    isInsideContainer(points) {
        const viewerContainer = document.getElementById('viewerContainer');
        const rect = viewerContainer.getBoundingClientRect();
        if (points === undefined || points.length == 0)
            return false;
        //TODO: Check event, is target.parent the viewerContainer? 
        // let allInside = true;
        for (let point of points) {
            let target = point.target;
            if (target) {
                let closest = target.closest("#viewerContainer");
                // console.log("closest: ", closest)
                if (closest == undefined) {
                    return false;
                }
            }
            let pageX = point.pageX; // + viewerContainer.scrollLeft;
            let pageY = point.pageY; // + viewerContainer.scrollTop;
            let inside = false;
            if (pageX >= rect.left && pageX <= rect.right) {
                if (pageY >= (rect.top + window.scrollY) && pageY <= (rect.bottom + window.scrollY)) {
                    inside = true;
                }
            }
            // console.log("pageX/Y: " + pageX + " / " + pageY + ", inside: " + inside + "; rect: ", rect, ", point: ", point);
            if (!inside)
                return false;
        }
        return true;
    }
    getViewerTransformScale(src) {
        let tf = getComputedStyle(this.viewer).transform;
        if (tf == "none" || tf.indexOf("(") < 0) {
            let vts = 1.0;
            // if (this.transformScale > 0.0) {
            //   vts = this.transformScale
            // }
            // if (this.debug.enabled) console.log("getViewerTransformScale, tf: " + tf + ", indexOf (: " + tf.indexOf("(") + ", src: " + src + ", vts: " + vts);
            return vts;
        }
        let isScale = tf.indexOf("scale") >= 0;
        let transformScale = parseFloat(tf.substring(tf.indexOf("(") + 1, tf.indexOf(isScale ? ")" : ",")));
        // if (this.debug.enabled) console.log("getViewerTransformScale, tf: " + tf + ", indexOf (: " + tf.indexOf("(") + ", transformScale: " + transformScale + ", src: " + src);
        return transformScale;
    }
    getViewerTransformOrigin() {
        let to = this.viewer.style.transformOrigin;
        if (to == undefined || to == "unset")
            return undefined;
        let parts = to.split(" ");
        if (parts.length != 2)
            return undefined;
        return { x: parseFloat(parts[0]), y: parseFloat(parts[1]) };
    }
    checkContraint() {
        const dims = this.getDimensions(this.viewer);
        let constrain = this.constrain({ left: dims.elem.left, top: dims.elem.top });
        return constrain.left != dims.elem.left && constrain.top != dims.elem.top;
    }
    updateViewerPosition(forceUpdate = false) {
        let viewerContainer = document.getElementById('viewerContainer');
        this.viewer = document.getElementById('viewer');
        const dims = this.getDimensions(this.viewer);
        let constrain = this.constrain({ left: dims.elem.left, top: dims.elem.top }); // ;
        let transformScale = this.getViewerTransformScale("updateViewerPosition");
        // if (transformScale == 1.0)
        if (this.debug.enabled) {
            // console.log("updateViewerPosition"
            //   + ", updateLeft: " + (dims.elem.width <= dims.parent.width) 
            //   + ", updateTop: " + (dims.elem.height <= dims.parent.height)
            //   + ", checkContraint: " + this.checkContraint()
            //   + ", transformScale: " + transformScale 
            //   + ", dims: ", dims);
        }
        let point = {
            left: undefined,
            top: undefined
        };
        if (forceUpdate || dims.elem.width <= dims.parent.width || (constrain && constrain.left != dims.elem.left)) {
            let left = (dims.parent.width - (dims.elem.width / transformScale)) / 2;
            // console.log("updateViewerPosition, left: " + this.viewer.style.left  + " -> " + left);
            // this.viewer.style.left = left + "px";
            point.left = left;
        }
        if (forceUpdate || dims.elem.height <= dims.parent.height || (constrain && constrain.top != dims.elem.top)) {
            let top = (dims.parent.height - (dims.elem.height / transformScale)) / 2;
            // console.log("updateViewerPosition, top: " + this.viewer.style.top  + " -> " + top);
            // this.viewer.style.top = top + "px";
            point.top = top;
        }
        if (point.left || point.top) {
            this.viewer.style.left = point.left + "px";
            this.viewer.style.top = point.top + "px";
        }
    }
    setViewerScale(newScale, options = {}) {
        let vtsSource = getComputedStyle(this.viewer).transform;
        if (this.debug.enabled)
            console.log("setViewerScale, newScale: " + newScale + ", vtsSource: " + vtsSource);
        let origin = options.origin;
        // let resetTransform = options.resetTransform === undefined || options.resetTransform === true; 
        let vts = this.getViewerTransformScale("setViewerScale");
        let dims = this.getDimensions(this.viewer);
        // let dimsAfterTransformReset = dims; 
        let reset = { left: undefined, top: undefined };
        if (vts != 1.0) { // resetTransform && 
            if (vtsSource != "none") {
                reset.left = dims.rel.left;
                reset.top = dims.rel.top;
            }
            this.viewer.style.transform = 'none';
            this.viewer.style.transformOrigin = 'unset';
            // this.transformScale = -1;
            // dimsAfterTransformReset = this.getDimensions(this.viewer);
        }
        let PDFViewerApplication = window.PDFViewerApplication;
        let currentScale = PDFViewerApplication.pdfViewer.currentScale;
        if (origin == undefined) {
            origin = { x: dims.elem.width / 2, y: dims.elem.height / 2 };
        }
        let oxp = origin.x / dims.elem.width;
        let oyp = origin.y / dims.elem.height;
        if (this.debug.enabled) {
            console.log("setViewerScale, currentScale: " + this.debug.nf.format(currentScale) + " -> " + this.debug.nf.format(newScale) + ", vts: " + this.debug.nf.format(vts) + " (" + vtsSource + ")"
                + ", origin: " + this.debug.nf.format(origin.x) + " (" + this.debug.nf.format(oxp * 100) + ") / " + this.debug.nf.format(origin.y) + " (" + this.debug.nf.format(oyp * 100) + ")"
                + ", debug.x/Y: " + this.debug.nf.format(this.debug.x) + " / " + +this.debug.nf.format(this.debug.y)
                + ", isZooming: " + this.isZooming()
                + ", dims: ", dims);
        }
        PDFViewerApplication.pdfViewer._setScale(newScale, true);
        let dimsAfter = this.getDimensions(this.viewer);
        let dimDiff = this.getDimDiff(dims, dimsAfter);
        let dimsCorr = {
            left: parseFloat(getComputedStyle(this.viewer).left) || 0,
            top: parseFloat(getComputedStyle(this.viewer).top) || 0,
        };
        dimsCorr.leftDiff = -(dimDiff.elem.width * oxp);
        dimsCorr.topDiff = -(dimDiff.elem.height * oyp);
        dimsCorr.leftNext = dimsCorr.left + dimsCorr.leftDiff;
        dimsCorr.topNext = dimsCorr.top + dimsCorr.topDiff;
        if (reset.left) {
            if (this.debug.enabled) {
                console.log("dimsCorr.leftNext: " + this.debug.nf.format(dimsCorr.leftNext) + " -> " + this.debug.nf.format(reset.left));
                console.log("dimsCorr.topNext: " + this.debug.nf.format(dimsCorr.topNext) + " -> " + this.debug.nf.format(reset.top));
            }
            dimsCorr.leftNext = reset.left;
            dimsCorr.topNext = reset.top;
        }
        this.viewer.style.left = dimsCorr.leftNext + "px";
        this.viewer.style.top = dimsCorr.topNext + "px";
        if (this.debug.enabled) {
            console.log("setViewerScale2, newCurrentScale: " + this.debug.nf.format(PDFViewerApplication.pdfViewer.currentScale)
                + ", isZooming: " + this.isZooming()
                + ", dimsAfter: ", dimsAfter, ", dimDiff: ", dimDiff, ", dimsCorr: ", dimsCorr);
        }
    }
    isZooming() {
        let PDFViewerApplication = window.PDFViewerApplication;
        const PDFViewerApplicationOptions = window.PDFViewerApplicationOptions;
        let currentScale = PDFViewerApplication.pdfViewer.currentScale;
        let czf = Math.round(currentScale * 10000);
        let minZoom = Math.round(Number(PDFViewerApplicationOptions.get('minZoom')) * 10000);
        //  console.log("isZooming, czf: "  + czf + ", minZoom: " + minZoom + "; isZ: " + (czf > minZoom));
        return czf > minZoom;
    }
    onViewerWheel(event) {
        if (this.options.disableEventHandling)
            return;
        if (this.debug.enabled)
            console.log("onWheel: event: ", event);
        setTimeout(() => {
            this.updateViewerPosition();
        }, 2);
    }
    ;
    initializeRelativeCoords() {
        let viewerContainer = document.getElementById('viewerContainer');
        this.viewer = document.getElementById('viewer');
        this.component.root.nativeElement.classList.add("relative-coords");
        let stfItemHack = document.createElement("div");
        stfItemHack.classList.add("stf__item");
        viewerContainer.appendChild(stfItemHack);
        if (this.debug.enabled)
            console.log("initializeRelativeCoords: isMobile: " + this.isMobile());
        let onContainerScoll = (event) => {
            //console.log("onContainerScoll: l/t: " + viewerContainer.scrollLeft + " / " + viewerContainer.scrollTop + ", event: " , event);
            if (viewerContainer.scrollLeft != 0 || viewerContainer.scrollTop != 0)
                viewerContainer.scroll({ left: 0, top: 0 });
        };
        viewerContainer.addEventListener('scroll', onContainerScoll);
        this.component.pagesLoaded.subscribe(async (event) => {
            if (this.debug.enabled)
                console.log("initializeRelativeCoords: scrollTop: ", viewerContainer.scrollTop);
            setTimeout(() => {
                // console.log("pageChange: pages: ", this.getCurrentPagesInView())
                this.updateViewerPosition(true);
            }, 10);
        });
        this.component.pageChange.subscribe(async (event) => {
            if (this.debug.enabled)
                console.log("pageChange: event: ", event, ", dims: ", this.getDimensions(this.viewer));
            // console.log("pageChange: pages: ", this.getCurrentPagesInView())
            setTimeout(() => {
                // console.log("pageChange: pages: ", this.getCurrentPagesInView())
                this.updateViewerPosition(true);
            }, 10);
        });
        // this.component.zoomChange.subscribe(async (event: any) => {
        //   console.log("zoomChange: event: ", event);
        // });
        this.component.currentZoomFactor.subscribe(async (event) => {
            if (this.debug.enabled)
                console.log("currentZoomFactor: event: ", event);
            // this.updateViewerPosition();
        });
        if (!this.isMobile()) {
            // let onWheel = 
            this._zone.runOutsideAngular(() => {
                // Panning support on desktop
                document.addEventListener('mousedown', this.boundOnViewerMouseDown);
                document.addEventListener('mousemove', this.boundOnViewerMouseMove, { passive: false });
                document.addEventListener('mouseup', this.boundOnViewerMouseUp);
                window.addEventListener("wheel", this.boundOnViewerWheel, { passive: false });
            });
        }
        else {
            this._zone.runOutsideAngular(() => {
                document.addEventListener('touchstart', this.boundOnViewerTouchStart);
                document.addEventListener('touchmove', this.boundOnViewerTouchMove, { passive: false });
                document.addEventListener('touchend', this.boundOnViewerTouchEnd);
            });
        }
        if (this.debug.enabled) {
            let onKeyup = (event) => {
                console.log("onKeyup: event.key: " + event.key);
                let dims = this.getDimensions(this.viewer);
                const PDFViewerApplication = window.PDFViewerApplication;
                if (event.key == "q") {
                    this.viewer.style.transform = `none`;
                    this.viewer.style.transformOrigin = `unset`;
                    this.currentScale = 1.0;
                    let dimsAfter = this.getDimensions(this.viewer);
                    console.log("dimsAfter: ", dimsAfter.scaled);
                    console.log("dimsDiff: ", this.getDimDiff(dims, dimsAfter).scaled);
                }
                else if (event.key == "w") {
                    let originX = this.debug.x || dims.parent.width / 2;
                    let originY = this.debug.y || dims.parent.height / 2;
                    originX -= dims.elem.left - dims.parent.left;
                    originY -= dims.elem.top - dims.parent.top;
                    this.currentScale = 1.3;
                    console.log("originX/Y: " + originX + " / " + originY + ", scale: " + this.currentScale + "; dims: ", dims);
                    console.log("originX/Y (%): " + this.debug.nf.format(originX / dims.elem.width * 100) + " / " + this.debug.nf.format(originY / dims.elem.height * 100));
                    this.viewer.style.transform = `scale(${this.currentScale})`;
                    this.viewer.style.transformOrigin = `${originX}px ${originY}px`;
                    let dimsAfter = this.getDimensions(this.viewer);
                    console.log("dimsAfter: ", dimsAfter.elem);
                    console.log("dimsDiff: ", this.getDimDiff(dims, dimsAfter).elem);
                }
                else if (event.key == "e") {
                    // this.viewer.style.transform = `none`;
                    // this.viewer.style.transformOrigin = `unset`;
                    let currentScale = PDFViewerApplication.pdfViewer.currentScale;
                    let newScale = currentScale * this.currentScale;
                    console.log("currentScale: " + currentScale + " -> " + newScale + ", cs: " + this.currentScale + ", dims: ", dims);
                    // PDFViewerApplication.pdfViewer._setScale(newScale, true);
                    this.setViewerScale(newScale, { resetTransform: true });
                    let dimsAfter = this.getDimensions(this.viewer);
                    console.log("dimsAfter: ", dimsAfter.elem);
                    console.log("dimsDiff: ", this.getDimDiff(dims, dimsAfter).elem);
                    // } else  if (event.key == "r") { // Rotate
                }
                else if (event.key == "s") {
                    let originX = this.debug.x || dims.parent.width / 2;
                    let originY = this.debug.y || dims.parent.height / 2;
                    originX -= dims.elem.left - dims.parent.left;
                    originY -= dims.elem.top - dims.parent.top;
                    // reset pdfViewer.scale
                    let currentScale = PDFViewerApplication.pdfViewer.currentScale;
                    let prevScale = currentScale / this.currentScale;
                    // console.log("currentScale: " + currentScale + " -> " + prevScale + ", originX/Y: " + originX + " / " + originY);
                    console.log("originX/Y: " + originX + " / " + originY + ", scale: " + currentScale + " -> " + prevScale + ", t.cs: " + this.currentScale + "; dims: ", dims);
                    console.log("originX/Y (%): " + (originX / dims.elem.width) + " / " + (originY / dims.elem.height));
                    // PDFViewerApplication.pdfViewer._setScale(prevScale, true);
                    if (currentScale != prevScale)
                        this.setViewerScale(prevScale);
                    originX = this.debug.x || dims.parent.width / 2;
                    originY = this.debug.y || dims.parent.height / 2;
                    let dimsAfter = this.getDimensions(this.viewer);
                    originX -= dimsAfter.elem.left - dimsAfter.parent.left;
                    originY -= dimsAfter.elem.top - dimsAfter.parent.top;
                    console.log("originX/Y: " + originX + " / " + originY + ", scale: " + currentScale + " -> " + prevScale + ", t.cs: " + this.currentScale + "; dimsAfter: ", dimsAfter);
                    console.log("originX/Y (%): " + (originX / dimsAfter.elem.width) + " / " + (originY / dimsAfter.elem.height));
                    this.viewer.style.transform = `scale(${this.currentScale})`;
                    this.viewer.style.transformOrigin = `${originX}px ${originY}px`;
                }
                else if (event.key == "t") {
                    // bare PDF.js-zoom
                    let originX = this.debug.x || dims.parent.width / 2;
                    let originY = this.debug.y || dims.parent.height / 2;
                    originX -= dims.elem.left - dims.parent.left;
                    originY -= dims.elem.top - dims.parent.top;
                    if (this.currentScale == 1.0)
                        this.currentScale = 1.3;
                    let currentScale = PDFViewerApplication.pdfViewer.currentScale;
                    let newScale = currentScale * this.currentScale;
                    this.setViewerScale(newScale, { origin: { x: originX, y: originY } });
                }
                else if (event.key == "y") {
                    let originX = this.debug.x || dims.parent.width / 2;
                    let originY = this.debug.y || dims.parent.height / 2;
                    originX -= dims.elem.left - dims.parent.left;
                    originY -= dims.elem.top - dims.parent.top;
                    let currentScale = PDFViewerApplication.pdfViewer.currentScale;
                    let prevScale = currentScale / this.currentScale;
                    console.log("y, currentScale: " + currentScale + "; prevScale: " + prevScale);
                    // PDFViewerApplication.pdfViewer._setScale(prevScale, true);
                    this.setViewerScale(prevScale, { origin: { x: originX, y: originY } });
                    // this.currentScale = 1.0;
                    // let dimsAfter = this.getDimensions(this.viewer);
                    // console.log("dimsAfter: ", dimsAfter.elem);
                    // console.log("dimsDiff: ", this.getDimDiff(dims, dimsAfter).elem);
                }
                else if (event.key == "u") {
                    this.updateViewerPosition();
                }
                else if (event.key == "i") {
                    let corrLeft = 200;
                    console.log("beforeCorr: ", this.getDimensions(this.viewer).elem);
                    console.log("this.viewer.style: ", this.viewer.style);
                    console.log("this.viewer.style.left: " + this.viewer.style.left + " -> " + corrLeft);
                    this.viewer.style.left = corrLeft + "px";
                    console.log("afterCorr: ", this.getDimensions(this.viewer).elem);
                    console.log("this.viewer.style: ", this.viewer.style);
                }
                else if (event.key == "o") {
                    let originX = this.debug.x || dims.parent.width / 2;
                    let originY = this.debug.y || dims.parent.height / 2;
                    originX -= dims.elem.left - dims.parent.left;
                    originY -= dims.elem.top - dims.parent.top;
                    console.log("originX/Y: " + originX + " / " + originY + ", scale: " + this.currentScale);
                    this.viewer.style.transform = `scale(${this.currentScale})`;
                    this.viewer.style.transformOrigin = `${originX}px ${originY}px`;
                }
                else if (event.key == "p") {
                    console.log("dims: ", dims);
                    // let originX = this.debug.x || dims.parent.width / 2; 
                    // let originY = this.debug.y || dims.parent.height / 2; 
                    console.log("getViewerTransformScale: ", this.getViewerTransformScale("key == p"));
                    this.viewer.style.transform = `none`;
                    this.viewer.style.transformOrigin = `unset`;
                    let dimsAfter = this.getDimensions(this.viewer);
                    console.log("dimsAfter: ", dimsAfter);
                    console.log("dimsDiff: ", this.getDimDiff(dims, dimsAfter));
                }
                else if (event.key == "f") {
                }
                else if (event.key == "d") {
                    console.log("dims: ", this.getDimensions(this.viewer));
                }
                else if (event.key == "z") {
                }
                else if (event.key == "x") {
                }
            };
            window.addEventListener("keyup", onKeyup);
        }
    }
    destroyRelativeCoords() {
        if (!this.isMobile()) {
            document.removeEventListener('mousedown', this.boundOnViewerMouseDown);
            document.removeEventListener('mousemove', this.boundOnViewerMouseMove);
            document.removeEventListener('mouseup', this.boundOnViewerMouseUp);
            window.removeEventListener("wheel", this.boundOnViewerWheel);
            return;
        }
        document.removeEventListener('touchstart', this.boundOnViewerTouchStart);
        document.removeEventListener('touchmove', this.boundOnViewerTouchMove);
        document.removeEventListener('touchend', this.boundOnViewerTouchEnd);
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsYXRpdmUtY29vcmRzLXN1cHBvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZXh0ZW5kZWQtcGRmLXZpZXdlci9zcmMvbGliL3JlbGF0aXZlLWNvb3Jkcy1zdXBwb3J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE1BQU0sT0FBTyxxQkFBcUI7SUEyQ2hDLFlBQW9CLEtBQWEsRUFBVSxTQUF3QyxFQUFFLE9BQVk7UUFBN0UsVUFBSyxHQUFMLEtBQUssQ0FBUTtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQStCO1FBekMzRSxZQUFPLEdBQVE7WUFDckIsS0FBSyxFQUFFLEtBQUs7WUFDWixXQUFXLEVBQUUsSUFBSTtZQUNqQixvQkFBb0IsRUFBRSxLQUFLO1NBQzVCLENBQUM7UUFHTSxXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsV0FBTSxHQUFHLENBQUMsQ0FBQztRQUNYLFVBQUssR0FBRyxDQUFDLENBQUM7UUFDVixVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFFYixVQUFLLEdBQTZCLE1BQU0sQ0FBQztRQUN6Qyx5QkFBb0IsR0FBRyxDQUFDLENBQUM7UUFDekIsaUJBQVksR0FBRyxHQUFHLENBQUM7UUFFbkIsYUFBUSxHQUFRLEVBRXZCLENBQUE7UUFhTyxVQUFLLEdBQUc7WUFDZCxPQUFPLEVBQUUsS0FBSztZQUNkLEVBQUUsRUFBRSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxxQkFBcUIsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNsRixDQUFDLEVBQUUsQ0FBQztZQUNKLENBQUMsRUFBRSxDQUFDO1NBQ0wsQ0FBQTtRQUlDLE9BQU8sR0FBRyxPQUFPLElBQUksRUFBRSxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxD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O2FBQ1AsQ0FBQTtTQUNGO1FBSUQsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2xFLElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUVsRSxJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ25FLElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7UUFFakUsSUFBSSxHQUFHLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDOUIsSUFBSSxHQUFHLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDL0IsSUFBSSxHQUFHLEdBQUcsRUFBRSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUM7UUFDaEMsSUFBSSxHQUFHLEdBQUcsRUFBRSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUM7UUFFakMsR0FBRyxDQUFDLEtBQUssR0FBRztZQUNWLEdBQUcsRUFBRSxLQUFLO1lBQ1YsQ0FBQyxFQUFFO2dCQUNELENBQUMsRUFBRSxFQUFFO2dCQUNMLENBQUMsRUFBRSxFQUFFO2dCQUNMLEVBQUUsRUFBRSxHQUFHO2dCQUNQLEVBQUUsRUFBRSxHQUFHO2FBQ1I7WUFDRCxDQUFDLEVBQUU7Z0JBQ0QsQ0FBQyxF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LElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBRTdELElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7WUFDeEMsU0FBUztZQUNULElBQUksR0FBRyxDQUFDLENBQUM7WUFDVCxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1NBQzdDO2FBQU07WUFDTCxVQUFVO1lBQ1YsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzlDLElBQUksR0FBRyxDQUFDLENBQUM7U0FFVjtRQUNELElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDMUMsU0FBUztZQUNULElBQUksR0FBRyxDQUFDLENBQUM7WUFDVCxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBRWhEO2FBQU07WUFDTCxVQUFVO1lBQ1YsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2hELElBQUksR0FBRyxDQUFDLENBQUM7U0FFVjtRQUVELElBQUksUUFBUSxFQUFFO1lBQ1osSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7WUFDMUIsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDL0MsSUFBSSxFQUFFLEdBQUcs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QUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1NBQzlEO1FBRUQsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNyQyxJQUFJLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBRXRDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUU7WUFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsR0FBRztrQkFDeEwsWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRztrQkFDL0ssZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFFLElBQUksQ0FBQyxL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QUMsR0FBRyxJQUFJLEdBQUcsRUFBRTtpQkFFNUI7cUJBQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLEdBQUcsRUFBRTtpQkFFNUI7WUFDSCxDQUFDLENBQUM7WUFHRixNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQzNDO0lBSUgsQ0FBQztJQUVNLHFCQUFxQjtRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQ3BCLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7WUFDdkUsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUN2RSxRQUFRLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBRW5FLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFFN0QsT0FBTztTQUNSO1FBQ0QsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUN6RSxRQUFRLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3ZFLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDdkUsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQYWdlc0xvYWRlZEV2ZW50IH0gZnJvbSAnLi4vcHVibGljX2FwaSc7XG5pbXBvcnQgeyBOZ3hFeHRlbmRlZFBkZlZpZXdlckNvbXBvbmVudCB9IGZyb20gJy4vbmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IElQREZWaWV3ZXJBcHBsaWNhdGlvbk9wdGlvbnMgfSBmcm9tICcuL29wdGlvbnMvcGRmLXZpZXdlci1hcHBsaWNhdGlvbi1vcHRpb25zJztcblxuZXhwb3J0IGNsYXNzIFJlbGF0aXZlQ29vcmRzU3VwcG9ydCB7XG5cbiAgcHJpdmF0ZSBvcHRpb25zOiBhbnkgPSB7XG4gICAgZGVidWc6IGZhbHNlLFxuICAgIG1vdmVFbmFibGVkOiB0cnVlLFxuICAgIGRpc2FibGVFdmVudEhhbmRsaW5nOiBmYWxzZSxcbiAgfTtcbiAgcHJpdmF0ZSB2aWV3ZXI6IGFueTtcblxuICBwcml2YXRlIHN0YXJ0WCA9IDA7XG4gIHByaXZhdGUgc3RhcnRZID0gMDtcbiAgcHJpdmF0ZSBtb3ZlWCA9IDA7XG4gIHByaXZhdGUgbW92ZVkgPSAwO1xuICBwcml2YXRlIHN0YXJ0TGVmdCA9IDA7XG4gIHByaXZhdGUgc3RhcnRUb3AgPSAwO1xuXG4gIHByaXZhdGUgc3RhdGU6IFwiaWRsZVwiIHwgXCJtb3ZlXCIgfCBcInpvb21cIiA9IFwiaWRsZVwiO1xuICBwcml2YXRlIGluaXRpYWxQaW5jaERpc3RhbmNlID0gMDtcbiAgcHJpdmF0ZSBjdXJyZW50U2NhbGUgPSAxLjA7XG5cbiAgcHJpdmF0ZSBwb2ludEVuZDogYW55ID0ge1xuXG4gIH1cblxuICAvLyBwcml2YXRlIHRyYW5zZm9ybVNjYWxlID0gLTE7XG5cbiAgcHJpdmF0ZSBib3VuZE9uVmlld2VyVG91Y2hTdGFydDogYW55O1xuICBwcml2YXRlIGJvdW5kT25WaWV3ZXJUb3VjaE1vdmU6IGFueTtcbiAgcHJpdmF0ZSBib3VuZE9uVmlld2VyVG91Y2hFbmQ6IGFueTtcblxuICBwcml2YXRlIGJvdW5kT25WaWV3ZXJNb3VzZURvd246IGFueTtcbiAgcHJpdmF0ZSBib3VuZE9uVmlld2VyTW91c2VNb3ZlOiBhbnk7XG4gIHByaXZhdGUgYm91bmRPblZpZXdlck1vdXNlVXA6IGFueTtcbiAgcHJpdmF0ZSBib3VuZE9uVmlld2VyV2hlZWw6IGFueTtcblxuICBwcml2YXRlIGRlYnVnID0ge1xuICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgIG5mOiBuZXcgSW50bC5OdW1iZXJGb3JtYXQoJ2VuLVVTJywgeyBzdHlsZTogJ2RlY2ltYWwnLCBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IDIgfSksXG4gICAgeDogMCxcbiAgICB5OiAwXG4gIH1cblxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX3pvbmU6IE5nWm9uZSwgcHJpdmF0ZSBjb21wb25lbnQ6IE5neEV4dGVuZGVkUGRmVmlld2VyQ29tcG9uZW50LCBvcHRpb25zOiBhbnkpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICBPYmplY3Qua2V5cyh0aGlzLm9wdGlvbnMpLmZvckVhY2goYXR0cmlidXQgPT4ge1xuICAgICAgaWYgKG9wdGlvbnNbYXR0cmlidXRdID09PSB1bmRlZmluZWQpIG9wdGlvbnNbYXR0cmlidXRdID0gdGhpcy5vcHRpb25zW2F0dHJpYnV0XTtcbiAgICB9KTtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG5cbiAgICB0aGlzLmRlYnVnLmVuYWJsZWQgPSB0aGlzLm9wdGlvbnMuZGVidWc7XG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgY29uc29sZS5sb2coXCJSZWxhdGl2ZUNvb3Jkc1N1cHBvcnQuY29uc3RydWN0b3JcIik7XG4gICAgdGhpcy5ib3VuZE9uVmlld2VyVG91Y2hTdGFydCA9IHRoaXMub25WaWV3ZXJUb3VjaFN0YXJ0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5ib3VuZE9uVmlld2VyVG91Y2hNb3ZlID0gdGhpcy5vblZpZXdlclRvdWNoTW92ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuYm91bmRPblZpZXdlclRvdWNoRW5kID0gdGhpcy5vblZpZXdlclRvdWNoRW5kLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLmJvdW5kT25WaWV3ZXJNb3VzZURvd24gPSB0aGlzLm9uVmlld2VyTW91c2VEb3duLmJpbmQodGhpcyk7XG4gICAgdGhpcy5ib3VuZE9uVmlld2VyTW91c2VNb3ZlID0gdGhpcy5vblZpZXdlck1vdXNlTW92ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuYm91bmRPblZpZXdlck1vdXNlVXAgPSB0aGlzLm9uVmlld2VyTW91c2VVcC5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5ib3VuZE9uVmlld2VyV2hlZWwgPSB0aGlzLm9uVmlld2VyV2hlZWwuYmluZCh0aGlzKTtcblxuICAgIHRoaXMuaW5pdGlhbGl6ZVJlbGF0aXZlQ29vcmRzKCk7XG4gIH1cblxuICBwcml2YXRlIGlzTW9iaWxlKCkge1xuXG4gICAgcmV0dXJuIChuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHMgPiAwKSB8fCAoKDxhbnk+bmF2aWdhdG9yKS5tc01heFRvdWNoUG9pbnRzID4gMCk7ICAvLyAoJ29udG91Y2hzdGFydCcgaW4gd2luZG93KSB8fCBcbiAgfVxuXG4gIHByaXZhdGUgb25WaWV3ZXJUb3VjaFN0YXJ0KGV2ZW50OiBUb3VjaEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlRXZlbnRIYW5kbGluZykgcmV0dXJuO1xuXG4gICAgdGhpcy5pbml0aWFsUGluY2hEaXN0YW5jZSA9IDA7XG5cbiAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3ZXJDb250YWluZXInKSBhcyBIVE1MRGl2RWxlbWVudDtcbiAgICAgIGNvbnN0IHJlY3QgPSBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBpZiAoZXZlbnQudG91Y2hlc1swXS5wYWdlWCA+PSByZWN0LmxlZnQgJiYgZXZlbnQudG91Y2hlc1swXS5wYWdlWCA8PSByZWN0LnJpZ2h0KSB7XG4gICAgICAgIGlmIChldmVudC50b3VjaGVzWzBdLnBhZ2VZID49IChyZWN0LnRvcCArIHdpbmRvdy5zY3JvbGxZKSAmJiBldmVudC50b3VjaGVzWzBdLnBhZ2VZIDw9IChyZWN0LmJvdHRvbSArIHdpbmRvdy5zY3JvbGxZKSkge1xuICAgICAgICAgIGlmIChldmVudC50b3VjaGVzWzFdLnBhZ2VYID49IHJlY3QubGVmdCAmJiBldmVudC50b3VjaGVzWzFdLnBhZ2VYIDw9IHJlY3QucmlnaHQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC50b3VjaGVzWzFdLnBhZ2VZID49IChyZWN0LnRvcCArIHdpbmRvdy5zY3JvbGxZKSAmJiBldmVudC50b3VjaGVzWzFdLnBhZ2VZIDw9IChyZWN0LmJvdHRvbSArIHdpbmRvdy5zY3JvbGxZKSkge1xuICAgICAgICAgICAgICB0aGlzLnN0YXJ0WCA9IChldmVudC50b3VjaGVzWzBdLnBhZ2VYICsgZXZlbnQudG91Y2hlc1sxXS5wYWdlWCkgLyAyO1xuICAgICAgICAgICAgICB0aGlzLnN0YXJ0WSA9IChldmVudC50b3VjaGVzWzBdLnBhZ2VZICsgZXZlbnQudG91Y2hlc1sxXS5wYWdlWSkgLyAyO1xuICAgICAgICAgICAgICB0aGlzLmluaXRpYWxQaW5jaERpc3RhbmNlID0gTWF0aC5oeXBvdChldmVudC50b3VjaGVzWzFdLnBhZ2VYIC0gZXZlbnQudG91Y2hlc1swXS5wYWdlWCwgZXZlbnQudG91Y2hlc1sxXS5wYWdlWSAtIGV2ZW50LnRvdWNoZXNbMF0ucGFnZVkpO1xuXG4gICAgICAgICAgICAgIHRoaXMuc3RhcnRMZWZ0ID0gcGFyc2VGbG9hdChnZXRDb21wdXRlZFN0eWxlKHRoaXMudmlld2VyKS5sZWZ0KSB8fCAwO1xuICAgICAgICAgICAgICB0aGlzLnN0YXJ0VG9wID0gcGFyc2VGbG9hdChnZXRDb21wdXRlZFN0eWxlKHRoaXMudmlld2VyKS50b3ApIHx8IDA7XG4gICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBcInpvb21cIjtcblxuICAgICAgICAgICAgICBpZiAoZXZlbnQuY2FuY2VsYWJsZSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBsZXQgdG91Y2ggPSBldmVudC50b3VjaGVzWzBdXG4gICAgICBpZiAodGhpcy5vcHRpb25zLm1vdmVFbmFibGVkICYmIHRoaXMuaXNJbnNpZGVDb250YWluZXIoW3RvdWNoXSkgJiYgdGhpcy5zdGF0ZSA9PSBcImlkbGVcIikge1xuICAgICAgICBjb25zdCB2aWV3ZXJDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlld2VyQ29udGFpbmVyJykgYXMgSFRNTERpdkVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHJlY3QgPSB2aWV3ZXJDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgbGV0IHBhZ2VYID0gdG91Y2gucGFnZVggLSByZWN0LmxlZnQ7XG4gICAgICAgIGxldCBwYWdlWSA9IHRvdWNoLnBhZ2VZIC0gcmVjdC50b3A7XG5cbiAgICAgICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgdGhpcy5kZWJ1Z1BvaW50KHBhZ2VYLCBwYWdlWSk7XG5cbiAgICAgICAgdGhpcy5zdGFydFggPSBwYWdlWDtcbiAgICAgICAgdGhpcy5zdGFydFkgPSBwYWdlWTtcblxuICAgICAgICBsZXQgbGVmdCA9IHBhcnNlRmxvYXQoZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnZpZXdlcikubGVmdCkgfHwgMDtcbiAgICAgICAgbGV0IHRvcCA9IHBhcnNlRmxvYXQoZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnZpZXdlcikudG9wKSB8fCAwO1xuXG5cblxuICAgICAgICBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJUb3VjaFN0YXJ0OiBcIlxuICAgICAgICAgICAgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChwYWdlWCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQocGFnZVkpXG4gICAgICAgICAgICArIFwiLCBzdGFydFgvWTogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh0aGlzLnN0YXJ0WCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodGhpcy5zdGFydFkpXG4gICAgICAgICAgICArIFwiLCBzdGFydExlZnQvVG9wOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMuc3RhcnRMZWZ0KSArIFwiIC0+IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQobGVmdCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodGhpcy5zdGFydFRvcCkgKyBcIiAtPiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRvcClcbiAgICAgICAgICAgICsgXCIsIHN0YXRlOiBcIiArIHRoaXMuc3RhdGUsXG4gICAgICAgICAgICBcIiwgZGltczogXCIsIHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcilcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdGFydExlZnQgPSBsZWZ0O1xuICAgICAgICB0aGlzLnN0YXJ0VG9wID0gdG9wO1xuICAgICAgICB0aGlzLnN0YXRlID0gXCJtb3ZlXCI7XG5cbiAgICAgICAgaWYgKGV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlRvdWNoU3RhcnQ6IGlzSW5zaWRlOiBcIiArICB0aGlzLmlzSW5zaWRlQ29udGFpbmVyKFsgdG91Y2ggXSkgKyBcIiwgc3RhdGU6IFwiICsgdGhpcy5zdGF0ZSk7XG4gICAgICB9XG5cblxuICAgIH1cbiAgfVxuXG5cblxuXG4gIC8vIHByaXZhdGUgZ2V0Q3VycmVudFBhZ2VzSW5WaWV3KCk6bnVtYmVyW10ge1xuICAvLyAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBhbnkgPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG5cbiAgLy8gICBsZXQgcGFnZSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBhZ2U7XG4gIC8vICAgbGV0IHBhZ2VDb3VudCA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5fcGFnZXMubGVuZ3RoO1xuXG4gIC8vICAgbGV0IHNwcmVhZE1vZGUgPSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIuc3ByZWFkTW9kZSBhcyBTcHJlYWRNb2RlVHlwZTtcblxuICAvLyAgIGxldCBwYWdlcyA9IFsgcGFnZSBdO1xuXG4gIC8vICAgaWYgKHBhZ2UgPT0gMSkgcmV0dXJuIHBhZ2VzO1xuXG4gIC8vICAgbGV0IGlzU3ByZWFkID0gc3ByZWFkTW9kZSA9PSBTcHJlYWRNb2RlVHlwZS5FVkVOIHx8IFNwcmVhZE1vZGVUeXBlLk9ERDtcbiAgLy8gICAvLyBjb25zb2xlLmxvZyhcImlzU3ByZWFkOiBcIiArIGlzU3ByZWFkKyBcIiwgcGFnZXM6IFwiICsgcGFnZXMuam9pbihcIixcIikpO1xuICAvLyAgIGlmICghaXNTcHJlYWQpIHJldHVybiBwYWdlcztcblxuICAvLyAgIGlmIChwYWdlICUgMiA9PSAxKSB7XG4gIC8vICAgICBwYWdlLS07XG4gIC8vICAgICBwYWdlcyA9IFsgcGFnZSBdO1xuICAvLyAgIH1cbiAgLy8gICAvLyBpZiAocGFnZSAlIDIgPT0gMSlcbiAgLy8gICBsZXQgbmV4dFBhZ2UgPSBwYWdlICsgMTtcbiAgLy8gICBpZiAobmV4dFBhZ2UgPD0gcGFnZUNvdW50KSBwYWdlcy5wdXNoKG5leHRQYWdlKTtcbiAgLy8gICAvLyBjb25zb2xlLmxvZyhcIm5leHRQYWdlOiBcIiArIG5leHRQYWdlICsgXCIsIHBhZ2VDb3VudDogXCIgKyBwYWdlQ291bnQrIFwiLCBwYWdlczogXCIgKyBwYWdlcy5qb2luKFwiLFwiKSk7XG4gIC8vICAgcmV0dXJuICBwYWdlcztcbiAgLy8gfVxuXG4gIHByaXZhdGUgZGVidWdQb2ludCh4OiBudW1iZXIsIHk6IG51bWJlciwgdmlld2VyOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5kZWJ1Z1BvaW50KSByZXR1cm47XG4gICAgY29uc3Qgdmlld2VyQ29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpZXdlckNvbnRhaW5lcicpIGFzIEhUTUxEaXZFbGVtZW50O1xuICAgIGxldCBpZCA9ICdkZWJ1Zy1wb2ludCcgKyAodmlld2VyID8gXCItdmlld2VyXCIgOiBcIlwiKTtcblxuICAgIGxldCBwb2ludCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgICBsZXQgc2l6ZSA9IHZpZXdlciA/IDEwIDogNTtcbiAgICBpZiAoIXBvaW50KSB7XG4gICAgICBwb2ludCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBwb2ludC5pZCA9IGlkO1xuICAgICAgcG9pbnQuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICBwb2ludC5zdHlsZS53aWR0aCA9IHNpemUgKyBcInB4XCI7XG4gICAgICBwb2ludC5zdHlsZS5oZWlnaHQgPSBzaXplICsgXCJweFwiO1xuICAgICAgcG9pbnQuc3R5bGUuYm9yZGVyUmFkaXVzID0gXCIxMDBweFwiO1xuXG4gICAgICBwb2ludC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB2aWV3ZXIgPyBcInJlZFwiIDogXCJibHVlXCI7XG5cbiAgICAgIGlmICghdmlld2VyKSB2aWV3ZXJDb250YWluZXIuYXBwZW5kQ2hpbGQocG9pbnQpO1xuICAgICAgZWxzZSB0aGlzLnZpZXdlci5hcHBlbmRDaGlsZChwb2ludCk7XG4gICAgfVxuXG5cblxuXG4gICAgbGV0IGRpbXMgPSB0aGlzLmdldERpbWVuc2lvbnModGhpcy52aWV3ZXIpO1xuXG4gICAgaWYgKHZpZXdlcikge1xuICAgICAgLy8gdGhpcy5kZWJ1Zy54diA9IHg7XG4gICAgICAvLyB0aGlzLmRlYnVnLnl2ID0geTtcblxuICAgICAgLy8gY29uc29sZS5sb2coXCJkZWJ1Z1BvaW50LnZpZXdlcjogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh4KSArIFwiIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh5KSArIFwiLCB8IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoeCAvIGRpbXMuZWxlbS53aWR0aCAqIDEwMCkgKyBcIiAlIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh5IC8gZGltcy5lbGVtLmhlaWdodCAqIDEwMCkgKyBcIiAlLCBkaW1zOiBcIiwgZGltcy5lbGVtKTtcblxuXG4gICAgICAvLyBsZXQgdnRzID0gdGhpcy5nZXRWaWV3ZXJUcmFuc2Zvcm1TY2FsZSgpO1xuICAgICAgLy8gaWYodnRzICE9IDEuMCkge1xuICAgICAgLy8gICB4IC89IHZ0cztcbiAgICAgIC8vICAgeSAvPSB2dHM7XG4gICAgICAvLyAgIGNvbnNvbGUubG9nKFwiZGVidWdQb2ludC52aWV3ZXI6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoeCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoeSkpO1xuICAgICAgLy8gfVxuXG4gICAgfSBlbHNlIHtcblxuICAgICAgdGhpcy5kZWJ1Zy54ID0geDtcbiAgICAgIHRoaXMuZGVidWcueSA9IHk7XG5cblxuICAgICAgLy8gY29uc29sZS5sb2coXCJkZWJ1Z1BvaW50LmNvbnQ6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoeCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoeSkgKyBcIiB8IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoeCAvIGRpbXMucGFyZW50LndpZHRoICogMTAwKSArIFwiICUgLyAgXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh5IC8gZGltcy5wYXJlbnQuaGVpZ2h0ICogMTAwKSArIFwiICUsIGRpbXM6IFwiLCBkaW1zLnBhcmVudCk7XG5cbiAgICB9XG5cblxuICAgIHBvaW50LnN0eWxlLmxlZnQgPSAoeCAtIChzaXplIC8gMikpICsgXCJweFwiO1xuICAgIHBvaW50LnN0eWxlLnRvcCA9ICh5IC0gKHNpemUgLyAyKSkgKyBcInB4XCI7XG5cblxuICB9XG5cbiAgcHJpdmF0ZSBvblZpZXdlclRvdWNoTW92ZShldmVudDogVG91Y2hFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZGlzYWJsZUV2ZW50SGFuZGxpbmcpIHJldHVybjtcblxuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uT3B0aW9uczogSVBERlZpZXdlckFwcGxpY2F0aW9uT3B0aW9ucyA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbk9wdGlvbnM7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IGFueSA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcblxuICAgIGNvbnN0IHZpZXdlckNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3ZXJDb250YWluZXInKSBhcyBIVE1MRGl2RWxlbWVudDtcbiAgICBjb25zdCByZWN0ID0gdmlld2VyQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHZyID0gdGhpcy52aWV3ZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBpZiAodGhpcy5pbml0aWFsUGluY2hEaXN0YW5jZSA8PSAwIHx8IGV2ZW50LnRvdWNoZXMubGVuZ3RoICE9PSAyKSB7XG5cblxuICAgICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09IDEgJiYgdGhpcy5zdGF0ZSA9PSBcIm1vdmVcIikge1xuICAgICAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07XG5cblxuICAgICAgICBsZXQgcGFnZVggPSB0b3VjaC5wYWdlWCAtIHJlY3QubGVmdCArIHZpZXdlckNvbnRhaW5lci5zY3JvbGxMZWZ0O1xuICAgICAgICBsZXQgcGFnZVkgPSB0b3VjaC5wYWdlWSAtIHJlY3QudG9wICsgdmlld2VyQ29udGFpbmVyLnNjcm9sbFRvcDtcblxuICAgICAgICBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSB0aGlzLmRlYnVnUG9pbnQocGFnZVgsIHBhZ2VZKTtcblxuICAgICAgICBsZXQgZGlmZlggPSBwYWdlWCAtIHRoaXMuc3RhcnRYO1xuICAgICAgICBsZXQgZGlmZlkgPSBwYWdlWSAtIHRoaXMuc3RhcnRZO1xuXG4gICAgICAgIGxldCBsZWZ0ID0gdGhpcy5zdGFydExlZnQgKyBkaWZmWDtcbiAgICAgICAgbGV0IHRvcCA9IHRoaXMuc3RhcnRUb3AgKyBkaWZmWTtcblxuICAgICAgICBsZXQgY29uc3RyYWluID0gdGhpcy5jb25zdHJhaW4oeyBsZWZ0OiBsZWZ0LCB0b3A6IHRvcCB9KTtcbiAgICAgICAgbGVmdCA9IGNvbnN0cmFpbi5sZWZ0O1xuICAgICAgICB0b3AgPSBjb25zdHJhaW4udG9wO1xuXG4gICAgICAgIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIlRvdWNoTW92ZTogXCJcbiAgICAgICAgICAgICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQocGFnZVgpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHBhZ2VZKVxuICAgICAgICAgICAgKyBcIiwgc3RhcnRYL1k6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodGhpcy5zdGFydFgpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMuc3RhcnRZKVxuICAgICAgICAgICAgKyBcIiwgZGlmZjogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChkaWZmWCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoZGlmZlkpXG4gICAgICAgICAgICArIFwiLCBsL3Q6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQobGVmdCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodG9wKVxuICAgICAgICAgICAgKyBcIiwgdmlld2VyLncvaDogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh2ci53aWR0aCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodnIuaGVpZ2h0KVxuXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudmlld2VyLnN0eWxlLmxlZnQgPSBsZWZ0ICsgXCJweFwiO1xuICAgICAgICB0aGlzLnZpZXdlci5zdHlsZS50b3AgPSB0b3AgKyBcInB4XCI7XG5cbiAgICAgICAgaWYgKGV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGluY2hEaXN0YW5jZSA9IE1hdGguaHlwb3QoZXZlbnQudG91Y2hlc1sxXS5wYWdlWCAtIGV2ZW50LnRvdWNoZXNbMF0ucGFnZVgsIGV2ZW50LnRvdWNoZXNbMV0ucGFnZVkgLSBldmVudC50b3VjaGVzWzBdLnBhZ2VZKTtcbiAgICAvLyBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlld2VyQ29udGFpbmVyJykgYXMgSFRNTERpdkVsZW1lbnQ7XG4gICAgLy8gY29uc3QgY29udGFpbmVyUmVjdCA9IGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGxldCBwYWdlWCA9IChldmVudC50b3VjaGVzWzFdLnBhZ2VYICsgZXZlbnQudG91Y2hlc1swXS5wYWdlWCkgLyAyO1xuICAgIGxldCBwYWdlWSA9IChldmVudC50b3VjaGVzWzFdLnBhZ2VZICsgZXZlbnQudG91Y2hlc1swXS5wYWdlWSkgLyAyO1xuXG4gICAgdGhpcy5tb3ZlWCA9IHBhZ2VYO1xuICAgIHRoaXMubW92ZVkgPSBwYWdlWTtcblxuXG4gICAgbGV0IGRpbXMgPSB0aGlzLmdldERpbWVuc2lvbnModGhpcy52aWV3ZXIsIHsgcGFnZVg6IHBhZ2VYLCBwYWdlWTogcGFnZVkgfSlcblxuXG4gICAgLy8gLy9jb25zdCB2aWV3ZXJSZWN0ID0gdGhpcy52aWV3ZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgLy8gcGFnZVggLT0gcmVjdC5sZWZ0O1xuICAgIC8vIHBhZ2VZIC09IHJlY3QudG9wO1xuXG4gICAgLy8gcGFnZVggLT0gdnIubGVmdDtcbiAgICAvLyBwYWdlWSAtPSB2ci50b3A7XG5cblxuICAgIC8vIHBhZ2VYID0gZGltcy5zY2FsZWQud2lkdGggKiBkaW1zLnBvaW50LnYueHA7XG4gICAgLy8gcGFnZVkgPSBkaW1zLnNjYWxlZC5oZWlnaHQgKiBkaW1zLnBvaW50LnYueXA7XG5cblxuICAgIC8vIGxldCBvcmlnaW5YID0gcGFnZVg7IC8vICsgdmlld2VyQ29udGFpbmVyLnNjcm9sbExlZnQ7IC8vIHRoaXMuc3RhcnRYICsgY29udGFpbmVyLnNjcm9sbExlZnQ7XG4gICAgLy8gbGV0IG9yaWdpblkgPSBwYWdlWTsgLy8gKyB2aWV3ZXJDb250YWluZXIuc2Nyb2xsVG9wIDsgLy90aGlzLnN0YXJ0WSArIGNvbnRhaW5lci5zY3JvbGxUb3A7XG5cbiAgICBjb25zdCBvcmlnaW5YID0gZGltcy5zY2FsZWQud2lkdGggKiBkaW1zLnBvaW50LnYueHA7XG4gICAgY29uc3Qgb3JpZ2luWSA9IGRpbXMuc2NhbGVkLmhlaWdodCAqIGRpbXMucG9pbnQudi55cDtcblxuXG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgdGhpcy5kZWJ1Z1BvaW50KHRoaXMubW92ZVggLSByZWN0LmxlZnQsIHRoaXMubW92ZVkgLSByZWN0LnRvcCk7XG5cbiAgICBsZXQgcHJldlNjYWxlID0gdGhpcy5jdXJyZW50U2NhbGU7XG4gICAgdGhpcy5jdXJyZW50U2NhbGUgPSBwaW5jaERpc3RhbmNlIC8gdGhpcy5pbml0aWFsUGluY2hEaXN0YW5jZTtcbiAgICBsZXQgbWluWm9vbSA9IE51bWJlcihQREZWaWV3ZXJBcHBsaWNhdGlvbk9wdGlvbnMuZ2V0KCdtaW5ab29tJykpO1xuICAgIGlmICghbWluWm9vbSkge1xuICAgICAgbWluWm9vbSA9IDAuMTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50Wm9vbSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5fY3VycmVudFNjYWxlO1xuICAgIGlmIChjdXJyZW50Wm9vbSAqIHRoaXMuY3VycmVudFNjYWxlIDwgbWluWm9vbSkge1xuICAgICAgdGhpcy5jdXJyZW50U2NhbGUgPSBtaW5ab29tIC8gY3VycmVudFpvb207XG4gICAgfVxuICAgIGxldCBtYXhab29tID0gTnVtYmVyKFBERlZpZXdlckFwcGxpY2F0aW9uT3B0aW9ucy5nZXQoJ21heFpvb20nKSk7XG4gICAgaWYgKCFtYXhab29tKSB7XG4gICAgICBtYXhab29tID0gMTA7XG4gICAgfVxuICAgIGlmIChjdXJyZW50Wm9vbSAqIHRoaXMuY3VycmVudFNjYWxlID4gbWF4Wm9vbSkge1xuICAgICAgdGhpcy5jdXJyZW50U2NhbGUgPSBtYXhab29tIC8gY3VycmVudFpvb207XG4gICAgfVxuXG5cblxuXG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkge1xuICAgICAgY29uc29sZS5sb2coXCJUb3VjaE1vdmUgUElOQ0g6IFwiXG4gICAgICAgICsgXCIsIHN0YXJ0WC9ZOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMuc3RhcnRYKSArIFwiIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh0aGlzLnN0YXJ0WSlcbiAgICAgICAgKyBcIiwgbW92ZVgvWTogXCIgKyArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMubW92ZVgpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMubW92ZVkpXG4gICAgICAgICsgXCIsIHJlY3QubC90OiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHJlY3QubGVmdCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQocmVjdC50b3ApXG4gICAgICAgICsgXCIsIHZpZXdlci5sL3Q6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodnIubGVmdCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodnIudG9wKVxuICAgICAgICAvLyArIFwiLCB2aWV3ZXJDb250YWluZXIuc2wvc3Q6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodmlld2VyQ29udGFpbmVyLnNjcm9sbExlZnQpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHZpZXdlckNvbnRhaW5lci5zY3JvbGxUb3ApXG4gICAgICAgICsgXCIsIG9yaWdpblgvWTogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChvcmlnaW5YKSArIFwiIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChvcmlnaW5ZKVxuXG4gICAgICAgICsgXCIsIHZpZXdlci53L2g6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodnIud2lkdGgpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHZyLmhlaWdodClcbiAgICAgICAgKyBcIiwgY3VycmVudFNjYWxlOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHByZXZTY2FsZSkgKyBcIiAtPiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMuY3VycmVudFNjYWxlKVxuICAgICAgICArIFwiLCBkaW1zOiBcIiwgZGltc1xuXG5cbiAgICAgICk7XG4gICAgfVxuXG5cbiAgICB0aGlzLnZpZXdlci5zdHlsZS50cmFuc2Zvcm0gPSBgc2NhbGUoJHt0aGlzLmN1cnJlbnRTY2FsZX0pYDtcbiAgICB0aGlzLnZpZXdlci5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgJHtvcmlnaW5YfXB4ICR7b3JpZ2luWX1weGA7XG5cbiAgICAvLyB0aGlzLnRyYW5zZm9ybVNjYWxlID0gdGhpcy5jdXJyZW50U2NhbGU7XG5cblxuXG4gICAgaWYgKGV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHJpdmF0ZSBvblZpZXdlclRvdWNoRW5kKGV2ZW50OiBUb3VjaEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlRXZlbnRIYW5kbGluZykgcmV0dXJuO1xuXG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgY29uc29sZS5sb2coXCJvblZpZXdlclRvdWNoRW5kXCJcbiAgICAgICsgXCIsIHZ0czogXCIgKyB0aGlzLmdldFZpZXdlclRyYW5zZm9ybVNjYWxlKFwib25WaWV3ZXJUb3VjaEVuZFwiKVxuICAgICAgKyAnLCBzdGF0ZTogJyArIHRoaXMuc3RhdGVcbiAgICAgICsgXCIsIGluaXRpYWxQaW5jaERpc3RhbmNlOiBcIiArIHRoaXMuaW5pdGlhbFBpbmNoRGlzdGFuY2VcbiAgICApO1xuXG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IGFueSA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcblxuXG4gICAgLy8gbGV0IHRvID0gdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtT3JpZ2luO1xuXG4gICAgLy8gdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtID0gYG5vbmVgO1xuICAgIC8vIHRoaXMudmlld2VyLnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGB1bnNldGA7XG5cbiAgICBsZXQgZGltc1N0YXJ0ID0gdGhpcy5nZXREaW1lbnNpb25zKHRoaXMudmlld2VyKTtcblxuXG4gICAgbGV0IHRsID0gZXZlbnQuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO1xuICAgIGxldCBwYWdlWCA9IHRoaXMubW92ZVg7XG4gICAgbGV0IHBhZ2VZID0gdGhpcy5tb3ZlWTtcblxuICAgIGlmICh0bCA+IDEpIHtcbiAgICAgIHBhZ2VYID0gKGV2ZW50LmNoYW5nZWRUb3VjaGVzWzFdLnBhZ2VYICsgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVgpIC8gMjtcbiAgICAgIHBhZ2VZID0gKGV2ZW50LmNoYW5nZWRUb3VjaGVzWzFdLnBhZ2VZICsgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVkpIC8gMjtcblxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIGNvbnNvbGUubG9nKFwiZW5kLm1vdmVYL1k6IFwiICsgdGhpcy5tb3ZlWCArIFwiIC0+IFwiICsgcGFnZVggKyBcIiwgbW92ZVk6IFwiICsgdGhpcy5tb3ZlWSArIFwiIC0+IFwiICsgcGFnZVkgKyBcIiwgdGw6IFwiICsgdGwpO1xuICAgIH1cblxuICAgIC8vIHRoaXMuY3VycmVudFNjYWxlID0gMTtcblxuXG5cbiAgICBsZXQgbm93ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgaWYgKHRoaXMucG9pbnRFbmQudGltZSkge1xuICAgICAgbGV0IHBlID0gdGhpcy5wb2ludEVuZDtcblxuICAgICAgbGV0IGRpZmYgPSBub3cgLSBwZS50aW1lO1xuICAgICAgLy8gY29uc29sZS5sb2coXCJwb2ludEVuZC5kaWZmOiBcIiArIGRpZmYpO1xuXG4gICAgICBpZiAocGUucGFnZVggPT0gcGFnZVggJiYgcGUucGFnZVkgPT0gcGFnZVkgJiYgZGlmZiA8IDMwMCkge1xuXG4gICAgICAgIGxldCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogYW55ID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgICAgICBsZXQgY3VycmVudFNjYWxlID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLmN1cnJlbnRTY2FsZTtcbiAgICAgICAgbGV0IHNjYWxlRmFjdG9yID0gMS40O1xuXG4gICAgICAgIGxldCBuZXdTY2FsZSA9IHRoaXMuaXNab29taW5nKCkgPyAoY3VycmVudFNjYWxlIC8gc2NhbGVGYWN0b3IpIDogKGN1cnJlbnRTY2FsZSAqIHNjYWxlRmFjdG9yKTtcblxuICAgICAgICAvLyBsZXQgbmV3U2NhbGUgPSBjdXJyZW50U2NhbGUgKiAxLjI7XG4gICAgICAgIC8vIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIGNvbnNvbGUubG9nKFwicG9pbnRFbmQucG9pbnQgbWF0ZWNoZXMsIG5ldyBzY2FsZTogXCIgKyBuZXdTY2FsZSk7XG5cbiAgICAgICAgaWYgKHRoaXMuaW5pdGlhbFBpbmNoRGlzdGFuY2UgPD0gMCB8fCB0aGlzLnN0YXRlID09IFwibW92ZVwiKSB7XG4gICAgICAgICAgaWYgKGV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgICB0aGlzLnNldFZpZXdlclNjYWxlKG5ld1NjYWxlKTtcbiAgICAgICAgICB0aGlzLnBvaW50RW5kID0ge307XG4gICAgICAgIH0sIDUpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHRoaXMucG9pbnRFbmQgPSB7XG4gICAgICB0aW1lOiBub3csXG4gICAgICBwYWdlWDogcGFnZVgsXG4gICAgICBwYWdlWTogcGFnZVlcbiAgICB9XG5cblxuICAgIGlmICh0aGlzLnN0YXRlID09IFwibW92ZVwiKSB7XG4gICAgICB0aGlzLnJlc2V0UGluY2hab29tUGFyYW1zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaW5pdGlhbFBpbmNoRGlzdGFuY2UgPD0gMCkge1xuICAgICAgdGhpcy5yZXNldFBpbmNoWm9vbVBhcmFtcygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG4gICAgbGV0IGN1cnJlbnRTY2FsZSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5jdXJyZW50U2NhbGU7XG4gICAgbGV0IG5ld1NjYWxlID0gY3VycmVudFNjYWxlICogdGhpcy5jdXJyZW50U2NhbGU7XG4gICAgLy8gbGV0IHNjYWxlQ2hhbmdlID0gMSArIChuZXdTY2FsZSAtIGN1cnJlbnRTY2FsZSkgLyBjdXJyZW50U2NhbGU7XG5cblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3ZXJDb250YWluZXInKSBhcyBIVE1MRGl2RWxlbWVudDtcbiAgICBjb25zdCByZWN0ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHZpZXdlclJlY3QgPSB0aGlzLnZpZXdlci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGxldCBkaW1zID0gdGhpcy5nZXREaW1lbnNpb25zKHRoaXMudmlld2VyKTtcblxuXG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgdGhpcy5kZWJ1Z1BvaW50KHBhZ2VYLCBwYWdlWSk7XG5cblxuXG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkge1xuICAgICAgY29uc29sZS5sb2coXCJUb3VjaEVuZDogXCJcbiAgICAgICAgKyBcIiwgc2NhbGU6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoY3VycmVudFNjYWxlKSArIFwiIC0+IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQobmV3U2NhbGUpICsgXCIsIGNzOiBcIiArIHRoaXMuY3VycmVudFNjYWxlXG5cbiAgICAgICAgKyBcIiwgcGFnZVgvWTogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChwYWdlWCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQocGFnZVkpXG4gICAgICAgICsgXCIsIHN0YXJ0WC9ZOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMuc3RhcnRYKSArIFwiIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh0aGlzLnN0YXJ0WSlcbiAgICAgICAgLy8gKyBcIiwgZGlmZjogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChkaWZmWCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoZGlmZlkpXG4gICAgICAgIC8vICsgXCIsIGRpZmZzOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KGRpZmZYcykgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoZGlmZllzKVxuXG4gICAgICAgIC8vICsgXCIsIGwvdDogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh2aWV3ZXJSZWN0LmxlZnQpICsgXCIgLT4gXCIgK3RoaXMuZGVidWcubmYuZm9ybWF0KGxlZnQpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHZpZXdlclJlY3QudG9wKSArIFwiIC0+IFwiICt0aGlzLmRlYnVnLm5mLmZvcm1hdCh0b3ApXG4gICAgICAgICsgXCIsIHZpZXdlci53L2g6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodmlld2VyUmVjdC53aWR0aCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodmlld2VyUmVjdC5oZWlnaHQpXG4gICAgICAgICsgXCIsIGRpbXM6IFwiLCBkaW1zXG5cbiAgICAgICk7XG4gICAgfVxuXG5cbiAgICB0aGlzLnNldFZpZXdlclNjYWxlKG5ld1NjYWxlLCB7IHJlc2V0VHJhbnNmb3JtOiB0cnVlIH0pO1xuXG5cbiAgICB0aGlzLnJlc2V0UGluY2hab29tUGFyYW1zKCk7XG5cbiAgICAvLyB9LCA1MCk7XG5cbiAgICBpZiAoZXZlbnQuY2FuY2VsYWJsZSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cblxuICAgIC8vIGlmICh0bCA9PSAxKSB7XG4gICAgLy8gbGV0IHBhZ2VYID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVg7XG4gICAgLy8gbGV0IHBhZ2VZID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVk7XG5cblxuXG4gICAgLy8gfVxuICB9XG5cblxuICBwcml2YXRlIG9uVmlld2VyTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlRXZlbnRIYW5kbGluZykgcmV0dXJuO1xuXG4gICAgbGV0IGlzSW5zaWRlID0gdGhpcy5pc0luc2lkZUNvbnRhaW5lcihbZXZlbnRdKVxuICAgIGlmICghaXNJbnNpZGUpIHJldHVybjtcblxuICAgIGlmICghdGhpcy5vcHRpb25zLm1vdmVFbmFibGVkKSByZXR1cm47XG5cbiAgICBsZXQgZGltcyA9IHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlciwgZXZlbnQpO1xuXG4gICAgLy8gdGhpcy56b29tVG9Qb2ludChldmVudCwgZXZlbnQucGFnZVgsIGV2ZW50LnBhZ2VZKTtcbiAgICBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSB7XG4gICAgICB0aGlzLmRlYnVnUG9pbnQoZGltcy5wb2ludC5jLngsIGRpbXMucG9pbnQuYy55KTtcbiAgICAgIHRoaXMuZGVidWdQb2ludChkaW1zLnBvaW50LnYueCwgZGltcy5wb2ludC52LngsIHRydWUpO1xuICAgIH1cblxuXG4gICAgdGhpcy5zdGFydFggPSBkaW1zLnBvaW50LmMueDtcbiAgICB0aGlzLnN0YXJ0WSA9IGRpbXMucG9pbnQuYy55O1xuXG4gICAgdGhpcy5zdGFydExlZnQgPSBwYXJzZUZsb2F0KGdldENvbXB1dGVkU3R5bGUodGhpcy52aWV3ZXIpLmxlZnQpIHx8IDA7XG4gICAgdGhpcy5zdGFydFRvcCA9IHBhcnNlRmxvYXQoZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnZpZXdlcikudG9wKSB8fCAwXG5cbiAgICB0aGlzLnN0YXRlID0gXCJtb3ZlXCI7XG5cbiAgICBpZiAoZXZlbnQuY2FuY2VsYWJsZSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgfVxuICBwcml2YXRlIG9uVmlld2VyTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlRXZlbnRIYW5kbGluZykgcmV0dXJuO1xuXG4gICAgaWYgKHRoaXMuc3RhdGUgIT0gXCJtb3ZlXCIpIHtcbiAgICAgIC8vIGNvbnNvbGUubG9nKFwibW91c2Vtb3ZlOiBzdGF0ZSE9bW92ZTogXCIgKyB0aGlzLnN0YXRlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgZGltcyA9IHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlciwgZXZlbnQpO1xuXG5cbiAgICBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSB0aGlzLmRlYnVnUG9pbnQoZGltcy5wb2ludC5jLngsIGRpbXMucG9pbnQuYy55KTtcblxuICAgIGxldCBkaWZmWCA9IGRpbXMucG9pbnQuYy54IC0gdGhpcy5zdGFydFg7XG4gICAgbGV0IGRpZmZZID0gZGltcy5wb2ludC5jLnkgLSB0aGlzLnN0YXJ0WTtcblxuICAgIGxldCBsZWZ0ID0gdGhpcy5zdGFydExlZnQgKyBkaWZmWDtcbiAgICBsZXQgdG9wID0gdGhpcy5zdGFydFRvcCArIGRpZmZZO1xuXG4gICAgbGV0IGNvbnN0cmFpbiA9IHRoaXMuY29uc3RyYWluKHsgbGVmdDogbGVmdCwgdG9wOiB0b3AgfSk7XG4gICAgbGVmdCA9IGNvbnN0cmFpbi5sZWZ0O1xuICAgIHRvcCA9IGNvbnN0cmFpbi50b3A7XG5cblxuICAgIHRoaXMudmlld2VyLnN0eWxlLmxlZnQgPSBsZWZ0ICsgXCJweFwiO1xuICAgIHRoaXMudmlld2VyLnN0eWxlLnRvcCA9IHRvcCArIFwicHhcIjtcblxuXG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkge1xuICAgICAgY29uc29sZS5sb2coXCJtb3VzZW1vdmU6IFwiXG4gICAgICAgICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoZGltcy5wb2ludC5jLngpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KGRpbXMucG9pbnQuYy55KVxuICAgICAgICArIFwiLCBkaWZmOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KGRpZmZYKSArIFwiIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChkaWZmWSlcbiAgICAgICAgKyBcIiwgbC90OiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KGxlZnQpICsgXCIgLyBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRvcClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG5cbiAgfVxuICBwcml2YXRlIG9uVmlld2VyTW91c2VVcChldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZGlzYWJsZUV2ZW50SGFuZGxpbmcpIHJldHVybjtcblxuICAgIGxldCBpc0luc2lkZSA9IHRoaXMuaXNJbnNpZGVDb250YWluZXIoW2V2ZW50XSk7XG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgY29uc29sZS5sb2coXCJtb3VzZXVwOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KGV2ZW50LnBhZ2VYKSArIFwiIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChldmVudC5wYWdlWSkgKyBcIjsgaW5zaWRlOiBcIiArIGlzSW5zaWRlKTtcbiAgICAvLyBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIGV2ZW50KTtcblxuICAgIGlmICghaXNJbnNpZGUpIHJldHVybjtcblxuICAgIHRoaXMucmVzZXRQaW5jaFpvb21QYXJhbXMoKTtcblxuICAgIC8vVE9ETzoga2FuIGlra2UgYnJ1a2UgcHJldmVudERlZmF1bHQgaHZpcyB2aSBza2FsIGt1bm5lIHN0w7h0dGUgZG9iYmVsdGtsaWtrXG5cbiAgICBpZiAoZXZlbnQuY2FuY2VsYWJsZSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBsZXQgcGFnZVggPSBldmVudC5wYWdlWDtcbiAgICBsZXQgcGFnZVkgPSBldmVudC5wYWdlWTtcbiAgICBsZXQgbm93ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgaWYgKHRoaXMucG9pbnRFbmQudGltZSkge1xuICAgICAgbGV0IHBlID0gdGhpcy5wb2ludEVuZDtcblxuICAgICAgbGV0IGRpZmYgPSBub3cgLSBwZS50aW1lO1xuICAgICAgLy8gY29uc29sZS5sb2coXCJwb2ludEVuZC5kaWZmOiBcIiArIGRpZmYpO1xuXG4gICAgICBpZiAocGUucGFnZVggPT0gcGFnZVggJiYgcGUucGFnZVkgPT0gcGFnZVkgJiYgZGlmZiA8IDMwMCkge1xuXG4gICAgICAgIGxldCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogYW55ID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgICAgICBsZXQgY3VycmVudFNjYWxlID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLmN1cnJlbnRTY2FsZTtcbiAgICAgICAgbGV0IHNjYWxlRmFjdG9yID0gMS40O1xuXG4gICAgICAgIGxldCBuZXdTY2FsZSA9IHRoaXMuaXNab29taW5nKCkgPyAoY3VycmVudFNjYWxlIC8gc2NhbGVGYWN0b3IpIDogKGN1cnJlbnRTY2FsZSAqIHNjYWxlRmFjdG9yKTtcbiAgICAgICAgLy8gaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgY29uc29sZS5sb2coXCJwb2ludEVuZC5wb2ludCBtYXRlY2hlcywgaXNaOiBcIit0aGlzLmlzWm9vbWluZygpICtcIiwgbmV3IHNjYWxlOiBcIiArIGN1cnJlbnRTY2FsZSArIFwiIC0+IFwiICsgbmV3U2NhbGUpO1xuXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgICAgdGhpcy5zZXRWaWV3ZXJTY2FsZShuZXdTY2FsZSk7XG4gICAgICAgICAgdGhpcy5wb2ludEVuZCA9IHt9O1xuICAgICAgICB9LCA1KTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICB0aGlzLnBvaW50RW5kID0ge1xuICAgICAgdGltZTogbm93LFxuICAgICAgcGFnZVg6IHBhZ2VYLFxuICAgICAgcGFnZVk6IHBhZ2VZXG4gICAgfVxuXG5cblxuICAgIC8vIGNvbnNvbGUubG9nKFwidXBkYXRlaW5nIHBvaW50RW5kOiBcIiwgdGhpcy5wb2ludEVuZCk7XG5cblxuICB9XG5cblxuICBwcml2YXRlIHJlc2V0UGluY2hab29tUGFyYW1zKCk6IHZvaWQge1xuICAgIHRoaXMuc3RhcnRYID0gdGhpcy5zdGFydFkgPSB0aGlzLm1vdmVYID0gdGhpcy5tb3ZlWSA9IHRoaXMuc3RhcnRMZWZ0ID0gdGhpcy5zdGFydFRvcCA9IHRoaXMuaW5pdGlhbFBpbmNoRGlzdGFuY2UgPSAwO1xuICAgIHRoaXMuY3VycmVudFNjYWxlID0gMTtcbiAgICB0aGlzLnN0YXRlID0gXCJpZGxlXCI7XG4gIH1cblxuICBwcml2YXRlIGdldEJveFN0eWxlKFxuICAgIGVsZW06IEhUTUxFbGVtZW50IHwgU1ZHRWxlbWVudCxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgc3R5bGU6IENTU1N0eWxlRGVjbGFyYXRpb24gPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKVxuICApIHtcbiAgICBjb25zdCBzdWZmaXggPSBuYW1lID09PSAnYm9yZGVyJyA/ICdXaWR0aCcgOiAnJ1xuICAgIHJldHVybiB7XG4gICAgICBsZWZ0OiBwYXJzZUZsb2F0KHN0eWxlW2Ake25hbWV9TGVmdCR7c3VmZml4fWBdKSB8fCAwLFxuICAgICAgcmlnaHQ6IHBhcnNlRmxvYXQoc3R5bGVbYCR7bmFtZX1SaWdodCR7c3VmZml4fWBdKSB8fCAwLFxuICAgICAgdG9wOiBwYXJzZUZsb2F0KHN0eWxlW2Ake25hbWV9VG9wJHtzdWZmaXh9YF0pIHx8IDAsXG4gICAgICBib3R0b206IHBhcnNlRmxvYXQoc3R5bGVbYCR7bmFtZX1Cb3R0b20ke3N1ZmZpeH1gXSkgfHwgMCxcbiAgICB9XG4gIH1cblxuXG4gIHByaXZhdGUgZ2V0RGltZW5zaW9ucyhlbGVtOiBIVE1MRWxlbWVudCwgcG9pbnQ/OiAoeyBwYWdlWDogbnVtYmVyLCBwYWdlWTogbnVtYmVyIH0pKSB7XG4gICAgY29uc3QgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlIGFzIEhUTUxFbGVtZW50XG4gICAgY29uc3Qgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKVxuICAgIGNvbnN0IHBhcmVudFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFyZW50KVxuICAgIGNvbnN0IHJlY3RFbGVtID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIGNvbnN0IHJlY3RQYXJlbnQgPSBwYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcblxuXG4gICAgY29uc3QgdnRzID0gdGhpcy5nZXRWaWV3ZXJUcmFuc2Zvcm1TY2FsZShcImdldERpbWVuc2lvbnNcIik7XG4gICAgY29uc3QgdnRvID0gdGhpcy5nZXRWaWV3ZXJUcmFuc2Zvcm1PcmlnaW4oKTtcblxuICAgIGxldCByZXM6IGFueSA9IHtcbiAgICAgIGVsZW06IHtcbiAgICAgICAgc3R5bGUsXG4gICAgICAgIHdpZHRoOiByZWN0RWxlbS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiByZWN0RWxlbS5oZWlnaHQsXG4gICAgICAgIHRvcDogcmVjdEVsZW0udG9wLFxuICAgICAgICBib3R0b206IHJlY3RFbGVtLmJvdHRvbSxcbiAgICAgICAgbGVmdDogcmVjdEVsZW0ubGVmdCxcbiAgICAgICAgcmlnaHQ6IHJlY3RFbGVtLnJpZ2h0LFxuICAgICAgICBtYXJnaW46IHRoaXMuZ2V0Qm94U3R5bGUoZWxlbSwgJ21hcmdpbicsIHN0eWxlKSxcbiAgICAgICAgYm9yZGVyOiB0aGlzLmdldEJveFN0eWxlKGVsZW0sICdib3JkZXInLCBzdHlsZSlcbiAgICAgIH0sXG4gICAgICByZWw6IHtcbiAgICAgICAgd2lkdGg6IHJlY3RFbGVtLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHJlY3RFbGVtLmhlaWdodCxcbiAgICAgICAgdG9wOiByZWN0RWxlbS50b3AgLSByZWN0UGFyZW50LnRvcCxcbiAgICAgICAgbGVmdDogcmVjdEVsZW0ubGVmdCAtIHJlY3RQYXJlbnQubGVmdCxcbiAgICAgICAgYm90dG9tOiByZWN0RWxlbS5ib3R0b20gLSByZWN0UGFyZW50LnRvcCxcbiAgICAgICAgcmlnaHQ6IHJlY3RFbGVtLnJpZ2h0IC0gcmVjdFBhcmVudC5sZWZ0LFxuICAgICAgfSxcblxuICAgICAgcGFyZW50OiB7XG4gICAgICAgIHN0eWxlOiBwYXJlbnRTdHlsZSxcbiAgICAgICAgd2lkdGg6IHJlY3RQYXJlbnQud2lkdGgsXG4gICAgICAgIGhlaWdodDogcmVjdFBhcmVudC5oZWlnaHQsXG4gICAgICAgIHRvcDogcmVjdFBhcmVudC50b3AsXG4gICAgICAgIGJvdHRvbTogcmVjdFBhcmVudC5ib3R0b20sXG4gICAgICAgIGxlZnQ6IHJlY3RQYXJlbnQubGVmdCxcbiAgICAgICAgcmlnaHQ6IHJlY3RQYXJlbnQucmlnaHQsXG4gICAgICAgIHBhZGRpbmc6IHRoaXMuZ2V0Qm94U3R5bGUocGFyZW50LCAncGFkZGluZycsIHBhcmVudFN0eWxlKSxcbiAgICAgICAgYm9yZGVyOiB0aGlzLmdldEJveFN0eWxlKHBhcmVudCwgJ2JvcmRlcicsIHBhcmVudFN0eWxlKVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAodnRzID09IDEuMCkgcmVzLnNjYWxlZCA9IHJlcy5yZWw7XG4gICAgZWxzZSB7XG4gICAgICBsZXQgc3cgPSByZXMucmVsLndpZHRoIC8gdnRzO1xuICAgICAgbGV0IHNoID0gcmVzLnJlbC5oZWlnaHQgLyB2dHM7XG4gICAgICBsZXQgd2QgPSByZXMucmVsLndpZHRoIC0gc3c7ICAvLyAxMThcbiAgICAgIGxldCBoZCA9IHJlcy5yZWwuaGVpZ2h0IC0gc2g7XG5cblxuICAgICAgcmVzLnNjYWxlZCA9IHtcbiAgICAgICAgdnRzOiB2dHMsXG4gICAgICAgIHZ0bzogdnRvLFxuICAgICAgICB3aWR0aDogc3csXG4gICAgICAgIGhlaWdodDogc2gsXG5cbiAgICAgICAgbGVmdDogcmVzLnJlbC5sZWZ0ICsgd2QgLyAyLFxuICAgICAgICByaWdodDogcmVzLnJlbC5yaWdodCAtIHdkIC8gMixcbiAgICAgICAgdG9wOiByZXMucmVsLnRvcCArIGhkIC8gMixcbiAgICAgICAgYm90dG9tOiByZXMucmVsLmJvdHRvbSAtIGhkIC8gMixcblxuICAgICAgICB3ZDogd2QsXG4gICAgICAgIGhkOiBoZCxcbiAgICAgIH1cbiAgICB9XG5cblxuXG4gICAgbGV0IHZ4ID0gcG9pbnQgPyBwb2ludC5wYWdlWCAtIHJlY3RFbGVtLmxlZnQgOiByZWN0RWxlbS53aWR0aCAvIDI7XG4gICAgbGV0IHZ5ID0gcG9pbnQgPyBwb2ludC5wYWdlWSAtIHJlY3RFbGVtLnRvcCA6IHJlY3RFbGVtLmhlaWdodCAvIDI7XG5cbiAgICBsZXQgY3ggPSBwb2ludCA/IHBvaW50LnBhZ2VYIC0gcmVjdFBhcmVudC5sZWZ0IDogdnggKyByZXMucmVsLmxlZnQ7XG4gICAgbGV0IGN5ID0gcG9pbnQgPyBwb2ludC5wYWdlWSAtIHJlY3RQYXJlbnQudG9wIDogdnkgKyByZXMucmVsLnRvcDtcblxuICAgIGxldCB2eHAgPSB2eCAvIHJlY3RFbGVtLndpZHRoO1xuICAgIGxldCB2eXAgPSB2eSAvIHJlY3RFbGVtLmhlaWdodDtcbiAgICBsZXQgY3hwID0gY3ggLyByZWN0UGFyZW50LndpZHRoO1xuICAgIGxldCBjeXAgPSBjeSAvIHJlY3RQYXJlbnQuaGVpZ2h0O1xuXG4gICAgcmVzLnBvaW50ID0ge1xuICAgICAgc3JjOiBwb2ludCxcbiAgICAgIHY6IHtcbiAgICAgICAgeDogdngsXG4gICAgICAgIHk6IHZ5LFxuICAgICAgICB4cDogdnhwLFxuICAgICAgICB5cDogdnlwXG4gICAgICB9LFxuICAgICAgYzoge1xuICAgICAgICB4OiBjeCxcbiAgICAgICAgeTogY3ksXG4gICAgICAgIHhwOiBjeHAsXG4gICAgICAgIHlwOiBjeXBcbiAgICAgIH1cbiAgICB9XG5cblxuXG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cblxuXG4gIC8vICAgcmV0dXJuIHJlcztcbiAgLy8gfVxuXG4gIHByaXZhdGUgZ2V0RGltRGlmZihzdGFydDogYW55LCBlbmQ6IGFueSkge1xuICAgIC8vIGxldCBzZSA9IHN0YXJ0LmVsZW07XG4gICAgLy8gbGV0IGVlID0gZW5kLmVsZW07XG4gICAgLy8gbGV0IHNwID0gc3RhcnQucGFyZW50O1xuICAgIC8vIGxldCBlcCA9IGVuZC5wYXJlbnQ7XG5cbiAgICBsZXQgaW5wdXQgPSB7XG4gICAgICBlbGVtOiB7XG4gICAgICAgIHN0YXJ0OiBzdGFydC5lbGVtLFxuICAgICAgICBlbmQ6IGVuZC5lbGVtXG4gICAgICB9LFxuICAgICAgcGFyZW50OiB7XG4gICAgICAgIHN0YXJ0OiBzdGFydC5wYXJlbnQsXG4gICAgICAgIGVuZDogZW5kLnBhcmVudFxuICAgICAgfSxcbiAgICAgIHJlbDoge1xuICAgICAgICBzdGFydDogc3RhcnQucmVsLFxuICAgICAgICBlbmQ6IGVuZC5yZWxcbiAgICAgIH0sXG4gICAgICBzY2FsZWQ6IHtcbiAgICAgICAgc3RhcnQ6IHN0YXJ0LnNjYWxlZCxcbiAgICAgICAgZW5kOiBlbmQuc2NhbGVkXG4gICAgICB9LFxuICAgIH1cblxuICAgIGxldCByZXM6IGFueSA9IHt9O1xuICAgIGZvciAobGV0IHR5cGUgb2YgW1wiZWxlbVwiLCBcInBhcmVudFwiLCBcInJlbFwiLCBcInNjYWxlZFwiXSkge1xuICAgICAgbGV0IHMgPSBpbnB1dFt0eXBlXS5zdGFydDtcbiAgICAgIGxldCBlID0gaW5wdXRbdHlwZV0uZW5kO1xuXG4gICAgICByZXNbdHlwZV0gPSB7fTtcblxuICAgICAgZm9yIChsZXQgcHJvcCBvZiBbXCJ3aWR0aFwiLCBcImhlaWdodFwiLCBcInRvcFwiLCBcImJvdHRvbVwiLCBcImxlZnRcIiwgXCJyaWdodFwiXSkge1xuICAgICAgICBsZXQgc3YgPSBzW3Byb3BdO1xuICAgICAgICBsZXQgZXYgPSBlW3Byb3BdO1xuICAgICAgICBsZXQgZGlmZiA9IGV2IC0gc3Y7XG5cbiAgICAgICAgcmVzW3R5cGVdW3Byb3AgKyBcIkxhYmVsXCJdID0gdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoc3YpICsgXCIgLT4gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChldikgKyBcIiwgZGlmZjogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChkaWZmKSArIFwiIChcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KGRpZmYgLyBzdiAqIDEwMC4wKSArIFwiICUpXCI7XG4gICAgICAgIHJlc1t0eXBlXVtwcm9wXSA9IGRpZmY7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcblxuXG4gIH1cblxuXG4gIHByaXZhdGUgY29uc3RyYWluKHA6ICh7IGxlZnQ6IG51bWJlciwgdG9wOiBudW1iZXIgfSkpOiAoeyBsZWZ0OiBudW1iZXIsIHRvcDogbnVtYmVyIH0pIHtcbiAgICBjb25zdCBkaW1zID0gdGhpcy5nZXREaW1lbnNpb25zKHRoaXMudmlld2VyKVxuXG4gICAgbGV0IGlzU2NhbGVkID0gZGltcy5zY2FsZWQudnRzICE9PSB1bmRlZmluZWQgJiYgZGltcy5zY2FsZWQudnRzICE9IDEuMDtcblxuICAgIGxldCBtaW5YID0gcC5sZWZ0LCBtYXhYID0gcC5sZWZ0LCBtaW5ZID0gcC50b3AsIG1heFkgPSBwLnRvcDtcblxuICAgIGlmIChkaW1zLmVsZW0ud2lkdGggPD0gZGltcy5wYXJlbnQud2lkdGgpIHtcbiAgICAgIC8vIGluc2lkZVxuICAgICAgbWluWCA9IDA7XG4gICAgICBtYXhYID0gKGRpbXMucGFyZW50LndpZHRoIC0gZGltcy5lbGVtLndpZHRoKVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBvdXRzaWRlXG4gICAgICBtaW5YID0gLShkaW1zLmVsZW0ud2lkdGggLSBkaW1zLnBhcmVudC53aWR0aCk7XG4gICAgICBtYXhYID0gMDtcblxuICAgIH1cbiAgICBpZiAoZGltcy5lbGVtLmhlaWdodCA8PSBkaW1zLnBhcmVudC5oZWlnaHQpIHtcbiAgICAgIC8vIGluc2lkZVxuICAgICAgbWluWSA9IDA7XG4gICAgICBtYXhZID0gKGRpbXMucGFyZW50LmhlaWdodCAtIGRpbXMuZWxlbS5oZWlnaHQpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG91dHNpZGVcbiAgICAgIG1pblkgPSAtKGRpbXMuZWxlbS5oZWlnaHQgLSBkaW1zLnBhcmVudC5oZWlnaHQpO1xuICAgICAgbWF4WSA9IDA7XG5cbiAgICB9XG5cbiAgICBpZiAoaXNTY2FsZWQpIHtcbiAgICAgIGxldCB2dG8gPSBkaW1zLnNjYWxlZC52dG87XG4gICAgICBsZXQgeHAgPSB2dG8gPyB2dG8ueCAvIGRpbXMuc2NhbGVkLndpZHRoIDogMC41O1xuICAgICAgbGV0IHlwID0gdnRvID8gdnRvLnkgLyBkaW1zLnNjYWxlZC5oZWlnaHQgOiAwLjU7XG5cbiAgICAgIG1pblggKz0gZGltcy5zY2FsZWQud2QgKiB4cDtcbiAgICAgIG1heFggKz0gZGltcy5zY2FsZWQud2QgKiB4cDtcblxuICAgICAgbWluWSArPSBkaW1zLnNjYWxlZC5oZCAqIHlwO1xuICAgICAgbWF4WSArPSBkaW1zLnNjYWxlZC5oZCAqIHlwO1xuICAgIH1cblxuXG5cbiAgICBsZXQgY0xlZnQgPSBNYXRoLm1heChNYXRoLm1pbihwLmxlZnQsIG1heFgpLCBtaW5YKVxuICAgIGxldCBjVG9wID0gTWF0aC5tYXgoTWF0aC5taW4ocC50b3AsIG1heFkpLCBtaW5ZKVxuXG4gICAgLy8gaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgY29uc29sZS5sb2coXCJjb25zdHJhaW4sIGxlZnQ6ICBcIiArIHAubGVmdCArIFwiIC0+IFwiICsgY0xlZnQgKyBcIiAoXCIrbWluWCArIFwiLVwiK21heFgrXCIpXCIgKyBcIiwgdG9wOiBcIiArIHAudG9wICsgXCIgLT4gXCIgKyBjVG9wICsgXCIgKFwiK21pblkgKyBcIi1cIittYXhZK1wiKSwgZGltczogXCIsIGRpbXMpO1xuXG4gICAgcmV0dXJuIHsgbGVmdDogY0xlZnQsIHRvcDogY1RvcCB9O1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luc2lkZUNvbnRhaW5lcihwb2ludHM6ICh7IHBhZ2VYOiBudW1iZXIsIHBhZ2VZOiBudW1iZXIsIHRhcmdldDogYW55IH0pW10pIHtcbiAgICBjb25zdCB2aWV3ZXJDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlld2VyQ29udGFpbmVyJykgYXMgSFRNTERpdkVsZW1lbnQ7XG4gICAgY29uc3QgcmVjdCA9IHZpZXdlckNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGlmIChwb2ludHMgPT09IHVuZGVmaW5lZCB8fCBwb2ludHMubGVuZ3RoID09IDApIHJldHVybiBmYWxzZTtcblxuICAgIC8vVE9ETzogQ2hlY2sgZXZlbnQsIGlzIHRhcmdldC5wYXJlbnQgdGhlIHZpZXdlckNvbnRhaW5lcj8gXG5cbiAgICAvLyBsZXQgYWxsSW5zaWRlID0gdHJ1ZTtcbiAgICBmb3IgKGxldCBwb2ludCBvZiBwb2ludHMpIHtcblxuICAgICAgbGV0IHRhcmdldCA9IHBvaW50LnRhcmdldDtcbiAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgbGV0IGNsb3Nlc3QgPSB0YXJnZXQuY2xvc2VzdChcIiN2aWV3ZXJDb250YWluZXJcIik7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwiY2xvc2VzdDogXCIsIGNsb3Nlc3QpXG4gICAgICAgIGlmIChjbG9zZXN0ID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG5cbiAgICAgIGxldCBwYWdlWCA9IHBvaW50LnBhZ2VYOyAvLyArIHZpZXdlckNvbnRhaW5lci5zY3JvbGxMZWZ0O1xuICAgICAgbGV0IHBhZ2VZID0gcG9pbnQucGFnZVk7IC8vICsgdmlld2VyQ29udGFpbmVyLnNjcm9sbFRvcDtcblxuXG4gICAgICBsZXQgaW5zaWRlID0gZmFsc2U7XG4gICAgICBpZiAocGFnZVggPj0gcmVjdC5sZWZ0ICYmIHBhZ2VYIDw9IHJlY3QucmlnaHQpIHtcbiAgICAgICAgaWYgKHBhZ2VZID49IChyZWN0LnRvcCArIHdpbmRvdy5zY3JvbGxZKSAmJiBwYWdlWSA8PSAocmVjdC5ib3R0b20gKyB3aW5kb3cuc2Nyb2xsWSkpIHtcbiAgICAgICAgICBpbnNpZGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGNvbnNvbGUubG9nKFwicGFnZVgvWTogXCIgKyBwYWdlWCArIFwiIC8gXCIgKyBwYWdlWSArIFwiLCBpbnNpZGU6IFwiICsgaW5zaWRlICsgXCI7IHJlY3Q6IFwiLCByZWN0LCBcIiwgcG9pbnQ6IFwiLCBwb2ludCk7XG5cbiAgICAgIGlmICghaW5zaWRlKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGdldFZpZXdlclRyYW5zZm9ybVNjYWxlKHNyYzogc3RyaW5nKSB7XG4gICAgbGV0IHRmID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnZpZXdlcikudHJhbnNmb3JtO1xuXG4gICAgaWYgKHRmID09IFwibm9uZVwiIHx8IHRmLmluZGV4T2YoXCIoXCIpIDwgMCkge1xuICAgICAgbGV0IHZ0cyA9IDEuMDtcblxuICAgICAgLy8gaWYgKHRoaXMudHJhbnNmb3JtU2NhbGUgPiAwLjApIHtcbiAgICAgIC8vICAgdnRzID0gdGhpcy50cmFuc2Zvcm1TY2FsZVxuICAgICAgLy8gfVxuXG4gICAgICAvLyBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSBjb25zb2xlLmxvZyhcImdldFZpZXdlclRyYW5zZm9ybVNjYWxlLCB0ZjogXCIgKyB0ZiArIFwiLCBpbmRleE9mICg6IFwiICsgdGYuaW5kZXhPZihcIihcIikgKyBcIiwgc3JjOiBcIiArIHNyYyArIFwiLCB2dHM6IFwiICsgdnRzKTtcblxuICAgICAgcmV0dXJuIHZ0cztcbiAgICB9XG5cbiAgICBsZXQgaXNTY2FsZSA9IHRmLmluZGV4T2YoXCJzY2FsZVwiKSA+PSAwO1xuICAgIGxldCB0cmFuc2Zvcm1TY2FsZSA9IHBhcnNlRmxvYXQoXG4gICAgICB0Zi5zdWJzdHJpbmcodGYuaW5kZXhPZihcIihcIikgKyAxLFxuICAgICAgICB0Zi5pbmRleE9mKGlzU2NhbGUgPyBcIilcIiA6IFwiLFwiKSlcbiAgICApO1xuICAgIC8vIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIGNvbnNvbGUubG9nKFwiZ2V0Vmlld2VyVHJhbnNmb3JtU2NhbGUsIHRmOiBcIiArIHRmICsgXCIsIGluZGV4T2YgKDogXCIgKyB0Zi5pbmRleE9mKFwiKFwiKSArIFwiLCB0cmFuc2Zvcm1TY2FsZTogXCIgKyB0cmFuc2Zvcm1TY2FsZSArIFwiLCBzcmM6IFwiICsgc3JjKTtcbiAgICByZXR1cm4gdHJhbnNmb3JtU2NhbGU7XG4gIH1cblxuICBwcml2YXRlIGdldFZpZXdlclRyYW5zZm9ybU9yaWdpbigpIHtcbiAgICBsZXQgdG8gPSB0aGlzLnZpZXdlci5zdHlsZS50cmFuc2Zvcm1PcmlnaW47XG4gICAgaWYgKHRvID09IHVuZGVmaW5lZCB8fCB0byA9PSBcInVuc2V0XCIpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBsZXQgcGFydHMgPSB0by5zcGxpdChcIiBcIik7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAyKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgcmV0dXJuIHsgeDogcGFyc2VGbG9hdChwYXJ0c1swXSksIHk6IHBhcnNlRmxvYXQocGFydHNbMV0pIH07XG4gIH1cblxuICBwdWJsaWMgY2hlY2tDb250cmFpbnQoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGltcyA9IHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcik7XG4gICAgbGV0IGNvbnN0cmFpbjogYW55ID0gdGhpcy5jb25zdHJhaW4oeyBsZWZ0OiBkaW1zLmVsZW0ubGVmdCwgdG9wOiBkaW1zLmVsZW0udG9wIH0pO1xuICAgIHJldHVybiBjb25zdHJhaW4ubGVmdCAhPSBkaW1zLmVsZW0ubGVmdCAmJiBjb25zdHJhaW4udG9wICE9IGRpbXMuZWxlbS50b3A7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlVmlld2VyUG9zaXRpb24oZm9yY2VVcGRhdGU6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGxldCB2aWV3ZXJDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlld2VyQ29udGFpbmVyJykgYXMgSFRNTERpdkVsZW1lbnQ7XG4gICAgdGhpcy52aWV3ZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlld2VyJykgYXMgSFRNTERpdkVsZW1lbnQ7XG5cbiAgICBjb25zdCBkaW1zID0gdGhpcy5nZXREaW1lbnNpb25zKHRoaXMudmlld2VyKTtcblxuXG4gICAgbGV0IGNvbnN0cmFpbjogYW55ID0gdGhpcy5jb25zdHJhaW4oeyBsZWZ0OiBkaW1zLmVsZW0ubGVmdCwgdG9wOiBkaW1zLmVsZW0udG9wIH0pOyAvLyA7XG4gICAgbGV0IHRyYW5zZm9ybVNjYWxlID0gdGhpcy5nZXRWaWV3ZXJUcmFuc2Zvcm1TY2FsZShcInVwZGF0ZVZpZXdlclBvc2l0aW9uXCIpO1xuXG4gICAgLy8gaWYgKHRyYW5zZm9ybVNjYWxlID09IDEuMClcblxuICAgIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIHtcbiAgICAgIC8vIGNvbnNvbGUubG9nKFwidXBkYXRlVmlld2VyUG9zaXRpb25cIlxuICAgICAgLy8gICArIFwiLCB1cGRhdGVMZWZ0OiBcIiArIChkaW1zLmVsZW0ud2lkdGggPD0gZGltcy5wYXJlbnQud2lkdGgpIFxuICAgICAgLy8gICArIFwiLCB1cGRhdGVUb3A6IFwiICsgKGRpbXMuZWxlbS5oZWlnaHQgPD0gZGltcy5wYXJlbnQuaGVpZ2h0KVxuICAgICAgLy8gICArIFwiLCBjaGVja0NvbnRyYWludDogXCIgKyB0aGlzLmNoZWNrQ29udHJhaW50KClcbiAgICAgIC8vICAgKyBcIiwgdHJhbnNmb3JtU2NhbGU6IFwiICsgdHJhbnNmb3JtU2NhbGUgXG4gICAgICAvLyAgICsgXCIsIGRpbXM6IFwiLCBkaW1zKTtcblxuICAgIH1cbiAgICBsZXQgcG9pbnQ6ICh7IGxlZnQ6IG51bWJlciB8IHVuZGVmaW5lZCwgdG9wOiBudW1iZXIgfCB1bmRlZmluZWQgfSkgPSB7XG4gICAgICBsZWZ0OiB1bmRlZmluZWQsXG4gICAgICB0b3A6IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChmb3JjZVVwZGF0ZSB8fCBkaW1zLmVsZW0ud2lkdGggPD0gZGltcy5wYXJlbnQud2lkdGggfHwgKGNvbnN0cmFpbiAmJiBjb25zdHJhaW4ubGVmdCAhPSBkaW1zLmVsZW0ubGVmdCkpIHtcbiAgICAgIGxldCBsZWZ0ID0gKGRpbXMucGFyZW50LndpZHRoIC0gKGRpbXMuZWxlbS53aWR0aCAvIHRyYW5zZm9ybVNjYWxlKSkgLyAyO1xuICAgICAgLy8gY29uc29sZS5sb2coXCJ1cGRhdGVWaWV3ZXJQb3NpdGlvbiwgbGVmdDogXCIgKyB0aGlzLnZpZXdlci5zdHlsZS5sZWZ0ICArIFwiIC0+IFwiICsgbGVmdCk7XG4gICAgICAvLyB0aGlzLnZpZXdlci5zdHlsZS5sZWZ0ID0gbGVmdCArIFwicHhcIjtcbiAgICAgIHBvaW50LmxlZnQgPSBsZWZ0O1xuICAgIH1cbiAgICBpZiAoZm9yY2VVcGRhdGUgfHwgZGltcy5lbGVtLmhlaWdodCA8PSBkaW1zLnBhcmVudC5oZWlnaHQgfHwgKGNvbnN0cmFpbiAmJiBjb25zdHJhaW4udG9wICE9IGRpbXMuZWxlbS50b3ApKSB7XG4gICAgICBsZXQgdG9wID0gKGRpbXMucGFyZW50LmhlaWdodCAtIChkaW1zLmVsZW0uaGVpZ2h0IC8gdHJhbnNmb3JtU2NhbGUpKSAvIDI7XG4gICAgICAvLyBjb25zb2xlLmxvZyhcInVwZGF0ZVZpZXdlclBvc2l0aW9uLCB0b3A6IFwiICsgdGhpcy52aWV3ZXIuc3R5bGUudG9wICArIFwiIC0+IFwiICsgdG9wKTtcbiAgICAgIC8vIHRoaXMudmlld2VyLnN0eWxlLnRvcCA9IHRvcCArIFwicHhcIjtcbiAgICAgIHBvaW50LnRvcCA9IHRvcDtcbiAgICB9XG5cbiAgICBpZiAocG9pbnQubGVmdCB8fCBwb2ludC50b3ApIHtcblxuICAgICAgdGhpcy52aWV3ZXIuc3R5bGUubGVmdCA9IHBvaW50LmxlZnQgKyBcInB4XCI7XG4gICAgICB0aGlzLnZpZXdlci5zdHlsZS50b3AgPSBwb2ludC50b3AgKyBcInB4XCI7XG4gICAgfVxuXG4gIH1cblxuICBwcml2YXRlIHNldFZpZXdlclNjYWxlKG5ld1NjYWxlLCBvcHRpb25zOiBhbnkgPSB7fSkge1xuICAgIGxldCB2dHNTb3VyY2UgPSBnZXRDb21wdXRlZFN0eWxlKHRoaXMudmlld2VyKS50cmFuc2Zvcm07XG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgY29uc29sZS5sb2coXCJzZXRWaWV3ZXJTY2FsZSwgbmV3U2NhbGU6IFwiICsgbmV3U2NhbGUgKyBcIiwgdnRzU291cmNlOiBcIiArIHZ0c1NvdXJjZSk7XG5cbiAgICBsZXQgb3JpZ2luID0gb3B0aW9ucy5vcmlnaW47XG4gICAgLy8gbGV0IHJlc2V0VHJhbnNmb3JtID0gb3B0aW9ucy5yZXNldFRyYW5zZm9ybSA9PT0gdW5kZWZpbmVkIHx8IG9wdGlvbnMucmVzZXRUcmFuc2Zvcm0gPT09IHRydWU7IFxuXG4gICAgbGV0IHZ0cyA9IHRoaXMuZ2V0Vmlld2VyVHJhbnNmb3JtU2NhbGUoXCJzZXRWaWV3ZXJTY2FsZVwiKTtcblxuXG4gICAgbGV0IGRpbXMgPSB0aGlzLmdldERpbWVuc2lvbnModGhpcy52aWV3ZXIpO1xuICAgIC8vIGxldCBkaW1zQWZ0ZXJUcmFuc2Zvcm1SZXNldCA9IGRpbXM7IFxuXG4gICAgbGV0IHJlc2V0OiBhbnkgPSB7IGxlZnQ6IHVuZGVmaW5lZCwgdG9wOiB1bmRlZmluZWQgfTtcblxuICAgIGlmICh2dHMgIT0gMS4wKSB7IC8vIHJlc2V0VHJhbnNmb3JtICYmIFxuXG4gICAgICBpZiAodnRzU291cmNlICE9IFwibm9uZVwiKSB7XG5cbiAgICAgICAgcmVzZXQubGVmdCA9IGRpbXMucmVsLmxlZnQ7XG4gICAgICAgIHJlc2V0LnRvcCA9IGRpbXMucmVsLnRvcDtcbiAgICAgIH1cblxuICAgICAgdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtID0gJ25vbmUnO1xuICAgICAgdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gJ3Vuc2V0JztcblxuICAgICAgLy8gdGhpcy50cmFuc2Zvcm1TY2FsZSA9IC0xO1xuICAgICAgLy8gZGltc0FmdGVyVHJhbnNmb3JtUmVzZXQgPSB0aGlzLmdldERpbWVuc2lvbnModGhpcy52aWV3ZXIpO1xuXG4gICAgfVxuXG4gICAgbGV0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBhbnkgPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG4gICAgbGV0IGN1cnJlbnRTY2FsZSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5jdXJyZW50U2NhbGU7XG5cbiAgICBpZiAob3JpZ2luID09IHVuZGVmaW5lZCkge1xuICAgICAgb3JpZ2luID0geyB4OiBkaW1zLmVsZW0ud2lkdGggLyAyLCB5OiBkaW1zLmVsZW0uaGVpZ2h0IC8gMiB9O1xuICAgIH1cblxuICAgIGxldCBveHAgPSBvcmlnaW4ueCAvIGRpbXMuZWxlbS53aWR0aDtcbiAgICBsZXQgb3lwID0gb3JpZ2luLnkgLyBkaW1zLmVsZW0uaGVpZ2h0O1xuXG4gICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkge1xuICAgICAgY29uc29sZS5sb2coXCJzZXRWaWV3ZXJTY2FsZSwgY3VycmVudFNjYWxlOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KGN1cnJlbnRTY2FsZSkgKyBcIiAtPiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KG5ld1NjYWxlKSArIFwiLCB2dHM6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQodnRzKSArIFwiIChcIiArIHZ0c1NvdXJjZSArIFwiKVwiXG4gICAgICAgICsgXCIsIG9yaWdpbjogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChvcmlnaW4ueCkgKyBcIiAoXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChveHAgKiAxMDApICsgXCIpIC8gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChvcmlnaW4ueSkgKyBcIiAoXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChveXAgKiAxMDApICsgXCIpXCJcbiAgICAgICAgKyBcIiwgZGVidWcueC9ZOiBcIiArIHRoaXMuZGVidWcubmYuZm9ybWF0KHRoaXMuZGVidWcueCkgKyBcIiAvIFwiICsgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdCh0aGlzLmRlYnVnLnkpXG4gICAgICAgICsgXCIsIGlzWm9vbWluZzogXCIgKyB0aGlzLmlzWm9vbWluZygpXG4gICAgICAgICsgXCIsIGRpbXM6IFwiLCBkaW1zKTtcbiAgICB9XG5cbiAgICBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIuX3NldFNjYWxlKG5ld1NjYWxlLCB0cnVlKTtcblxuICAgIGxldCBkaW1zQWZ0ZXIgPSB0aGlzLmdldERpbWVuc2lvbnModGhpcy52aWV3ZXIpO1xuICAgIGxldCBkaW1EaWZmID0gdGhpcy5nZXREaW1EaWZmKGRpbXMsIGRpbXNBZnRlcik7XG5cbiAgICBsZXQgZGltc0NvcnI6IGFueSA9IHtcbiAgICAgIGxlZnQ6IHBhcnNlRmxvYXQoZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnZpZXdlcikubGVmdCkgfHwgMCxcbiAgICAgIHRvcDogcGFyc2VGbG9hdChnZXRDb21wdXRlZFN0eWxlKHRoaXMudmlld2VyKS50b3ApIHx8IDAsXG4gICAgfVxuICAgIGRpbXNDb3JyLmxlZnREaWZmID0gLSAoZGltRGlmZi5lbGVtLndpZHRoICogb3hwKTtcbiAgICBkaW1zQ29yci50b3BEaWZmID0gLSAoZGltRGlmZi5lbGVtLmhlaWdodCAqIG95cCk7XG5cbiAgICBkaW1zQ29yci5sZWZ0TmV4dCA9IGRpbXNDb3JyLmxlZnQgKyBkaW1zQ29yci5sZWZ0RGlmZjtcbiAgICBkaW1zQ29yci50b3BOZXh0ID0gZGltc0NvcnIudG9wICsgZGltc0NvcnIudG9wRGlmZjtcblxuICAgIGlmIChyZXNldC5sZWZ0KSB7XG4gICAgICBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiZGltc0NvcnIubGVmdE5leHQ6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoZGltc0NvcnIubGVmdE5leHQpICsgXCIgLT4gXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChyZXNldC5sZWZ0KSk7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiZGltc0NvcnIudG9wTmV4dDogXCIgKyB0aGlzLmRlYnVnLm5mLmZvcm1hdChkaW1zQ29yci50b3BOZXh0KSArIFwiIC0+IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQocmVzZXQudG9wKSk7XG4gICAgICB9XG5cbiAgICAgIGRpbXNDb3JyLmxlZnROZXh0ID0gcmVzZXQubGVmdDtcbiAgICAgIGRpbXNDb3JyLnRvcE5leHQgPSByZXNldC50b3A7XG5cbiAgICB9XG5cbiAgICB0aGlzLnZpZXdlci5zdHlsZS5sZWZ0ID0gZGltc0NvcnIubGVmdE5leHQgKyBcInB4XCI7XG4gICAgdGhpcy52aWV3ZXIuc3R5bGUudG9wID0gZGltc0NvcnIudG9wTmV4dCArIFwicHhcIjtcblxuICAgIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIHtcbiAgICAgIGNvbnNvbGUubG9nKFwic2V0Vmlld2VyU2NhbGUyLCBuZXdDdXJyZW50U2NhbGU6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQoUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLmN1cnJlbnRTY2FsZSlcbiAgICAgICAgKyBcIiwgaXNab29taW5nOiBcIiArIHRoaXMuaXNab29taW5nKClcbiAgICAgICAgKyBcIiwgZGltc0FmdGVyOiBcIiwgZGltc0FmdGVyLFxuICAgICAgICBcIiwgZGltRGlmZjogXCIsIGRpbURpZmYsXG4gICAgICAgIFwiLCBkaW1zQ29ycjogXCIsIGRpbXNDb3JyXG4gICAgICApO1xuICAgIH1cblxuICB9XG5cbiAgaXNab29taW5nKCkge1xuICAgIGxldCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogYW55ID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uT3B0aW9uczogSVBERlZpZXdlckFwcGxpY2F0aW9uT3B0aW9ucyA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbk9wdGlvbnM7XG5cbiAgICBsZXQgY3VycmVudFNjYWxlID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLmN1cnJlbnRTY2FsZTtcblxuICAgIGxldCBjemYgPSBNYXRoLnJvdW5kKGN1cnJlbnRTY2FsZSAqIDEwMDAwKTtcblxuICAgIGxldCBtaW5ab29tID0gTWF0aC5yb3VuZChOdW1iZXIoUERGVmlld2VyQXBwbGljYXRpb25PcHRpb25zLmdldCgnbWluWm9vbScpKSAqIDEwMDAwKTtcbiAgICAvLyAgY29uc29sZS5sb2coXCJpc1pvb21pbmcsIGN6ZjogXCIgICsgY3pmICsgXCIsIG1pblpvb206IFwiICsgbWluWm9vbSArIFwiOyBpc1o6IFwiICsgKGN6ZiA+IG1pblpvb20pKTtcbiAgICByZXR1cm4gY3pmID4gbWluWm9vbTtcbiAgfVxuXG4gIG9uVmlld2VyV2hlZWwoZXZlbnQ6IEV2ZW50KSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlRXZlbnRIYW5kbGluZykgcmV0dXJuO1xuICAgIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIGNvbnNvbGUubG9nKFwib25XaGVlbDogZXZlbnQ6IFwiLCBldmVudCk7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcblxuICAgICAgdGhpcy51cGRhdGVWaWV3ZXJQb3NpdGlvbigpO1xuICAgIH0sIDIpXG5cbiAgfTtcblxuICBwdWJsaWMgaW5pdGlhbGl6ZVJlbGF0aXZlQ29vcmRzKCk6IHZvaWQge1xuXG4gICAgbGV0IHZpZXdlckNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3ZXJDb250YWluZXInKSBhcyBIVE1MRGl2RWxlbWVudDtcbiAgICB0aGlzLnZpZXdlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3ZXInKSBhcyBIVE1MRGl2RWxlbWVudDtcblxuICAgIHRoaXMuY29tcG9uZW50LnJvb3QubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKFwicmVsYXRpdmUtY29vcmRzXCIpO1xuXG4gICAgbGV0IHN0Zkl0ZW1IYWNrID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBzdGZJdGVtSGFjay5jbGFzc0xpc3QuYWRkKFwic3RmX19pdGVtXCIpO1xuICAgIHZpZXdlckNvbnRhaW5lci5hcHBlbmRDaGlsZChzdGZJdGVtSGFjayk7XG5cblxuICAgIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIGNvbnNvbGUubG9nKFwiaW5pdGlhbGl6ZVJlbGF0aXZlQ29vcmRzOiBpc01vYmlsZTogXCIgKyB0aGlzLmlzTW9iaWxlKCkpO1xuXG4gICAgbGV0IG9uQ29udGFpbmVyU2NvbGwgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgICAvL2NvbnNvbGUubG9nKFwib25Db250YWluZXJTY29sbDogbC90OiBcIiArIHZpZXdlckNvbnRhaW5lci5zY3JvbGxMZWZ0ICsgXCIgLyBcIiArIHZpZXdlckNvbnRhaW5lci5zY3JvbGxUb3AgKyBcIiwgZXZlbnQ6IFwiICwgZXZlbnQpO1xuICAgICAgaWYgKHZpZXdlckNvbnRhaW5lci5zY3JvbGxMZWZ0ICE9IDAgfHwgdmlld2VyQ29udGFpbmVyLnNjcm9sbFRvcCAhPSAwKSB2aWV3ZXJDb250YWluZXIuc2Nyb2xsKHsgbGVmdDogMCwgdG9wOiAwIH0pXG4gICAgfVxuXG4gICAgdmlld2VyQ29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIG9uQ29udGFpbmVyU2NvbGwpO1xuXG5cbiAgICB0aGlzLmNvbXBvbmVudC5wYWdlc0xvYWRlZC5zdWJzY3JpYmUoYXN5bmMgKGV2ZW50OiBQYWdlc0xvYWRlZEV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSBjb25zb2xlLmxvZyhcImluaXRpYWxpemVSZWxhdGl2ZUNvb3Jkczogc2Nyb2xsVG9wOiBcIiwgdmlld2VyQ29udGFpbmVyLnNjcm9sbFRvcCk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJwYWdlQ2hhbmdlOiBwYWdlczogXCIsIHRoaXMuZ2V0Q3VycmVudFBhZ2VzSW5WaWV3KCkpXG4gICAgICAgIHRoaXMudXBkYXRlVmlld2VyUG9zaXRpb24odHJ1ZSk7XG4gICAgICB9LCAxMCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbXBvbmVudC5wYWdlQ2hhbmdlLnN1YnNjcmliZShhc3luYyAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVidWcuZW5hYmxlZCkgY29uc29sZS5sb2coXCJwYWdlQ2hhbmdlOiBldmVudDogXCIsIGV2ZW50LCBcIiwgZGltczogXCIsIHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcikpO1xuICAgICAgLy8gY29uc29sZS5sb2coXCJwYWdlQ2hhbmdlOiBwYWdlczogXCIsIHRoaXMuZ2V0Q3VycmVudFBhZ2VzSW5WaWV3KCkpXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJwYWdlQ2hhbmdlOiBwYWdlczogXCIsIHRoaXMuZ2V0Q3VycmVudFBhZ2VzSW5WaWV3KCkpXG4gICAgICAgIHRoaXMudXBkYXRlVmlld2VyUG9zaXRpb24odHJ1ZSk7XG4gICAgICB9LCAxMCk7XG5cbiAgICB9KTtcbiAgICAvLyB0aGlzLmNvbXBvbmVudC56b29tQ2hhbmdlLnN1YnNjcmliZShhc3luYyAoZXZlbnQ6IGFueSkgPT4ge1xuICAgIC8vICAgY29uc29sZS5sb2coXCJ6b29tQ2hhbmdlOiBldmVudDogXCIsIGV2ZW50KTtcbiAgICAvLyB9KTtcbiAgICB0aGlzLmNvbXBvbmVudC5jdXJyZW50Wm9vbUZhY3Rvci5zdWJzY3JpYmUoYXN5bmMgKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIGlmICh0aGlzLmRlYnVnLmVuYWJsZWQpIGNvbnNvbGUubG9nKFwiY3VycmVudFpvb21GYWN0b3I6IGV2ZW50OiBcIiwgZXZlbnQpO1xuICAgICAgLy8gdGhpcy51cGRhdGVWaWV3ZXJQb3NpdGlvbigpO1xuICAgIH0pO1xuXG4gICAgaWYgKCF0aGlzLmlzTW9iaWxlKCkpIHtcblxuICAgICAgLy8gbGV0IG9uV2hlZWwgPSBcblxuXG4gICAgICB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgLy8gUGFubmluZyBzdXBwb3J0IG9uIGRlc2t0b3BcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5ib3VuZE9uVmlld2VyTW91c2VEb3duKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5ib3VuZE9uVmlld2VyTW91c2VNb3ZlLCB7IHBhc3NpdmU6IGZhbHNlIH0pO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5ib3VuZE9uVmlld2VyTW91c2VVcCk7XG5cbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJ3aGVlbFwiLCB0aGlzLmJvdW5kT25WaWV3ZXJXaGVlbCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcblxuICAgICAgfSk7XG5cblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5ib3VuZE9uVmlld2VyVG91Y2hTdGFydCk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuYm91bmRPblZpZXdlclRvdWNoTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLmJvdW5kT25WaWV3ZXJUb3VjaEVuZCk7XG5cbiAgICAgIH0pO1xuXG5cbiAgICB9XG5cblxuXG5cbiAgICBpZiAodGhpcy5kZWJ1Zy5lbmFibGVkKSB7XG5cbiAgICAgIGxldCBvbktleXVwID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwib25LZXl1cDogZXZlbnQua2V5OiBcIiArIGV2ZW50LmtleSk7XG4gICAgICAgIGxldCBkaW1zID0gdGhpcy5nZXREaW1lbnNpb25zKHRoaXMudmlld2VyKTtcbiAgICAgICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IGFueSA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcblxuICAgICAgICBpZiAoZXZlbnQua2V5ID09IFwicVwiKSB7XG5cblxuXG4gICAgICAgICAgdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtID0gYG5vbmVgO1xuICAgICAgICAgIHRoaXMudmlld2VyLnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGB1bnNldGA7XG4gICAgICAgICAgdGhpcy5jdXJyZW50U2NhbGUgPSAxLjA7XG5cbiAgICAgICAgICBsZXQgZGltc0FmdGVyID0gdGhpcy5nZXREaW1lbnNpb25zKHRoaXMudmlld2VyKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcImRpbXNBZnRlcjogXCIsIGRpbXNBZnRlci5zY2FsZWQpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiZGltc0RpZmY6IFwiLCB0aGlzLmdldERpbURpZmYoZGltcywgZGltc0FmdGVyKS5zY2FsZWQpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09IFwid1wiKSB7XG4gICAgICAgICAgbGV0IG9yaWdpblggPSB0aGlzLmRlYnVnLnggfHwgZGltcy5wYXJlbnQud2lkdGggLyAyO1xuICAgICAgICAgIGxldCBvcmlnaW5ZID0gdGhpcy5kZWJ1Zy55IHx8IGRpbXMucGFyZW50LmhlaWdodCAvIDI7XG4gICAgICAgICAgb3JpZ2luWCAtPSBkaW1zLmVsZW0ubGVmdCAtIGRpbXMucGFyZW50LmxlZnQ7XG4gICAgICAgICAgb3JpZ2luWSAtPSBkaW1zLmVsZW0udG9wIC0gZGltcy5wYXJlbnQudG9wO1xuICAgICAgICAgIHRoaXMuY3VycmVudFNjYWxlID0gMS4zO1xuXG4gICAgICAgICAgY29uc29sZS5sb2coXCJvcmlnaW5YL1k6IFwiICsgb3JpZ2luWCArIFwiIC8gXCIgKyBvcmlnaW5ZICsgXCIsIHNjYWxlOiBcIiArIHRoaXMuY3VycmVudFNjYWxlICsgXCI7IGRpbXM6IFwiLCBkaW1zKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIm9yaWdpblgvWSAoJSk6IFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQob3JpZ2luWCAvIGRpbXMuZWxlbS53aWR0aCAqIDEwMCkgKyBcIiAvIFwiICsgdGhpcy5kZWJ1Zy5uZi5mb3JtYXQob3JpZ2luWSAvIGRpbXMuZWxlbS5oZWlnaHQgKiAxMDApKTtcblxuXG4gICAgICAgICAgdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtID0gYHNjYWxlKCR7dGhpcy5jdXJyZW50U2NhbGV9KWA7XG4gICAgICAgICAgdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gYCR7b3JpZ2luWH1weCAke29yaWdpbll9cHhgO1xuXG4gICAgICAgICAgbGV0IGRpbXNBZnRlciA9IHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcik7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJkaW1zQWZ0ZXI6IFwiLCBkaW1zQWZ0ZXIuZWxlbSk7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJkaW1zRGlmZjogXCIsIHRoaXMuZ2V0RGltRGlmZihkaW1zLCBkaW1zQWZ0ZXIpLmVsZW0pO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09IFwiZVwiKSB7XG5cbiAgICAgICAgICAvLyB0aGlzLnZpZXdlci5zdHlsZS50cmFuc2Zvcm0gPSBgbm9uZWA7XG4gICAgICAgICAgLy8gdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gYHVuc2V0YDtcblxuXG4gICAgICAgICAgbGV0IGN1cnJlbnRTY2FsZSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5jdXJyZW50U2NhbGU7XG4gICAgICAgICAgbGV0IG5ld1NjYWxlID0gY3VycmVudFNjYWxlICogdGhpcy5jdXJyZW50U2NhbGU7XG5cbiAgICAgICAgICBjb25zb2xlLmxvZyhcImN1cnJlbnRTY2FsZTogXCIgKyBjdXJyZW50U2NhbGUgKyBcIiAtPiBcIiArIG5ld1NjYWxlICsgXCIsIGNzOiBcIiArIHRoaXMuY3VycmVudFNjYWxlICsgXCIsIGRpbXM6IFwiLCBkaW1zKTtcblxuXG4gICAgICAgICAgLy8gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLl9zZXRTY2FsZShuZXdTY2FsZSwgdHJ1ZSk7XG4gICAgICAgICAgdGhpcy5zZXRWaWV3ZXJTY2FsZShuZXdTY2FsZSwgeyByZXNldFRyYW5zZm9ybTogdHJ1ZSB9KTtcblxuICAgICAgICAgIGxldCBkaW1zQWZ0ZXIgPSB0aGlzLmdldERpbWVuc2lvbnModGhpcy52aWV3ZXIpO1xuXG4gICAgICAgICAgY29uc29sZS5sb2coXCJkaW1zQWZ0ZXI6IFwiLCBkaW1zQWZ0ZXIuZWxlbSk7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJkaW1zRGlmZjogXCIsIHRoaXMuZ2V0RGltRGlmZihkaW1zLCBkaW1zQWZ0ZXIpLmVsZW0pO1xuXG4gICAgICAgICAgLy8gfSBlbHNlICBpZiAoZXZlbnQua2V5ID09IFwiclwiKSB7IC8vIFJvdGF0ZVxuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PSBcInNcIikge1xuICAgICAgICAgIGxldCBvcmlnaW5YID0gdGhpcy5kZWJ1Zy54IHx8IGRpbXMucGFyZW50LndpZHRoIC8gMjtcbiAgICAgICAgICBsZXQgb3JpZ2luWSA9IHRoaXMuZGVidWcueSB8fCBkaW1zLnBhcmVudC5oZWlnaHQgLyAyO1xuICAgICAgICAgIG9yaWdpblggLT0gZGltcy5lbGVtLmxlZnQgLSBkaW1zLnBhcmVudC5sZWZ0O1xuICAgICAgICAgIG9yaWdpblkgLT0gZGltcy5lbGVtLnRvcCAtIGRpbXMucGFyZW50LnRvcDtcblxuICAgICAgICAgIC8vIHJlc2V0IHBkZlZpZXdlci5zY2FsZVxuICAgICAgICAgIGxldCBjdXJyZW50U2NhbGUgPSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIuY3VycmVudFNjYWxlO1xuICAgICAgICAgIGxldCBwcmV2U2NhbGUgPSBjdXJyZW50U2NhbGUgLyB0aGlzLmN1cnJlbnRTY2FsZTtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcImN1cnJlbnRTY2FsZTogXCIgKyBjdXJyZW50U2NhbGUgKyBcIiAtPiBcIiArIHByZXZTY2FsZSArIFwiLCBvcmlnaW5YL1k6IFwiICsgb3JpZ2luWCArIFwiIC8gXCIgKyBvcmlnaW5ZKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIm9yaWdpblgvWTogXCIgKyBvcmlnaW5YICsgXCIgLyBcIiArIG9yaWdpblkgKyBcIiwgc2NhbGU6IFwiICsgY3VycmVudFNjYWxlICsgXCIgLT4gXCIgKyBwcmV2U2NhbGUgKyBcIiwgdC5jczogXCIgKyB0aGlzLmN1cnJlbnRTY2FsZSArIFwiOyBkaW1zOiBcIiwgZGltcyk7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJvcmlnaW5YL1kgKCUpOiBcIiArIChvcmlnaW5YIC8gZGltcy5lbGVtLndpZHRoKSArIFwiIC8gXCIgKyAob3JpZ2luWSAvIGRpbXMuZWxlbS5oZWlnaHQpKTtcblxuICAgICAgICAgIC8vIFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5fc2V0U2NhbGUocHJldlNjYWxlLCB0cnVlKTtcbiAgICAgICAgICBpZiAoY3VycmVudFNjYWxlICE9IHByZXZTY2FsZSkgdGhpcy5zZXRWaWV3ZXJTY2FsZShwcmV2U2NhbGUpO1xuXG5cbiAgICAgICAgICBvcmlnaW5YID0gdGhpcy5kZWJ1Zy54IHx8IGRpbXMucGFyZW50LndpZHRoIC8gMjtcbiAgICAgICAgICBvcmlnaW5ZID0gdGhpcy5kZWJ1Zy55IHx8IGRpbXMucGFyZW50LmhlaWdodCAvIDI7XG4gICAgICAgICAgbGV0IGRpbXNBZnRlciA9IHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcik7XG4gICAgICAgICAgb3JpZ2luWCAtPSBkaW1zQWZ0ZXIuZWxlbS5sZWZ0IC0gZGltc0FmdGVyLnBhcmVudC5sZWZ0O1xuICAgICAgICAgIG9yaWdpblkgLT0gZGltc0FmdGVyLmVsZW0udG9wIC0gZGltc0FmdGVyLnBhcmVudC50b3A7XG5cbiAgICAgICAgICBjb25zb2xlLmxvZyhcIm9yaWdpblgvWTogXCIgKyBvcmlnaW5YICsgXCIgLyBcIiArIG9yaWdpblkgKyBcIiwgc2NhbGU6IFwiICsgY3VycmVudFNjYWxlICsgXCIgLT4gXCIgKyBwcmV2U2NhbGUgKyBcIiwgdC5jczogXCIgKyB0aGlzLmN1cnJlbnRTY2FsZSArIFwiOyBkaW1zQWZ0ZXI6IFwiLCBkaW1zQWZ0ZXIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwib3JpZ2luWC9ZICglKTogXCIgKyAob3JpZ2luWCAvIGRpbXNBZnRlci5lbGVtLndpZHRoKSArIFwiIC8gXCIgKyAob3JpZ2luWSAvIGRpbXNBZnRlci5lbGVtLmhlaWdodCkpO1xuXG4gICAgICAgICAgdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtID0gYHNjYWxlKCR7dGhpcy5jdXJyZW50U2NhbGV9KWA7XG4gICAgICAgICAgdGhpcy52aWV3ZXIuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gYCR7b3JpZ2luWH1weCAke29yaWdpbll9cHhgO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09IFwidFwiKSB7XG5cbiAgICAgICAgICAvLyBiYXJlIFBERi5qcy16b29tXG4gICAgICAgICAgbGV0IG9yaWdpblggPSB0aGlzLmRlYnVnLnggfHwgZGltcy5wYXJlbnQud2lkdGggLyAyO1xuICAgICAgICAgIGxldCBvcmlnaW5ZID0gdGhpcy5kZWJ1Zy55IHx8IGRpbXMucGFyZW50LmhlaWdodCAvIDI7XG4gICAgICAgICAgb3JpZ2luWCAtPSBkaW1zLmVsZW0ubGVmdCAtIGRpbXMucGFyZW50LmxlZnQ7XG4gICAgICAgICAgb3JpZ2luWSAtPSBkaW1zLmVsZW0udG9wIC0gZGltcy5wYXJlbnQudG9wO1xuXG4gICAgICAgICAgaWYgKHRoaXMuY3VycmVudFNjYWxlID09IDEuMCkgdGhpcy5jdXJyZW50U2NhbGUgPSAxLjM7XG5cbiAgICAgICAgICBsZXQgY3VycmVudFNjYWxlID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLmN1cnJlbnRTY2FsZTtcbiAgICAgICAgICBsZXQgbmV3U2NhbGUgPSBjdXJyZW50U2NhbGUgKiB0aGlzLmN1cnJlbnRTY2FsZTtcbiAgICAgICAgICB0aGlzLnNldFZpZXdlclNjYWxlKG5ld1NjYWxlLCB7IG9yaWdpbjogeyB4OiBvcmlnaW5YLCB5OiBvcmlnaW5ZIH0gfSk7XG5cblxuXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09IFwieVwiKSB7XG5cbiAgICAgICAgICBsZXQgb3JpZ2luWCA9IHRoaXMuZGVidWcueCB8fCBkaW1zLnBhcmVudC53aWR0aCAvIDI7XG4gICAgICAgICAgbGV0IG9yaWdpblkgPSB0aGlzLmRlYnVnLnkgfHwgZGltcy5wYXJlbnQuaGVpZ2h0IC8gMjtcbiAgICAgICAgICBvcmlnaW5YIC09IGRpbXMuZWxlbS5sZWZ0IC0gZGltcy5wYXJlbnQubGVmdDtcbiAgICAgICAgICBvcmlnaW5ZIC09IGRpbXMuZWxlbS50b3AgLSBkaW1zLnBhcmVudC50b3A7XG5cbiAgICAgICAgICBsZXQgY3VycmVudFNjYWxlID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLmN1cnJlbnRTY2FsZTtcbiAgICAgICAgICBsZXQgcHJldlNjYWxlID0gY3VycmVudFNjYWxlIC8gdGhpcy5jdXJyZW50U2NhbGU7XG5cbiAgICAgICAgICBjb25zb2xlLmxvZyhcInksIGN1cnJlbnRTY2FsZTogXCIgKyBjdXJyZW50U2NhbGUgKyBcIjsgcHJldlNjYWxlOiBcIiArIHByZXZTY2FsZSk7XG4gICAgICAgICAgLy8gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLl9zZXRTY2FsZShwcmV2U2NhbGUsIHRydWUpO1xuICAgICAgICAgIHRoaXMuc2V0Vmlld2VyU2NhbGUocHJldlNjYWxlLCB7IG9yaWdpbjogeyB4OiBvcmlnaW5YLCB5OiBvcmlnaW5ZIH0gfSk7XG4gICAgICAgICAgLy8gdGhpcy5jdXJyZW50U2NhbGUgPSAxLjA7XG5cbiAgICAgICAgICAvLyBsZXQgZGltc0FmdGVyID0gdGhpcy5nZXREaW1lbnNpb25zKHRoaXMudmlld2VyKTtcblxuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiZGltc0FmdGVyOiBcIiwgZGltc0FmdGVyLmVsZW0pO1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiZGltc0RpZmY6IFwiLCB0aGlzLmdldERpbURpZmYoZGltcywgZGltc0FmdGVyKS5lbGVtKTtcblxuXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09IFwidVwiKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVWaWV3ZXJQb3NpdGlvbigpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09IFwiaVwiKSB7XG4gICAgICAgICAgbGV0IGNvcnJMZWZ0ID0gMjAwO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiYmVmb3JlQ29ycjogXCIsIHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcikuZWxlbSk7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJ0aGlzLnZpZXdlci5zdHlsZTogXCIsIHRoaXMudmlld2VyLnN0eWxlKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcInRoaXMudmlld2VyLnN0eWxlLmxlZnQ6IFwiICsgdGhpcy52aWV3ZXIuc3R5bGUubGVmdCArIFwiIC0+IFwiICsgY29yckxlZnQpO1xuICAgICAgICAgIHRoaXMudmlld2VyLnN0eWxlLmxlZnQgPSBjb3JyTGVmdCArIFwicHhcIjtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcImFmdGVyQ29ycjogXCIsIHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcikuZWxlbSk7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJ0aGlzLnZpZXdlci5zdHlsZTogXCIsIHRoaXMudmlld2VyLnN0eWxlKTtcblxuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PSBcIm9cIikge1xuXG4gICAgICAgICAgbGV0IG9yaWdpblggPSB0aGlzLmRlYnVnLnggfHwgZGltcy5wYXJlbnQud2lkdGggLyAyO1xuICAgICAgICAgIGxldCBvcmlnaW5ZID0gdGhpcy5kZWJ1Zy55IHx8IGRpbXMucGFyZW50LmhlaWdodCAvIDI7XG4gICAgICAgICAgb3JpZ2luWCAtPSBkaW1zLmVsZW0ubGVmdCAtIGRpbXMucGFyZW50LmxlZnQ7XG4gICAgICAgICAgb3JpZ2luWSAtPSBkaW1zLmVsZW0udG9wIC0gZGltcy5wYXJlbnQudG9wO1xuXG4gICAgICAgICAgY29uc29sZS5sb2coXCJvcmlnaW5YL1k6IFwiICsgb3JpZ2luWCArIFwiIC8gXCIgKyBvcmlnaW5ZICsgXCIsIHNjYWxlOiBcIiArIHRoaXMuY3VycmVudFNjYWxlKTtcblxuICAgICAgICAgIHRoaXMudmlld2VyLnN0eWxlLnRyYW5zZm9ybSA9IGBzY2FsZSgke3RoaXMuY3VycmVudFNjYWxlfSlgO1xuICAgICAgICAgIHRoaXMudmlld2VyLnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGAke29yaWdpblh9cHggJHtvcmlnaW5ZfXB4YDtcblxuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PSBcInBcIikge1xuXG5cbiAgICAgICAgICBjb25zb2xlLmxvZyhcImRpbXM6IFwiLCBkaW1zKTtcbiAgICAgICAgICAvLyBsZXQgb3JpZ2luWCA9IHRoaXMuZGVidWcueCB8fCBkaW1zLnBhcmVudC53aWR0aCAvIDI7IFxuICAgICAgICAgIC8vIGxldCBvcmlnaW5ZID0gdGhpcy5kZWJ1Zy55IHx8IGRpbXMucGFyZW50LmhlaWdodCAvIDI7IFxuXG5cbiAgICAgICAgICBjb25zb2xlLmxvZyhcImdldFZpZXdlclRyYW5zZm9ybVNjYWxlOiBcIiwgdGhpcy5nZXRWaWV3ZXJUcmFuc2Zvcm1TY2FsZShcImtleSA9PSBwXCIpKTtcblxuICAgICAgICAgIHRoaXMudmlld2VyLnN0eWxlLnRyYW5zZm9ybSA9IGBub25lYDtcbiAgICAgICAgICB0aGlzLnZpZXdlci5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgdW5zZXRgO1xuXG4gICAgICAgICAgbGV0IGRpbXNBZnRlciA9IHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcik7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJkaW1zQWZ0ZXI6IFwiLCBkaW1zQWZ0ZXIpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwiZGltc0RpZmY6IFwiLCB0aGlzLmdldERpbURpZmYoZGltcywgZGltc0FmdGVyKSk7XG5cblxuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PSBcImZcIikge1xuXG5cbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT0gXCJkXCIpIHtcblxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiZGltczogXCIsIHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLnZpZXdlcikpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09IFwielwiKSB7XG5cbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT0gXCJ4XCIpIHtcblxuICAgICAgICB9XG4gICAgICB9O1xuXG5cbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwia2V5dXBcIiwgb25LZXl1cCk7XG4gICAgfVxuXG5cblxuICB9XG5cbiAgcHVibGljIGRlc3Ryb3lSZWxhdGl2ZUNvb3JkcygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNNb2JpbGUoKSkge1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5ib3VuZE9uVmlld2VyTW91c2VEb3duKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRPblZpZXdlck1vdXNlTW92ZSk7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5ib3VuZE9uVmlld2VyTW91c2VVcCk7XG5cbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwid2hlZWxcIiwgdGhpcy5ib3VuZE9uVmlld2VyV2hlZWwpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0aGlzLmJvdW5kT25WaWV3ZXJUb3VjaFN0YXJ0KTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLmJvdW5kT25WaWV3ZXJUb3VjaE1vdmUpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5ib3VuZE9uVmlld2VyVG91Y2hFbmQpO1xuICB9XG59XG4iXX0=