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.

713 lines 106 kB
import { effect, Injectable } from '@angular/core';
import { AnnotationEditorParamsType, AnnotationMode } from './options/editor-annotations';
import * as i0 from "@angular/core";
import * as i1 from "./pdf-notification-service";
export class NgxExtendedPdfViewerService {
    rendererFactory;
    ngxExtendedPdfViewerInitialized = false;
    secondaryMenuIsEmpty = false;
    renderer;
    PDFViewerApplication;
    constructor(rendererFactory, notificationService) {
        this.rendererFactory = rendererFactory;
        this.renderer = this.rendererFactory.createRenderer(null, null);
        effect(() => {
            this.PDFViewerApplication = notificationService.onPDFJSInitSignal();
        });
    }
    find(text, options = {}) {
        if (!this.ngxExtendedPdfViewerInitialized) {
            // tslint:disable-next-line:quotemark
            console.error("The PDF viewer hasn't finished initializing. Please call find() later.");
            return undefined;
        }
        else {
            if (!options.useSecondaryFindcontroller) {
                const highlightAllCheckbox = document.getElementById('findHighlightAll');
                if (highlightAllCheckbox) {
                    highlightAllCheckbox.checked = options.highlightAll ?? false;
                }
                const matchCaseCheckbox = document.getElementById('findMatchCase');
                if (matchCaseCheckbox) {
                    matchCaseCheckbox.checked = options.matchCase ?? false;
                }
                const findMultipleCheckbox = document.getElementById('findMultiple');
                if (findMultipleCheckbox) {
                    findMultipleCheckbox.checked = options.findMultiple ?? false;
                }
                const entireWordCheckbox = document.getElementById('findEntireWord');
                if (entireWordCheckbox) {
                    entireWordCheckbox.checked = options.wholeWords ?? false;
                }
                const matchDiacriticsCheckbox = document.getElementById('findMatchDiacritics');
                if (matchDiacriticsCheckbox) {
                    matchDiacriticsCheckbox.checked = options.matchDiacritics ?? false;
                }
                const matchRegExpCheckbox = document.getElementById('matchRegExp');
                if (matchRegExpCheckbox) {
                    matchRegExpCheckbox.checked = options.regexp ?? false;
                    if (matchRegExpCheckbox.checked) {
                        if (findMultipleCheckbox) {
                            findMultipleCheckbox.checked = false;
                        }
                        if (entireWordCheckbox) {
                            entireWordCheckbox.checked = false;
                        }
                        if (matchDiacriticsCheckbox) {
                            matchDiacriticsCheckbox.checked = false;
                        }
                    }
                    if (findMultipleCheckbox) {
                        findMultipleCheckbox.disabled = matchRegExpCheckbox.checked;
                    }
                    if (entireWordCheckbox) {
                        entireWordCheckbox.disabled = matchRegExpCheckbox.checked;
                    }
                    if (matchDiacriticsCheckbox) {
                        matchDiacriticsCheckbox.disabled = matchRegExpCheckbox.checked;
                    }
                }
                const inputField = document.getElementById('findInput');
                if (inputField && typeof text === 'string') {
                    inputField.value = text;
                }
            }
            const findParameters = {
                caseSensitive: options.matchCase ?? false,
                entireWord: options.wholeWords ?? false,
                highlightAll: options.highlightAll ?? false,
                matchDiacritics: options.matchDiacritics ?? false,
                findMultiple: options.findMultiple,
                matchRegExp: options.regexp ?? false,
                findPrevious: false,
                query: text,
                source: null,
                type: 'find',
                dontScrollIntoView: options.dontScrollIntoView ?? false,
            };
            const findController = options.useSecondaryFindcontroller ? this.PDFViewerApplication?.customFindController : this.PDFViewerApplication?.findController;
            const result = findController?.ngxFind(findParameters);
            return result;
        }
    }
    findNext(useSecondaryFindcontroller = false) {
        if (!this.ngxExtendedPdfViewerInitialized) {
            // tslint:disable-next-line:quotemark
            console.error("The PDF viewer hasn't finished initializing. Please call findNext() later.");
            return false;
        }
        else {
            const findController = useSecondaryFindcontroller ? this.PDFViewerApplication?.customFindController : this.PDFViewerApplication?.findController;
            findController?.ngxFindNext();
            return true;
        }
    }
    findPrevious(useSecondaryFindcontroller = false) {
        if (!this.ngxExtendedPdfViewerInitialized) {
            // tslint:disable-next-line:quotemark
            console.error("The PDF viewer hasn't finished initializing. Please call findPrevious() later.");
            return false;
        }
        else {
            const findController = useSecondaryFindcontroller ? this.PDFViewerApplication?.customFindController : this.PDFViewerApplication?.findController;
            findController?.ngxFindPrevious();
            return true;
        }
    }
    print(printRange) {
        if (this.PDFViewerApplication) {
            const alreadyPrinting = this.PDFViewerApplication?.PDFPrintServiceFactory?.isInPDFPrintRange !== undefined;
            if (!alreadyPrinting) {
                // slow down hurried users clicking the print button multiple times
                if (!printRange) {
                    printRange = {};
                }
                this.setPrintRange(printRange);
                this.PDFViewerApplication?.printPdf();
                this.PDFViewerApplication?.eventBus.on('afterprint', this.removePrintRange.bind(this), { once: true });
            }
        }
    }
    removePrintRange() {
        if (this.PDFViewerApplication?.PDFPrintServiceFactory) {
            delete this.PDFViewerApplication.PDFPrintServiceFactory.isInPDFPrintRange;
            delete this.PDFViewerApplication.PDFPrintServiceFactory.filteredPageCount;
        }
    }
    setPrintRange(printRange) {
        if (!this.PDFViewerApplication?.PDFPrintServiceFactory) {
            console.error("The print service hasn't been initialized yet.");
            return;
        }
        this.PDFViewerApplication.PDFPrintServiceFactory.isInPDFPrintRange = (page) => this.isInPDFPrintRange(page, printRange);
        this.PDFViewerApplication.PDFPrintServiceFactory.filteredPageCount = this.filteredPageCount(this.PDFViewerApplication?.pagesCount, printRange);
    }
    filteredPageCount(pageCount, range) {
        let result = 0;
        for (let page = 0; page < pageCount; page++) {
            if (this.isInPDFPrintRange(page, range)) {
                result++;
            }
        }
        return result;
    }
    isInPDFPrintRange(pageIndex, printRange) {
        const page = pageIndex + 1;
        if (printRange.from) {
            if (page < printRange.from) {
                return false;
            }
        }
        if (printRange.to) {
            if (page > printRange.to) {
                return false;
            }
        }
        if (printRange.excluded) {
            if (printRange.excluded.some((p) => p === page)) {
                return false;
            }
        }
        if (printRange.included) {
            if (!printRange.included.some((p) => p === page)) {
                return false;
            }
        }
        return true;
    }
    async getPageAsLines(pageNumber) {
        if (this.PDFViewerApplication) {
            const pdfDocument = this.PDFViewerApplication?.pdfDocument;
            const page = await pdfDocument.getPage(pageNumber);
            const textSnippets = (await page.getTextContent()).items //
                .filter((info) => !info['type']); // ignore the TextMarkedContent items
            const snippets = textSnippets;
            let minX = Number.MAX_SAFE_INTEGER;
            let minY = Number.MAX_SAFE_INTEGER;
            let maxX = Number.MIN_SAFE_INTEGER;
            let maxY = Number.MIN_SAFE_INTEGER;
            let countLTR = 0;
            let countRTL = 0;
            let text = '';
            let lines = new Array();
            for (let i = 0; i < snippets.length; i++) {
                const currentSnippet = snippets[i];
                if (!currentSnippet.hasEOL) {
                    const x = currentSnippet.transform[4];
                    const y = -currentSnippet.transform[5];
                    const width = currentSnippet.width;
                    const height = currentSnippet.height;
                    minX = Math.min(minX, x);
                    minY = Math.min(minY, y);
                    maxX = Math.max(maxX, x + width);
                    maxY = Math.max(maxY, y + height);
                    text += currentSnippet.str;
                    if (currentSnippet.dir === 'rtl') {
                        countRTL++;
                    }
                    if (currentSnippet.dir === 'ltr') {
                        countLTR++;
                    }
                }
                let addIt = i === snippets.length - 1 || currentSnippet.hasEOL;
                if (addIt) {
                    let direction = undefined;
                    if (countLTR > 0 && countRTL > 0) {
                        direction = 'both';
                    }
                    else if (countLTR > 0) {
                        direction = 'ltr';
                    }
                    else if (countRTL > 0) {
                        direction = 'rtl';
                    }
                    const line = {
                        direction,
                        x: minX,
                        y: minY,
                        width: maxX - minX,
                        height: maxY - minY,
                        text: text.trim(),
                    };
                    lines.push(line);
                    minX = Number.MAX_SAFE_INTEGER;
                    minY = Number.MAX_SAFE_INTEGER;
                    maxX = Number.MIN_SAFE_INTEGER;
                    maxY = Number.MIN_SAFE_INTEGER;
                    countLTR = 0;
                    countRTL = 0;
                    text = '';
                }
            }
            return lines;
        }
        return [];
    }
    async getPageAsText(pageNumber) {
        if (!this.PDFViewerApplication) {
            return '';
        }
        const pdfDocument = this.PDFViewerApplication?.pdfDocument;
        const page = await pdfDocument.getPage(pageNumber);
        const textSnippets = (await page.getTextContent()).items;
        return this.convertTextInfoToText(textSnippets);
    }
    convertTextInfoToText(textInfoItems) {
        if (!textInfoItems) {
            return '';
        }
        return textInfoItems
            .filter((info) => !info['type'])
            .map((info) => (info.hasEOL ? info.str + '\n' : info.str))
            .join('');
    }
    async getPageAsCanvas(pageNumber, scale, background, backgroundColorToReplace = '#FFFFFF', annotationMode = AnnotationMode.ENABLE) {
        if (!this.PDFViewerApplication) {
            return Promise.resolve(undefined);
        }
        const pdfDocument = this.PDFViewerApplication.pdfDocument;
        const pdfPage = await pdfDocument.getPage(pageNumber);
        return this.draw(pdfPage, scale, background, backgroundColorToReplace, annotationMode);
    }
    async getPageAsImage(pageNumber, scale, background, backgroundColorToReplace = '#FFFFFF', annotationMode = AnnotationMode.ENABLE) {
        const canvas = await this.getPageAsCanvas(pageNumber, scale, background, backgroundColorToReplace, annotationMode);
        return canvas?.toDataURL();
    }
    async draw(pdfPage, scale, background, backgroundColorToReplace = '#FFFFFF', annotationMode = AnnotationMode.ENABLE) {
        let zoomFactor = 1;
        if (scale.scale) {
            zoomFactor = scale.scale;
        }
        else if (scale.width) {
            zoomFactor = scale.width / pdfPage.getViewport({ scale: 1 }).width;
        }
        else if (scale.height) {
            zoomFactor = scale.height / pdfPage.getViewport({ scale: 1 }).height;
        }
        const viewport = pdfPage.getViewport({
            scale: zoomFactor,
        });
        const { ctx, canvas } = this.getPageDrawContext(viewport.width, viewport.height);
        const drawViewport = viewport.clone();
        const renderContext = {
            canvasContext: ctx,
            viewport: drawViewport,
            background,
            backgroundColorToReplace,
            annotationMode,
        };
        const renderTask = pdfPage.render(renderContext);
        const dataUrlPromise = () => Promise.resolve(canvas);
        return renderTask.promise.then(dataUrlPromise);
    }
    getPageDrawContext(width, height) {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d', { alpha: true });
        if (!ctx) {
            // tslint:disable-next-line: quotemark
            throw new Error("Couldn't create the 2d context");
        }
        canvas.width = width;
        canvas.height = height;
        this.renderer.setStyle(canvas, 'width', `${width}px`);
        this.renderer.setStyle(canvas, 'height', `${height}px`);
        return { ctx, canvas };
    }
    async getCurrentDocumentAsBlob() {
        return (await this.PDFViewerApplication?.export()) || undefined;
    }
    async getFormData(currentFormValues = true) {
        if (!this.PDFViewerApplication) {
            return [];
        }
        const pdf = this.PDFViewerApplication?.pdfDocument;
        // screen DPI / PDF DPI
        const dpiRatio = 96 / 72;
        const result = [];
        for (let i = 1; i <= pdf?.numPages; i++) {
            // track the current page
            const currentPage /* : PDFPageProxy */ = await pdf.getPage(i);
            const annotations = await currentPage.getAnnotations();
            annotations
                .filter((a) => a.subtype === 'Widget') // get the form field annotations only
                .map((a) => ({ ...a })) // only expose copies of the annotations to avoid side-effects
                .forEach((a) => {
                // get the rectangle that represent the single field
                // and resize it according to the current DPI
                const fieldRect = currentPage.getViewport({ scale: dpiRatio }).convertToViewportRectangle(a.rect);
                // add the corresponding input
                if (currentFormValues && a.fieldName) {
                    try {
                        if (a.exportValue) {
                            const currentValue = this.PDFViewerApplication?.pdfDocument.annotationStorage.getValue(a.id, a.fieldName + '/' + a.exportValue, '');
                            a.value = currentValue?.value;
                        }
                        else if (a.radioButton) {
                            const currentValue = this.PDFViewerApplication?.pdfDocument.annotationStorage.getValue(a.id, a.fieldName + '/' + a.fieldValue, '');
                            a.value = currentValue?.value;
                        }
                        else {
                            const currentValue = this.PDFViewerApplication?.pdfDocument.annotationStorage.getValue(a.id, a.fieldName, '');
                            a.value = currentValue?.value;
                        }
                    }
                    catch (exception) {
                        // just ignore it
                    }
                }
                result.push({ fieldAnnotation: a, fieldRect, pageNumber: i });
            });
        }
        return result;
    }
    /**
     * Adds a page to the rendering queue
     * @param {number} pageIndex Index of the page to render
     * @returns {boolean} false, if the page has already been rendered,
     * if it's out of range or if the viewer hasn't been initialized yet
     */
    addPageToRenderQueue(pageIndex) {
        return this.PDFViewerApplication?.pdfViewer.addPageToRenderQueue(pageIndex) ?? false;
    }
    isRenderQueueEmpty() {
        const scrolledDown = true;
        const renderExtra = false;
        if (this.PDFViewerApplication) {
            const nextPage = this.PDFViewerApplication.pdfViewer.renderingQueue.getHighestPriority(this.PDFViewerApplication?.pdfViewer._getVisiblePages(), this.PDFViewerApplication?.pdfViewer._pages, scrolledDown, renderExtra);
            return !nextPage;
        }
        return true;
    }
    hasPageBeenRendered(pageIndex) {
        if (!this.PDFViewerApplication) {
            return false;
        }
        const pages = this.PDFViewerApplication?.pdfViewer._pages;
        if (pages.length > pageIndex && pageIndex >= 0) {
            const pageView = pages[pageIndex];
            const hasBeenRendered = pageView.renderingState === 3;
            return hasBeenRendered;
        }
        return false;
    }
    sleep(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }
    async renderPage(pageIndex) {
        if (!this.hasPageBeenRendered(pageIndex)) {
            await this.addPageToRenderQueue(pageIndex);
            while (!this.hasPageBeenRendered(pageIndex)) {
                await this.sleep(7);
            }
        }
    }
    currentlyRenderedPages() {
        if (!this.PDFViewerApplication) {
            return [];
        }
        const pages = this.PDFViewerApplication?.pdfViewer._pages;
        return pages.filter((page) => page.renderingState === 3).map((page) => page.id);
    }
    numberOfPages() {
        if (!this.PDFViewerApplication) {
            return 0;
        }
        const pages = this.PDFViewerApplication?.pdfViewer._pages;
        return pages.length;
    }
    getCurrentlyVisiblePageNumbers() {
        const app = this.PDFViewerApplication;
        if (!app) {
            return [];
        }
        const pages = app.pdfViewer._getVisiblePages().views;
        return pages?.map((page) => page.id);
    }
    async listLayers() {
        if (!this.PDFViewerApplication) {
            return [];
        }
        const optionalContentConfig = await this.PDFViewerApplication?.pdfViewer.optionalContentConfigPromise;
        if (optionalContentConfig) {
            const levelData = optionalContentConfig.getOrder();
            const layerIds = levelData.filter((groupId) => typeof groupId !== 'object');
            return layerIds.map((layerId) => {
                const config = optionalContentConfig.getGroup(layerId);
                return {
                    layerId: layerId,
                    name: config.name,
                    visible: config.visible,
                };
            });
        }
        return undefined;
    }
    async toggleLayer(layerId) {
        if (!this.PDFViewerApplication) {
            return;
        }
        const optionalContentConfig = await this.PDFViewerApplication?.pdfViewer.optionalContentConfigPromise;
        if (optionalContentConfig) {
            let isVisible = optionalContentConfig.getGroup(layerId).visible;
            const checkbox = document.querySelector(`input[id='${layerId}']`);
            if (checkbox) {
                isVisible = checkbox.checked;
                checkbox.checked = !isVisible;
            }
            optionalContentConfig.setVisibility(layerId, !isVisible);
            this.PDFViewerApplication?.eventBus.dispatch('optionalcontentconfig', {
                source: this,
                promise: Promise.resolve(optionalContentConfig),
            });
        }
    }
    scrollPageIntoView(pageNumber, pageSpot) {
        const viewer = this.PDFViewerApplication?.pdfViewer;
        viewer?.scrollPagePosIntoView(pageNumber, pageSpot);
    }
    getSerializedAnnotations() {
        return this.PDFViewerApplication?.pdfViewer.getSerializedAnnotations();
    }
    async addEditorAnnotation(serializedAnnotation) {
        await this.PDFViewerApplication?.pdfViewer.addEditorAnnotation(serializedAnnotation);
    }
    removeEditorAnnotations(filter) {
        this.PDFViewerApplication?.pdfViewer.removeEditorAnnotations(filter);
    }
    async loadImageAsDataURL(imageUrl) {
        if (imageUrl.startsWith('data:')) {
            return imageUrl;
        }
        const response = await fetch(imageUrl);
        if (!response.ok) {
            throw new Error(`Failed to fetch the image from ${imageUrl}: ${response.statusText}`);
        }
        const imageBlob = await response.blob();
        return imageBlob;
    }
    async addImageToAnnotationLayer({ urlOrDataUrl, page, left, bottom, right, top, rotation }) {
        if (!this.PDFViewerApplication) {
            console.error('The PDF viewer has not been initialized yet.');
            return;
        }
        let pageToModify;
        if (page !== undefined) {
            if (page !== this.currentPageIndex()) {
                await this.renderPage(page);
            }
            pageToModify = page;
        }
        else {
            pageToModify = this.currentPageIndex() ?? 0;
        }
        const previousAnnotationEditorMode = this.PDFViewerApplication.pdfViewer.annotationEditorMode;
        this.switchAnnotationEdtorMode(13);
        const dataUrl = await this.loadImageAsDataURL(urlOrDataUrl);
        const pageSize = this.PDFViewerApplication.pdfViewer._pages[pageToModify].pdfPage.view;
        const leftDim = pageSize[0];
        const bottomDim = pageSize[1];
        const rightDim = pageSize[2];
        const topDim = pageSize[3];
        const width = rightDim - leftDim;
        const height = topDim - bottomDim;
        const imageWidth = this.PDFViewerApplication?.pdfViewer._pages[pageToModify].div.clientWidth;
        const imageHeight = this.PDFViewerApplication?.pdfViewer._pages[pageToModify].div.clientHeight;
        const leftPdf = this.convertToPDFCoordinates(left, width, 0, imageWidth);
        const bottomPdf = this.convertToPDFCoordinates(bottom, height, 0, imageHeight);
        const rightPdf = this.convertToPDFCoordinates(right, width, width, imageWidth);
        const topPdf = this.convertToPDFCoordinates(top, height, height, imageHeight);
        const stampAnnotation = {
            annotationType: 13,
            pageIndex: pageToModify,
            bitmapUrl: dataUrl,
            rect: [leftPdf, bottomPdf, rightPdf, topPdf],
            rotation: rotation ?? 0,
            isCopy: true,
        };
        this.addEditorAnnotation(stampAnnotation);
        await this.sleep(10);
        this.switchAnnotationEdtorMode(previousAnnotationEditorMode);
    }
    async addHighlightToAnnotationLayer(color, page, left, bottom, right, top, thickness = 12, rotation = 0, opacity = 0.5) {
        if (!this.PDFViewerApplication) {
            console.error('The PDF viewer has not been initialized yet.');
            return;
        }
        let pageToModify;
        if (page !== undefined) {
            if (page !== this.currentPageIndex()) {
                await this.renderPage(page);
            }
            pageToModify = page;
        }
        else {
            pageToModify = this.currentPageIndex() ?? 0;
        }
        const previousAnnotationEditorMode = this.PDFViewerApplication.pdfViewer.annotationEditorMode;
        this.switchAnnotationEdtorMode(9); // AnnotationEditorType.HIGHLIGHT
        const pageSize = this.PDFViewerApplication.pdfViewer._pages[pageToModify].pdfPage.view;
        const leftDim = pageSize[0];
        const bottomDim = pageSize[1];
        const rightDim = pageSize[2];
        const topDim = pageSize[3];
        const width = rightDim - leftDim;
        const height = topDim - bottomDim;
        const pageWidth = this.PDFViewerApplication?.pdfViewer._pages[pageToModify].div.clientWidth;
        const pageHeight = this.PDFViewerApplication?.pdfViewer._pages[pageToModify].div.clientHeight;
        const leftPdf = this.convertToPDFCoordinates(left, width, 0, pageWidth);
        const bottomPdf = this.convertToPDFCoordinates(bottom, height, 0, pageHeight);
        const rightPdf = this.convertToPDFCoordinates(right, width, width, pageWidth);
        const topPdf = this.convertToPDFCoordinates(top, height, height, pageHeight);
        // Create quadPoints object with numeric keys (matching export format)
        const quadPoints = {};
        quadPoints[0] = leftPdf; // x1 - left edge start
        quadPoints[1] = topPdf; // y1 - top edge start
        quadPoints[2] = rightPdf; // x2 - right edge end
        quadPoints[3] = topPdf; // y2 - top edge end
        quadPoints[4] = leftPdf; // x3 - left edge start (bottom)
        quadPoints[5] = bottomPdf; // y3 - bottom edge start
        quadPoints[6] = rightPdf; // x4 - right edge end (bottom)
        quadPoints[7] = bottomPdf; // y4 - bottom edge end
        const highlightAnnotation = {
            annotationType: 9,
            color: color,
            opacity: opacity,
            thickness: thickness,
            quadPoints: quadPoints,
            outlines: [
                [
                    // Single outline rectangle
                    leftPdf,
                    bottomPdf,
                    leftPdf,
                    topPdf,
                    rightPdf,
                    topPdf,
                    rightPdf,
                    bottomPdf, // Bottom-right
                ],
            ],
            pageIndex: pageToModify,
            rect: [leftPdf, bottomPdf, rightPdf, topPdf],
            rotation: rotation,
            isCopy: true,
        };
        this.addEditorAnnotation(highlightAnnotation);
        await this.sleep(10);
        this.switchAnnotationEdtorMode(previousAnnotationEditorMode);
    }
    currentPageIndex() {
        const viewer = this.PDFViewerApplication?.pdfViewer;
        if (viewer) {
            return viewer.currentPageNumber - 1;
        }
        return undefined;
    }
    convertToPDFCoordinates(value, maxValue, defaultValue, imageMaxValue) {
        if (!value) {
            return defaultValue;
        }
        if (typeof value === 'string') {
            if (value.endsWith('%')) {
                return (parseInt(value, 10) / 100) * maxValue;
            }
            else if (value.endsWith('px')) {
                return parseInt(value, 10) * (maxValue / imageMaxValue);
            }
            else {
                return parseInt(value, 10);
            }
        }
        else {
            return value;
        }
    }
    switchAnnotationEdtorMode(mode) {
        this.PDFViewerApplication?.eventBus.dispatch('switchannotationeditormode', { mode });
    }
    set editorFontSize(size) {
        this.setEditorProperty(AnnotationEditorParamsType.FREETEXT_SIZE, size);
    }
    set editorFontColor(color) {
        this.setEditorProperty(AnnotationEditorParamsType.FREETEXT_COLOR, color);
    }
    set editorInkColor(color) {
        this.setEditorProperty(AnnotationEditorParamsType.INK_COLOR, color);
    }
    set editorInkOpacity(opacity) {
        this.setEditorProperty(AnnotationEditorParamsType.INK_OPACITY, opacity);
    }
    set editorInkThickness(thickness) {
        this.setEditorProperty(AnnotationEditorParamsType.INK_THICKNESS, thickness);
    }
    set editorHighlightColor(color) {
        this.setEditorProperty(AnnotationEditorParamsType.HIGHLIGHT_COLOR, color);
    }
    set editorHighlightDefaultColor(color) {
        this.setEditorProperty(AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR, color);
    }
    set editorHighlightShowAll(showAll) {
        this.setEditorProperty(AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL, showAll);
    }
    set editorHighlightThickness(thickness) {
        this.setEditorProperty(AnnotationEditorParamsType.HIGHLIGHT_THICKNESS, thickness);
    }
    setEditorProperty(editorPropertyType, value) {
        this.PDFViewerApplication?.eventBus.dispatch('switchannotationeditorparams', { type: editorPropertyType, value });
        this.PDFViewerApplication?.eventBus.dispatch('annotationeditorparamschanged', { details: [[editorPropertyType, value]] });
    }
    getCurrentPage() {
        if (!this.PDFViewerApplication) {
            return 1;
        }
        return this.PDFViewerApplication.page ?? 1;
    }
    getPageCount() {
        if (!this.PDFViewerApplication) {
            return 0;
        }
        return this.PDFViewerApplication.pagesCount ?? 0;
    }
    movePage(fromIndex, toIndex) {
        if (!this.PDFViewerApplication) {
            console.error('PDF viewer not initialized');
            return;
        }
        // Check if page reordering is enabled
        const enablePageReordering = globalThis.pdfDefaultOptions?.enablePageReordering;
        if (!enablePageReordering) {
            console.error('Page reordering is not enabled. Set pdfDefaultOptions.enablePageReordering = true');
            return;
        }
        // Validate indices (1-based)
        const pageCount = this.getPageCount();
        if (fromIndex < 1 || fromIndex > pageCount || toIndex < 1 || toIndex > pageCount) {
            console.error(`Invalid page indices. fromIndex: ${fromIndex}, toIndex: ${toIndex}, pageCount: ${pageCount}`);
            return;
        }
        if (fromIndex === toIndex) {
            return; // No movement needed
        }
        try {
            // Call the movePage function from app.js
            if (this.PDFViewerApplication.movePage) {
                this.PDFViewerApplication.movePage(fromIndex, toIndex);
            }
            else {
                console.error('movePage function not available in PDF viewer application');
            }
        }
        catch (error) {
            console.error('Error moving page:', error);
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxExtendedPdfViewerService, deps: [{ token: i0.RendererFactory2 }, { token: i1.PDFNotificationService }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxExtendedPdfViewerService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxExtendedPdfViewerService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }], ctorParameters: () => [{ type: i0.RendererFactory2 }, { type: i1.PDFNotificationService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1leHRlbmRlZC1wZGYtdmlld2VyL3NyYy9saWIvbmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBK0IsTUFBTSxlQUFlLENBQUM7QUFDaEYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLGNBQWMsRUFBc0UsTUFBTSw4QkFBOEIsQ0FBQzs7O0FBNkQ5SixNQUFNLE9BQU8sMkJBQTJCO0lBU25CO0lBUlosK0JBQStCLEdBQUcsS0FBSyxDQUFDO0lBRXhDLG9CQUFvQixHQUFHLEtBQUssQ0FBQztJQUVuQixRQUFRLENBQVk7SUFDN0Isb0JBQW9CLENBQXlCO0lBRXJELFlBQ21CLGVBQWlDLEVBQ2xELG1CQUEyQztRQUQxQixvQkFBZSxHQUFmLGVBQWUsQ0FBa0I7UUFHbEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEUsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNWLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxtQkFBbUIsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3RFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLElBQUksQ0FBQyxJQUFnQyxFQUFFLFVBQXVCLEVBQUU7UUFDckUsSUFBSSxDQUFDLElBQUksQ0FBQywrQkFBK0IsRUFBRTtZQUN6QyxxQ0FBcUM7WUFDckMsT0FBTyxDQUFDLEtBQUssQ0FBQyx3RUFBd0UsQ0FBQyxDQUFDO1lBQ3hGLE9BQU8sU0FBUyxDQUFDO1NBQ2xCO2FBQU07WUFDTCxJQUFJLENBQUMsT0FBTyxDQUFDLDBCQUEwQixFQUFFO2dCQUN2QyxNQUFNLG9CQUFvQixH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QUFLLEVBQUU7WUFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzVDO0lBQ0gsQ0FBQzt3R0FweUJVLDJCQUEyQjs0R0FBM0IsMkJBQTJCLGNBRjFCLE1BQU07OzRGQUVQLDJCQUEyQjtrQkFIdkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBlZmZlY3QsIEluamVjdGFibGUsIFJlbmRlcmVyMiwgUmVuZGVyZXJGYWN0b3J5MiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQW5ub3RhdGlvbkVkaXRvclBhcmFtc1R5cGUsIEFubm90YXRpb25Nb2RlLCBFZGl0b3JBbm5vdGF0aW9uLCBIaWdobGlnaHRFZGl0b3JBbm5vdGF0aW9uLCBTdGFtcEVkaXRvckFubm90YXRpb24gfSBmcm9tICcuL29wdGlvbnMvZWRpdG9yLWFubm90YXRpb25zJztcbmltcG9ydCB7IFBkZkxheWVyIH0gZnJvbSAnLi9vcHRpb25zL29wdGlvbmFsX2NvbnRlbnRfY29uZmlnJztcbmltcG9ydCB7IFBERlByaW50UmFuZ2UgfSBmcm9tICcuL29wdGlvbnMvcGRmLXByaW50LXJhbmdlJztcbmltcG9ydCB7IElQREZWaWV3ZXJBcHBsaWNhdGlvbiwgUERGRG9jdW1lbnRQcm94eSwgUERGRmluZFBhcmFtZXRlcnMsIFBERlBhZ2VQcm94eSwgVGV4dEl0ZW0sIFRleHRNYXJrZWRDb250ZW50IH0gZnJvbSAnLi9vcHRpb25zL3BkZi12aWV3ZXItYXBwbGljYXRpb24nO1xuaW1wb3J0IHsgWm9vbVR5cGUgfSBmcm9tICcuL29wdGlvbnMvem9vbS10eXBlJztcbmltcG9ydCB7IFBERk5vdGlmaWNhdGlvblNlcnZpY2UgfSBmcm9tICcuL3BkZi1ub3RpZmljYXRpb24tc2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmluZE9wdGlvbnMge1xuICBoaWdobGlnaHRBbGw/OiBib29sZWFuO1xuICBtYXRjaENhc2U/OiBib29sZWFuO1xuICB3aG9sZVdvcmRzPzogYm9vbGVhbjtcbiAgbWF0Y2hEaWFjcml0aWNzPzogYm9vbGVhbjtcbiAgZG9udFNjcm9sbEludG9WaWV3PzogYm9vbGVhbjtcbiAgZmluZE11bHRpcGxlPzogYm9vbGVhbjtcbiAgcmVnZXhwPzogYm9vbGVhbjtcbiAgdXNlU2Vjb25kYXJ5RmluZGNvbnRyb2xsZXI/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgRHJhd0NvbnRleHQge1xuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQREZFeHBvcnRTY2FsZUZhY3RvciB7XG4gIHdpZHRoPzogbnVtYmVyO1xuICBoZWlnaHQ/OiBudW1iZXI7XG4gIHNjYWxlPzogbnVtYmVyO1xufVxuXG50eXBlIERpcmVjdGlvblR5cGUgPSAnbHRyJyB8ICdydGwnIHwgJ2JvdGgnIHwgdW5kZWZpbmVkO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBkZkltYWdlUGFyYW1ldGVycyB7XG4gIHVybE9yRGF0YVVybDogc3RyaW5nO1xuICBwYWdlPzogbnVtYmVyO1xuICBsZWZ0PzogbnVtYmVyIHwgc3RyaW5nO1xuICBib3R0b20/OiBudW1iZXIgfCBzdHJpbmc7XG4gIHJpZ2h0PzogbnVtYmVyIHwgc3RyaW5nO1xuICB0b3A/OiBudW1iZXIgfCBzdHJpbmc7XG4gIHJvdGF0aW9uPzogMCB8IDkwIHwgMTgwIHwgMjcwO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpbmUge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbiAgd2lkdGg6IG51bWJlcjtcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIGRpcmVjdGlvbjogRGlyZWN0aW9uVHlwZTtcbiAgdGV4dDogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBTZWN0aW9uIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICBkaXJlY3Rpb246IERpcmVjdGlvblR5cGU7XG4gIGxpbmVzOiBBcnJheTxMaW5lPjtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIE5neEV4dGVuZGVkUGRmVmlld2VyU2VydmljZSB7XG4gIHB1YmxpYyBuZ3hFeHRlbmRlZFBkZlZpZXdlckluaXRpYWxpemVkID0gZmFsc2U7XG5cbiAgcHVibGljIHNlY29uZGFyeU1lbnVJc0VtcHR5ID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSByZW5kZXJlcjogUmVuZGVyZXIyO1xuICBwcml2YXRlIFBERlZpZXdlckFwcGxpY2F0aW9uPzogSVBERlZpZXdlckFwcGxpY2F0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyLFxuICAgIG5vdGlmaWNhdGlvblNlcnZpY2U6IFBERk5vdGlmaWNhdGlvblNlcnZpY2UsXG4gICkge1xuICAgIHRoaXMucmVuZGVyZXIgPSB0aGlzLnJlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbiA9IG5vdGlmaWNhdGlvblNlcnZpY2Uub25QREZKU0luaXRTaWduYWwoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBmaW5kKHRleHQ6IHN0cmluZyB8IHN0cmluZ1tdIHwgUmVnRXhwLCBvcHRpb25zOiBGaW5kT3B0aW9ucyA9IHt9KTogQXJyYXk8UHJvbWlzZTxudW1iZXI+PiB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLm5neEV4dGVuZGVkUGRmVmlld2VySW5pdGlhbGl6ZWQpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpxdW90ZW1hcmtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaGUgUERGIHZpZXdlciBoYXNuJ3QgZmluaXNoZWQgaW5pdGlhbGl6aW5nLiBQbGVhc2UgY2FsbCBmaW5kKCkgbGF0ZXIuXCIpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFvcHRpb25zLnVzZVNlY29uZGFyeUZpbmRjb250cm9sbGVyKSB7XG4gICAgICAgIGNvbnN0IGhpZ2hsaWdodEFsbENoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRIaWdobGlnaHRBbGwnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgICBpZiAoaGlnaGxpZ2h0QWxsQ2hlY2tib3gpIHtcbiAgICAgICAgICBoaWdobGlnaHRBbGxDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy5oaWdobGlnaHRBbGwgPz8gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtYXRjaENhc2VDaGVja2JveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaW5kTWF0Y2hDYXNlJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgaWYgKG1hdGNoQ2FzZUNoZWNrYm94KSB7XG4gICAgICAgICAgbWF0Y2hDYXNlQ2hlY2tib3guY2hlY2tlZCA9IG9wdGlvbnMubWF0Y2hDYXNlID8/IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmluZE11bHRpcGxlQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZE11bHRpcGxlJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgaWYgKGZpbmRNdWx0aXBsZUNoZWNrYm94KSB7XG4gICAgICAgICAgZmluZE11bHRpcGxlQ2hlY2tib3guY2hlY2tlZCA9IG9wdGlvbnMuZmluZE11bHRpcGxlID8/IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW50aXJlV29yZENoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRFbnRpcmVXb3JkJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgaWYgKGVudGlyZVdvcmRDaGVja2JveCkge1xuICAgICAgICAgIGVudGlyZVdvcmRDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy53aG9sZVdvcmRzID8/IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWF0Y2hEaWFjcml0aWNzQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZE1hdGNoRGlhY3JpdGljcycpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICAgIGlmIChtYXRjaERpYWNyaXRpY3NDaGVja2JveCkge1xuICAgICAgICAgIG1hdGNoRGlhY3JpdGljc0NoZWNrYm94LmNoZWNrZWQgPSBvcHRpb25zLm1hdGNoRGlhY3JpdGljcyA/PyBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG1hdGNoUmVnRXhwQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWF0Y2hSZWdFeHAnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgICBpZiAobWF0Y2hSZWdFeHBDaGVja2JveCkge1xuICAgICAgICAgIG1hdGNoUmVnRXhwQ2hlY2tib3guY2hlY2tlZCA9IG9wdGlvbnMucmVnZXhwID8/IGZhbHNlO1xuICAgICAgICAgIGlmIChtYXRjaFJlZ0V4cENoZWNrYm94LmNoZWNrZWQpIHtcbiAgICAgICAgICAgIGlmIChmaW5kTXVsdGlwbGVDaGVja2JveCkge1xuICAgICAgICAgICAgICBmaW5kTXVsdGlwbGVDaGVja2JveC5jaGVja2VkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZW50aXJlV29yZENoZWNrYm94KSB7XG4gICAgICAgICAgICAgIGVudGlyZVdvcmRDaGVja2JveC5jaGVja2VkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtYXRjaERpYWNyaXRpY3NDaGVja2JveCkge1xuICAgICAgICAgICAgICBtYXRjaERpYWNyaXRpY3NDaGVja2JveC5jaGVja2VkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChmaW5kTXVsdGlwbGVDaGVja2JveCkge1xuICAgICAgICAgICAgZmluZE11bHRpcGxlQ2hlY2tib3guZGlzYWJsZWQgPSBtYXRjaFJlZ0V4cENoZWNrYm94LmNoZWNrZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChlbnRpcmVXb3JkQ2hlY2tib3gpIHtcbiAgICAgICAgICAgIGVudGlyZVdvcmRDaGVja2JveC5kaXNhYmxlZCA9IG1hdGNoUmVnRXhwQ2hlY2tib3guY2hlY2tlZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobWF0Y2hEaWFjcml0aWNzQ2hlY2tib3gpIHtcbiAgICAgICAgICAgIG1hdGNoRGlhY3JpdGljc0NoZWNrYm94LmRpc2FibGVkID0gbWF0Y2hSZWdFeHBDaGVja2JveC5jaGVja2VkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlucHV0RmllbGQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0JykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgaWYgKGlucHV0RmllbGQgJiYgdHlwZW9mIHRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgaW5wdXRGaWVsZC52YWx1ZSA9IHRleHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgZmluZFBhcmFtZXRlcnM6IFBERkZpbmRQYXJhbWV0ZXJzID0ge1xuICAgICAgICBjYXNlU2Vuc2l0aXZlOiBvcHRpb25zLm1hdGNoQ2FzZSA/PyBmYWxzZSxcbiAgICAgICAgZW50aXJlV29yZDogb3B0aW9ucy53aG9sZVdvcmRzID8/IGZhbHNlLFxuICAgICAgICBoaWdobGlnaHRBbGw6IG9wdGlvbnMuaGlnaGxpZ2h0QWxsID8/IGZhbHNlLFxuICAgICAgICBtYXRjaERpYWNyaXRpY3M6IG9wdGlvbnMubWF0Y2hEaWFjcml0aWNzID8/IGZhbHNlLFxuICAgICAgICBmaW5kTXVsdGlwbGU6IG9wdGlvbnMuZmluZE11bHRpcGxlLFxuICAgICAgICBtYXRjaFJlZ0V4cDogb3B0aW9ucy5yZWdleHAgPz8gZmFsc2UsXG4gICAgICAgIGZpbmRQcmV2aW91czogZmFsc2UsXG4gICAgICAgIHF1ZXJ5OiB0ZXh0LFxuICAgICAgICBzb3VyY2U6IG51bGwsXG4gICAgICAgIHR5cGU6ICdmaW5kJyxcbiAgICAgICAgZG9udFNjcm9sbEludG9WaWV3OiBvcHRpb25zLmRvbnRTY3JvbGxJbnRvVmlldyA/PyBmYWxzZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBmaW5kQ29udHJvbGxlciA9IG9wdGlvbnMudXNlU2Vjb25kYXJ5RmluZGNvbnRyb2xsZXIgPyB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5jdXN0b21GaW5kQ29udHJvbGxlciA6IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LmZpbmRDb250cm9sbGVyO1xuICAgICAgY29uc3QgcmVzdWx0ID0gZmluZENvbnRyb2xsZXI/Lm5neEZpbmQoZmluZFBhcmFtZXRlcnMpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZmluZE5leHQodXNlU2Vjb25kYXJ5RmluZGNvbnRyb2xsZXI6IGJvb2xlYW4gPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5uZ3hFeHRlbmRlZFBkZlZpZXdlckluaXRpYWxpemVkKSB7XG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6cXVvdGVtYXJrXG4gICAgICBjb25zb2xlLmVycm9yKFwiVGhlIFBERiB2aWV3ZXIgaGFzbid0IGZpbmlzaGVkIGluaXRpYWxpemluZy4gUGxlYXNlIGNhbGwgZmluZE5leHQoKSBsYXRlci5cIik7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGZpbmRDb250cm9sbGVyID0gdXNlU2Vjb25kYXJ5RmluZGNvbnRyb2xsZXIgPyB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5jdXN0b21GaW5kQ29udHJvbGxlciA6IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LmZpbmRDb250cm9sbGVyO1xuICAgICAgZmluZENvbnRyb2xsZXI/Lm5neEZpbmROZXh0KCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZmluZFByZXZpb3VzKHVzZVNlY29uZGFyeUZpbmRjb250cm9sbGVyOiBib29sZWFuID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMubmd4RXh0ZW5kZWRQZGZWaWV3ZXJJbml0aWFsaXplZCkge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnF1b3RlbWFya1xuICAgICAgY29uc29sZS5lcnJvcihcIlRoZSBQREYgdmlld2VyIGhhc24ndCBmaW5pc2hlZCBpbml0aWFsaXppbmcuIFBsZWFzZSBjYWxsIGZpbmRQcmV2aW91cygpIGxhdGVyLlwiKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZmluZENvbnRyb2xsZXIgPSB1c2VTZWNvbmRhcnlGaW5kY29udHJvbGxlciA/IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LmN1c3RvbUZpbmRDb250cm9sbGVyIDogdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8uZmluZENvbnRyb2xsZXI7XG4gICAgICBmaW5kQ29udHJvbGxlcj8ubmd4RmluZFByZXZpb3VzKCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcHJpbnQocHJpbnRSYW5nZT86IFBERlByaW50UmFuZ2UpIHtcbiAgICBpZiAodGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbikge1xuICAgICAgY29uc3QgYWxyZWFkeVByaW50aW5nID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8uUERGUHJpbnRTZXJ2aWNlRmFjdG9yeT8uaXNJblBERlByaW50UmFuZ2UgIT09IHVuZGVmaW5lZDtcbiAgICAgIGlmICghYWxyZWFkeVByaW50aW5nKSB7XG4gICAgICAgIC8vIHNsb3cgZG93biBodXJyaWVkIHVzZXJzIGNsaWNraW5nIHRoZSBwcmludCBidXR0b24gbXVsdGlwbGUgdGltZXNcbiAgICAgICAgaWYgKCFwcmludFJhbmdlKSB7XG4gICAgICAgICAgcHJpbnRSYW5nZSA9IHt9IGFzIFBERlByaW50UmFuZ2U7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRQcmludFJhbmdlKHByaW50UmFuZ2UpO1xuICAgICAgICB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wcmludFBkZigpO1xuICAgICAgICB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5ldmVudEJ1cy5vbignYWZ0ZXJwcmludCcsIHRoaXMucmVtb3ZlUHJpbnRSYW5nZS5iaW5kKHRoaXMpLCB7IG9uY2U6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlbW92ZVByaW50UmFuZ2UoKSB7XG4gICAgaWYgKHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LlBERlByaW50U2VydmljZUZhY3RvcnkpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uLlBERlByaW50U2VydmljZUZhY3RvcnkuaXNJblBERlByaW50UmFuZ2U7XG4gICAgICBkZWxldGUgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbi5QREZQcmludFNlcnZpY2VGYWN0b3J5LmZpbHRlcmVkUGFnZUNvdW50O1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRQcmludFJhbmdlKHByaW50UmFuZ2U6IFBERlByaW50UmFuZ2UpIHtcbiAgICBpZiAoIXRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LlBERlByaW50U2VydmljZUZhY3RvcnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaGUgcHJpbnQgc2VydmljZSBoYXNuJ3QgYmVlbiBpbml0aWFsaXplZCB5ZXQuXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24uUERGUHJpbnRTZXJ2aWNlRmFjdG9yeS5pc0luUERGUHJpbnRSYW5nZSA9IChwYWdlOiBudW1iZXIpID0+IHRoaXMuaXNJblBERlByaW50UmFuZ2UocGFnZSwgcHJpbnRSYW5nZSk7XG4gICAgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbi5QREZQcmludFNlcnZpY2VGYWN0b3J5LmZpbHRlcmVkUGFnZUNvdW50ID0gdGhpcy5maWx0ZXJlZFBhZ2VDb3VudCh0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wYWdlc0NvdW50LCBwcmludFJhbmdlKTtcbiAgfVxuXG4gIHB1YmxpYyBmaWx0ZXJlZFBhZ2VDb3VudChwYWdlQ291bnQ6IG51bWJlciwgcmFuZ2U6IFBERlByaW50UmFuZ2UpOiBudW1iZXIge1xuICAgIGxldCByZXN1bHQgPSAwO1xuICAgIGZvciAobGV0IHBhZ2UgPSAwOyBwYWdlIDwgcGFnZUNvdW50OyBwYWdlKyspIHtcbiAgICAgIGlmICh0aGlzLmlzSW5QREZQcmludFJhbmdlKHBhZ2UsIHJhbmdlKSkge1xuICAgICAgICByZXN1bHQrKztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBpc0luUERGUHJpbnRSYW5nZShwYWdlSW5kZXg6IG51bWJlciwgcHJpbnRSYW5nZTogUERGUHJpbnRSYW5nZSkge1xuICAgIGNvbnN0IHBhZ2UgPSBwYWdlSW5kZXggKyAxO1xuICAgIGlmIChwcmludFJhbmdlLmZyb20pIHtcbiAgICAgIGlmIChwYWdlIDwgcHJpbnRSYW5nZS5mcm9tKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHByaW50UmFuZ2UudG8pIHtcbiAgICAgIGlmIChwYWdlID4gcHJpbnRSYW5nZS50bykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcmludFJhbmdlLmV4Y2x1ZGVkKSB7XG4gICAgICBpZiAocHJpbnRSYW5nZS5leGNsdWRlZC5zb21lKChwKSA9PiBwID09PSBwYWdlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcmludFJhbmdlLmluY2x1ZGVkKSB7XG4gICAgICBpZiAoIXByaW50UmFuZ2UuaW5jbHVkZWQuc29tZSgocCkgPT4gcCA9PT0gcGFnZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRQYWdlQXNMaW5lcyhwYWdlTnVtYmVyOiBudW1iZXIpOiBQcm9taXNlPEFycmF5PExpbmU+PiB7XG4gICAgaWYgKHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24pIHtcbiAgICAgIGNvbnN0IHBkZkRvY3VtZW50ID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmRG9jdW1lbnQ7XG5cbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBwZGZEb2N1bWVudC5nZXRQYWdlKHBhZ2VOdW1iZXIpO1xuICAgICAgY29uc3QgdGV4dFNuaXBwZXRzID0gKGF3YWl0IHBhZ2UuZ2V0VGV4dENvbnRlbnQoKSkuaXRlbXMgLy9cbiAgICAgICAgLmZpbHRlcigoaW5mbykgPT4gIWluZm9bJ3R5cGUnXSk7IC8vIGlnbm9yZSB0aGUgVGV4dE1hcmtlZENvbnRlbnQgaXRlbXNcblxuICAgICAgY29uc3Qgc25pcHBldHMgPSB0ZXh0U25pcHBldHMgYXMgQXJyYXk8VGV4dEl0ZW0+O1xuXG4gICAgICBsZXQgbWluWCA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgICAgbGV0IG1pblkgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICAgIGxldCBtYXhYID0gTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVI7XG4gICAgICBsZXQgbWF4WSA9IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSO1xuICAgICAgbGV0IGNvdW50TFRSID0gMDtcbiAgICAgIGxldCBjb3VudFJUTCA9IDA7XG4gICAgICBsZXQgdGV4dCA9ICcnO1xuICAgICAgbGV0IGxpbmVzID0gbmV3IEFycmF5PExpbmU+KCk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNuaXBwZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRTbmlwcGV0ID0gc25pcHBldHNbaV07XG4gICAgICAgIGlmICghY3VycmVudFNuaXBwZXQuaGFzRU9MKSB7XG4gICAgICAgICAgY29uc3QgeCA9IGN1cnJlbnRTbmlwcGV0LnRyYW5zZm9ybVs0XTtcbiAgICAgICAgICBjb25zdCB5ID0gLWN1cnJlbnRTbmlwcGV0LnRyYW5zZm9ybVs1XTtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IGN1cnJlbnRTbmlwcGV0LndpZHRoO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IGN1cnJlbnRTbmlwcGV0LmhlaWdodDtcbiAgICAgICAgICBtaW5YID0gTWF0aC5taW4obWluWCwgeCk7XG4gICAgICAgICAgbWluWSA9IE1hdGgubWluKG1pblksIHkpO1xuICAgICAgICAgIG1heFggPSBNYXRoLm1heChtYXhYLCB4ICsgd2lkdGgpO1xuICAgICAgICAgIG1heFkgPSBNYXRoLm1heChtYXhZLCB5ICsgaGVpZ2h0KTtcbiAgICAgICAgICB0ZXh0ICs9IGN1cnJlbnRTbmlwcGV0LnN0cjtcbiAgICAgICAgICBpZiAoY3VycmVudFNuaXBwZXQuZGlyID09PSAncnRsJykge1xuICAgICAgICAgICAgY291bnRSVEwrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGN1cnJlbnRTbmlwcGV0LmRpciA9PT0gJ2x0cicpIHtcbiAgICAgICAgICAgIGNvdW50TFRSKys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGFkZEl0ID0gaSA9PT0gc25pcHBldHMubGVuZ3RoIC0gMSB8fCBjdXJyZW50U25pcHBldC5oYXNFT0w7XG4gICAgICAgIGlmIChhZGRJdCkge1xuICAgICAgICAgIGxldCBkaXJlY3Rpb246IERpcmVjdGlvblR5cGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKGNvdW50TFRSID4gMCAmJiBjb3VudFJUTCA+IDApIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbiA9ICdib3RoJztcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvdW50TFRSID4gMCkge1xuICAgICAgICAgICAgZGlyZWN0aW9uID0gJ2x0cic7XG4gICAgICAgICAgfSBlbHNlIGlmIChjb3VudFJUTCA+IDApIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbiA9ICdydGwnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBsaW5lID0ge1xuICAgICAgICAgICAgZGlyZWN0aW9uLFxuICAgICAgICAgICAgeDogbWluWCxcbiAgICAgICAgICAgIHk6IG1pblksXG4gICAgICAgICAgICB3aWR0aDogbWF4WCAtIG1pblgsXG4gICAgICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZLFxuICAgICAgICAgICAgdGV4dDogdGV4dC50cmltKCksXG4gICAgICAgICAgfSBhcyBMaW5lO1xuICAgICAgICAgIGxpbmVzLnB1c2gobGluZSk7XG4gICAgICAgICAgbWluWCA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgICAgICAgIG1pblkgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICAgICAgICBtYXhYID0gTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVI7XG4gICAgICAgICAgbWF4WSA9IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSO1xuICAgICAgICAgIGNvdW50TFRSID0gMDtcbiAgICAgICAgICBjb3VudFJUTCA9IDA7XG4gICAgICAgICAgdGV4dCA9ICcnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbGluZXM7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRQYWdlQXNUZXh0KHBhZ2VOdW1iZXI6IG51bWJlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgaWYgKCF0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGNvbnN0IHBkZkRvY3VtZW50ID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmRG9jdW1lbnQ7XG5cbiAgICBjb25zdCBwYWdlID0gYXdhaXQgcGRmRG9jdW1lbnQuZ2V0UGFnZShwYWdlTnVtYmVyKTtcbiAgICBjb25zdCB0ZXh0U25pcHBldHMgPSAoYXdhaXQgcGFnZS5nZXRUZXh0Q29udGVudCgpKS5pdGVtcztcbiAgICByZXR1cm4gdGhpcy5jb252ZXJ0VGV4dEluZm9Ub1RleHQodGV4dFNuaXBwZXRzKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydFRleHRJbmZvVG9UZXh0KHRleHRJbmZvSXRlbXM6IEFycmF5PFRleHRJdGVtIHwgVGV4dE1hcmtlZENvbnRlbnQ+KTogc3RyaW5nIHtcbiAgICBpZiAoIXRleHRJbmZvSXRlbXMpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIHRleHRJbmZvSXRlbXNcbiAgICAgIC5maWx0ZXIoKGluZm8pID0+ICFpbmZvWyd0eXBlJ10pXG4gICAgICAubWFwKChpbmZvOiBUZXh0SXRlbSkgPT4gKGluZm8uaGFzRU9MID8gaW5mby5zdHIgKyAnXFxuJyA6IGluZm8uc3RyKSlcbiAgICAgIC5qb2luKCcnKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRQYWdlQXNDYW52YXMoXG4gICAgcGFnZU51bWJlcjogbnVtYmVyLFxuICAgIHNjYWxlOiBQREZFeHBvcnRTY2FsZUZhY3RvcixcbiAgICBiYWNrZ3JvdW5kPzogc3RyaW5nLFxuICAgIGJhY2tncm91bmRDb2xvclRvUmVwbGFjZTogc3RyaW5nID0gJyNGRkZGRkYnLFxuICAgIGFubm90YXRpb25Nb2RlOiBBbm5vdGF0aW9uTW9kZSA9IEFubm90YXRpb25Nb2RlLkVOQUJMRSxcbiAgKTogUHJvbWlzZTxIVE1MQ2FudmFzRWxlbWVudCB8IHVuZGVmaW5lZD4ge1xuICAgIGlmICghdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBjb25zdCBwZGZEb2N1bWVudCA9IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24ucGRmRG9jdW1lbnQ7XG4gICAgY29uc3QgcGRmUGFnZSA9IGF3YWl0IHBkZkRvY3VtZW50LmdldFBhZ2UocGFnZU51bWJlcik7XG4gICAgcmV0dXJuIHRoaXMuZHJhdyhwZGZQYWdlLCBzY2FsZSwgYmFja2dyb3VuZCwgYmFja2dyb3VuZENvbG9yVG9SZXBsYWNlLCBhbm5vdGF0aW9uTW9kZSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0UGFnZUFzSW1hZ2UoXG4gICAgcGFnZU51bWJlcjogbnVtYmVyLFxuICAgIHNjYWxlOiBQREZFeHBvcnRTY2FsZUZhY3RvcixcbiAgICBiYWNrZ3JvdW5kPzogc3RyaW5nLFxuICAgIGJhY2tncm91bmRDb2xvclRvUmVwbGFjZTogc3RyaW5nID0gJyNGRkZGRkYnLFxuICAgIGFubm90YXRpb25Nb2RlOiBBbm5vdGF0aW9uTW9kZSA9IEFubm90YXRpb25Nb2RlLkVOQUJMRSxcbiAgKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBjYW52YXMgPSBhd2FpdCB0aGlzLmdldFBhZ2VBc0NhbnZhcyhwYWdlTnVtYmVyLCBzY2FsZSwgYmFja2dyb3VuZCwgYmFja2dyb3VuZENvbG9yVG9SZXBsYWNlLCBhbm5vdGF0aW9uTW9kZSk7XG4gICAgcmV0dXJuIGNhbnZhcz8udG9EYXRhVVJMKCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRyYXcoXG4gICAgcGRmUGFnZTogUERGUGFnZVByb3h5LFxuICAgIHNjYWxlOiBQREZFeHBvcnRTY2FsZUZhY3RvcixcbiAgICBiYWNrZ3JvdW5kPzogc3RyaW5nLFxuICAgIGJhY2tncm91bmRDb2xvclRvUmVwbGFjZTogc3RyaW5nID0gJyNGRkZGRkYnLFxuICAgIGFubm90YXRpb25Nb2RlOiBBbm5vdGF0aW9uTW9kZSA9IEFubm90YXRpb25Nb2RlLkVOQUJMRSxcbiAgKTogUHJvbWlzZTxIVE1MQ2FudmFzRWxlbWVudD4ge1xuICAgIGxldCB6b29tRmFjdG9yID0gMTtcbiAgICBpZiAoc2NhbGUuc2NhbGUpIHtcbiAgICAgIHpvb21GYWN0b3IgPSBzY2FsZS5zY2FsZTtcbiAgICB9IGVsc2UgaWYgKHNjYWxlLndpZHRoKSB7XG4gICAgICB6b29tRmFjdG9yID0gc2NhbGUud2lkdGggLyBwZGZQYWdlLmdldFZpZXdwb3J0KHsgc2NhbGU6IDEgfSkud2lkdGg7XG4gICAgfSBlbHNlIGlmIChzY2FsZS5oZWlnaHQpIHtcbiAgICAgIHpvb21GYWN0b3IgPSBzY2FsZS5oZWlnaHQgLyBwZGZQYWdlLmdldFZpZXdwb3J0KHsgc2NhbGU6IDEgfSkuaGVpZ2h0O1xuICAgIH1cbiAgICBjb25zdCB2aWV3cG9ydCA9IHBkZlBhZ2UuZ2V0Vmlld3BvcnQoe1xuICAgICAgc2NhbGU6IHpvb21GYWN0b3IsXG4gICAgfSk7XG4gICAgY29uc3QgeyBjdHgsIGNhbnZhcyB9ID0gdGhpcy5nZXRQYWdlRHJhd0NvbnRleHQodmlld3BvcnQud2lkdGgsIHZpZXdwb3J0LmhlaWdodCk7XG4gICAgY29uc3QgZHJhd1ZpZXdwb3J0ID0gdmlld3BvcnQuY2xvbmUoKTtcblxuICAgIGNvbnN0IHJlbmRlckNvbnRleHQgPSB7XG4gICAgICBjYW52YXNDb250ZXh0OiBjdHgsXG4gICAgICB2aWV3cG9ydDogZHJhd1ZpZXdwb3J0LFxuICAgICAgYmFja2dyb3VuZCxcbiAgICAgIGJhY2tncm91bmRDb2xvclRvUmVwbGFjZSxcbiAgICAgIGFubm90YXRpb25Nb2RlLFxuICAgIH07XG4gICAgY29uc3QgcmVuZGVyVGFzayA9IHBkZlBhZ2UucmVuZGVyKHJlbmRlckNvbnRleHQpO1xuXG4gICAgY29uc3QgZGF0YVVybFByb21pc2UgPSAoKSA9PiBQcm9taXNlLnJlc29sdmUoY2FudmFzKTtcblxuICAgIHJldHVybiByZW5kZXJUYXNrLnByb21pc2UudGhlbihkYXRhVXJsUHJvbWlzZSk7XG4gIH1cblxuICBwcml2YXRlIGdldFBhZ2VEcmF3Q29udGV4dCh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IERyYXdDb250ZXh0IHtcbiAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7IGFscGhhOiB0cnVlIH0pO1xuICAgIGlmICghY3R4KSB7XG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IHF1b3RlbWFya1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGRuJ3QgY3JlYXRlIHRoZSAyZCBjb250ZXh0XCIpO1xuICAgIH1cblxuICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShjYW52YXMsICd3aWR0aCcsIGAke3dpZHRofXB4YCk7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShjYW52YXMsICdoZWlnaHQnLCBgJHtoZWlnaHR9cHhgKTtcblxuICAgIHJldHVybiB7IGN0eCwgY2FudmFzIH07XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0Q3VycmVudERvY3VtZW50QXNCbG9iKCk6IFByb21pc2U8QmxvYiB8IHVuZGVmaW5lZD4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8uZXhwb3J0KCkpIHx8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRGb3JtRGF0YShjdXJyZW50Rm9ybVZhbHVlcyA9IHRydWUpOiBQcm9taXNlPEFycmF5PE9iamVjdD4+IHtcbiAgICBpZiAoIXRoaXMuUERGVmlld2VyQXBwbGljYXRpb24pIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgY29uc3QgcGRmOiBQREZEb2N1bWVudFByb3h5IHwgdW5kZWZpbmVkID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmRG9jdW1lbnQ7XG4gICAgLy8gc2NyZWVuIERQSSAvIFBERiBEUElcbiAgICBjb25zdCBkcGlSYXRpbyA9IDk2IC8gNzI7XG4gICAgY29uc3QgcmVzdWx0OiBBcnJheTxPYmplY3Q+ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gcGRmPy5udW1QYWdlczsgaSsrKSB7XG4gICAgICAvLyB0cmFjayB0aGUgY3VycmVudCBwYWdlXG4gICAgICBjb25zdCBjdXJyZW50UGFnZSAvKiA6IFBERlBhZ2VQcm94eSAqLyA9IGF3YWl0IHBkZi5nZXRQYWdlKGkpO1xuICAgICAgY29uc3QgYW5ub3RhdGlvbnMgPSBhd2FpdCBjdXJyZW50UGFnZS5nZXRBbm5vdGF0aW9ucygpO1xuXG4gICAgICBhbm5vdGF0aW9uc1xuICAgICAgICAuZmlsdGVyKChhKSA9PiBhLnN1YnR5cGUgPT09ICdXaWRnZXQnKSAvLyBnZXQgdGhlIGZvcm0gZmllbGQgYW5ub3RhdGlvbnMgb25seVxuICAgICAgICAubWFwKChhKSA9PiAoeyAuLi5hIH0pKSAvLyBvbmx5IGV4cG9zZSBjb3BpZXMgb2YgdGhlIGFubm90YXRpb25zIHRvIGF2b2lkIHNpZGUtZWZmZWN0c1xuICAgICAgICAuZm9yRWFjaCgoYSkgPT4ge1xuICAgICAgICAgIC8vIGdldCB0aGUgcmVjdGFuZ2xlIHRoYXQgcmVwcmVzZW50IHRoZSBzaW5nbGUgZmllbGRcbiAgICAgICAgICAvLyBhbmQgcmVzaXplIGl0IGFjY29yZGluZyB0byB0aGUgY3VycmVudCBEUElcbiAgICAgICAgICBjb25zdCBmaWVsZFJlY3Q6IEFycmF5PG51bWJlcj4gPSBjdXJyZW50UGFnZS5nZXRWaWV3cG9ydCh7IHNjYWxlOiBkcGlSYXRpbyB9KS5jb252ZXJ0VG9WaWV3cG9ydFJlY3RhbmdsZShhLnJlY3QpO1xuXG4gICAgICAgICAgLy8gYWRkIHRoZSBjb3JyZXNwb25kaW5nIGlucHV0XG4gICAgICAgICAgaWYgKGN1cnJlbnRGb3JtVmFsdWVzICYmIGEuZmllbGROYW1lKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoYS5leHBvcnRWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZTogYW55ID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmRG9jdW1lbnQuYW5ub3RhdGlvblN0b3JhZ2UuZ2V0VmFsdWUoYS5pZCwgYS5maWVsZE5hbWUgKyAnLycgKyBhLmV4cG9ydFZhbHVlLCAnJyk7XG4gICAgICAgICAgICAgICAgYS52YWx1ZSA9IGN1cnJlbnRWYWx1ZT8udmFsdWU7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoYS5yYWRpb0J1dHRvbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZTogYW55ID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmRG9jdW1lbnQuYW5ub3RhdGlvblN0b3JhZ2UuZ2V0VmFsdWUoYS5pZCwgYS5maWVsZE5hbWUgKyAnLycgKyBhLmZpZWxkVmFsdWUsICcnKTtcbiAgICAgICAgICAgICAgICBhLnZhbHVlID0gY3VycmVudFZhbHVlPy52YWx1ZTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWU6IGFueSA9IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LnBkZkRvY3VtZW50LmFubm90YXRpb25TdG9yYWdlLmdldFZhbHVlKGEuaWQsIGEuZmllbGROYW1lLCAnJyk7XG4gICAgICAgICAgICAgICAgYS52YWx1ZSA9IGN1cnJlbnRWYWx1ZT8udmFsdWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAvLyBqdXN0IGlnbm9yZSBpdFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQucHVzaCh7IGZpZWxkQW5ub3RhdGlvbjogYSwgZmllbGRSZWN0LCBwYWdlTnVtYmVyOiBpIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcGFnZSB0byB0aGUgcmVuZGVyaW5nIHF1ZXVlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlSW5kZXggSW5kZXggb2YgdGhlIHBhZ2UgdG8gcmVuZGVyXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBmYWxzZSwgaWYgdGhlIHBhZ2UgaGFzIGFscmVhZHkgYmVlbiByZW5kZXJlZCxcbiAgICogaWYgaXQncyBvdXQgb2YgcmFuZ2Ugb3IgaWYgdGhlIHZpZXdlciBoYXNuJ3QgYmVlbiBpbml0aWFsaXplZCB5ZXRcbiAgICovXG4gIHB1YmxpYyBhZGRQYWdlVG9SZW5kZXJRdWV1ZShwYWdlSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wZGZWaWV3ZXIuYWRkUGFnZVRvUmVuZGVyUXVldWUocGFnZUluZGV4KSA/PyBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBpc1JlbmRlclF1ZXVlRW1wdHkoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc2Nyb2xsZWREb3duID0gdHJ1ZTtcbiAgICBjb25zdCByZW5kZXJFeHRyYSA9IGZhbHNlO1xuICAgIGlmICh0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uKSB7XG4gICAgICBjb25zdCBuZXh0UGFnZSA9IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLnJlbmRlcmluZ1F1ZXVlLmdldEhpZ2hlc3RQcmlvcml0eShcbiAgICAgICAgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmVmlld2VyLl9nZXRWaXNpYmxlUGFnZXMoKSxcbiAgICAgICAgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmVmlld2VyLl9wYWdlcyxcbiAgICAgICAgc2Nyb2xsZWREb3duLFxuICAgICAgICByZW5kZXJFeHRyYSxcbiAgICAgICk7XG4gICAgICByZXR1cm4gIW5leHRQYWdlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBoYXNQYWdlQmVlblJlbmRlcmVkKHBhZ2VJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHBhZ2VzID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmVmlld2VyLl9wYWdlcztcbiAgICBpZiAocGFnZXMubGVuZ3RoID4gcGFnZUluZGV4ICYmIHBhZ2VJbmRleCA+PSAwKSB7XG4gICAgICBjb25zdCBwYWdlVmlldyA9IHBhZ2VzW3BhZ2VJbmRleF07XG4gICAgICBjb25zdCBoYXNCZWVuUmVuZGVyZWQgPSBwYWdlVmlldy5yZW5kZXJpbmdTdGF0ZSA9PT0gMztcbiAgICAgIHJldHVybiBoYXNCZWVuUmVuZGVyZWQ7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlbmRlclBhZ2UocGFnZUluZGV4OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuaGFzUGFnZUJlZW5SZW5kZXJlZChwYWdlSW5kZXgpKSB7XG4gICAgICBhd2FpdCB0aGlzLmFkZFBhZ2VUb1JlbmRlclF1ZXVlKHBhZ2VJbmRleCk7XG4gICAgICB3aGlsZSAoIXRoaXMuaGFzUGFnZUJlZW5SZW5kZXJlZChwYWdlSW5kZXgpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2xlZXAoNyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGN1cnJlbnRseVJlbmRlcmVkUGFnZXMoKTogQXJyYXk8bnVtYmVyPiB7XG4gICAgaWYgKCF0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IHBhZ2VzID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmVmlld2VyLl9wYWdlcztcbiAgICByZXR1cm4gcGFnZXMuZmlsdGVyKChwYWdlKSA9PiBwYWdlLnJlbmRlcmluZ1N0YXRlID09PSAzKS5tYXAoKHBhZ2UpID0+IHBhZ2UuaWQpO1xuICB9XG5cbiAgcHVibGljIG51bWJlck9mUGFnZXMoKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuUERGVmlld2VyQXBwbGljYXRpb24pIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjb25zdCBwYWdlcyA9IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LnBkZlZpZXdlci5fcGFnZXM7XG4gICAgcmV0dXJuIHBhZ2VzLmxlbmd0aDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDdXJyZW50bHlWaXNpYmxlUGFnZU51bWJlcnMoKTogQXJyYXk8bnVtYmVyPiB7XG4gICAgY29uc3QgYXBwID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBpZiAoIWFwcCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCBwYWdlcyA9IChhcHAucGRmVmlld2VyLl9nZXRWaXNpYmxlUGFnZXMoKSBhcyBhbnkpLnZpZXdzIGFzIEFycmF5PGFueT47XG4gICAgcmV0dXJuIHBhZ2VzPy5tYXAoKHBhZ2UpID0+IHBhZ2UuaWQpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RMYXllcnMoKTogUHJvbWlzZTxBcnJheTxQZGZMYXllcj4gfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoIXRoaXMuUERGVmlld2VyQXBwbGljYXRpb24pIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25hbENvbnRlbnRDb25maWcgPSBhd2FpdCB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wZGZWaWV3ZXIub3B0aW9uYWxDb250ZW50Q29uZmlnUHJvbWlzZTtcbiAgICBpZiAob3B0aW9uYWxDb250ZW50Q29uZmlnKSB7XG4gICAgICBjb25zdCBsZXZlbERhdGEgPSBvcHRpb25hbENvbnRlbnRDb25maWcuZ2V0T3JkZXIoKTtcbiAgICAgIGNvbnN0IGxheWVySWRzID0gbGV2ZWxEYXRhLmZpbHRlcigoZ3JvdXBJZCkgPT4gdHlwZW9mIGdyb3VwSWQgIT09ICdvYmplY3QnKTtcbiAgICAgIHJldHVybiBsYXllcklkcy5tYXAoKGxheWVySWQpID0+IHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gb3B0aW9uYWxDb250ZW50Q29uZmlnLmdldEdyb3VwKGxheWVySWQpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxheWVySWQ6IGxheWVySWQsXG4gICAgICAgICAgbmFtZTogY29uZmlnLm5hbWUsXG4gICAgICAgICAgdmlzaWJsZTogY29uZmlnLnZpc2libGUsXG4gICAgICAgIH0gYXMgUGRmTGF5ZXI7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyB0b2dnbGVMYXllcihsYXllcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuUERGVmlld2VyQXBwbGljYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgb3B0aW9uYWxDb250ZW50Q29uZmlnID0gYXdhaXQgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmVmlld2VyLm9wdGlvbmFsQ29udGVudENvbmZpZ1Byb21pc2U7XG4gICAgaWYgKG9wdGlvbmFsQ29udGVudENvbmZpZykge1xuICAgICAgbGV0IGlzVmlzaWJsZSA9IG9wdGlvbmFsQ29udGVudENvbmZpZy5nZXRHcm91cChsYXllcklkKS52aXNpYmxlO1xuICAgICAgY29uc3QgY2hlY2tib3ggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBpbnB1dFtpZD0nJHtsYXllcklkfSddYCk7XG4gICAgICBpZiAoY2hlY2tib3gpIHtcbiAgICAgICAgaXNWaXNpYmxlID0gKGNoZWNrYm94IGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNoZWNrZWQ7XG4gICAgICAgIChjaGVja2JveCBhcyBIVE1MSW5wdXRFbGVtZW50KS5jaGVja2VkID0gIWlzVmlzaWJsZTtcbiAgICAgIH1cbiAgICAgIG9wdGlvbmFsQ29udGVudENvbmZpZy5zZXRWaXNpYmlsaXR5KGxheWVySWQsICFpc1Zpc2libGUpO1xuICAgICAgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8uZXZlbnRCdXMuZGlzcGF0Y2goJ29wdGlvbmFsY29udGVudGNvbmZpZycsIHtcbiAgICAgICAgc291cmNlOiB0aGlzLFxuICAgICAgICBwcm9taXNlOiBQcm9taXNlLnJlc29sdmUob3B0aW9uYWxDb250ZW50Q29uZmlnKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzY3JvbGxQYWdlSW50b1ZpZXcocGFnZU51bWJlcjogbnVtYmVyLCBwYWdlU3BvdD86IHsgdG9wPzogbnVtYmVyIHwgc3RyaW5nOyBsZWZ0PzogbnVtYmVyIHwgc3RyaW5nIH0pOiB2b2lkIHtcbiAgICBjb25zdCB2aWV3ZXIgPSB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wZGZWaWV3ZXIgYXMgYW55O1xuICAgIHZpZXdlcj8uc2Nyb2xsUGFnZVBvc0ludG9WaWV3KHBhZ2VOdW1iZXIsIHBhZ2VTcG90KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRTZXJpYWxpemVkQW5ub3RhdGlvbnMoKTogRWRpdG9yQW5ub3RhdGlvbltdIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LnBkZlZpZXdlci5nZXRTZXJpYWxpemVkQW5ub3RhdGlvbnMoKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBhZGRFZGl0b3JBbm5vdGF0aW9uKHNlcmlhbGl6ZWRBbm5vdGF0aW9uOiBzdHJpbmcgfCBFZGl0b3JBbm5vdGF0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmVmlld2VyLmFkZEVkaXRvckFubm90YXRpb24oc2VyaWFsaXplZEFubm90YXRpb24pO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZUVkaXRvckFubm90YXRpb25zKGZpbHRlcj86IChzZXJpYWxpemVkOiBvYmplY3QpID0+IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wZGZWaWV3ZXIucmVtb3ZlRWRpdG9yQW5ub3RhdGlvbnMoZmlsdGVyKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZEltYWdlQXNEYXRhVVJMKGltYWdlVXJsOiBzdHJpbmcpOiBQcm9taXNlPEJsb2IgfCBzdHJpbmc+IHtcbiAgICBpZiAoaW1hZ2VVcmwuc3RhcnRzV2l0aCgnZGF0YTonKSkge1xuICAgICAgcmV0dXJuIGltYWdlVXJsO1xuICAgIH1cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGltYWdlVXJsKTtcbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCB0aGUgaW1hZ2UgZnJvbSAke2ltYWdlVXJsfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgIH1cblxuICAgIGNvbnN0IGltYWdlQmxvYiA9IGF3YWl0IHJlc3BvbnNlLmJsb2IoKTtcbiAgICByZXR1cm4gaW1hZ2VCbG9iO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGFkZEltYWdlVG9Bbm5vdGF0aW9uTGF5ZXIoeyB1cmxPckRhdGFVcmwsIHBhZ2UsIGxlZnQsIGJvdHRvbSwgcmlnaHQsIHRvcCwgcm90YXRpb24gfTogUGRmSW1hZ2VQYXJhbWV0ZXJzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgUERGIHZpZXdlciBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcGFnZVRvTW9kaWZ5OiBudW1iZXI7XG4gICAgaWYgKHBhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHBhZ2UgIT09IHRoaXMuY3VycmVudFBhZ2VJbmRleCgpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVuZGVyUGFnZShwYWdlKTtcbiAgICAgIH1cbiAgICAgIHBhZ2VUb01vZGlmeSA9IHBhZ2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhZ2VUb01vZGlmeSA9IHRoaXMuY3VycmVudFBhZ2VJbmRleCgpID8/IDA7XG4gICAgfVxuICAgIGNvbnN0IHByZXZpb3VzQW5ub3RhdGlvbkVkaXRvck1vZGUgPSB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5hbm5vdGF0aW9uRWRpdG9yTW9kZTtcbiAgICB0aGlzLnN3aXRjaEFubm90YXRpb25FZHRvck1vZGUoMTMpO1xuICAgIGNvbnN0IGRhdGFVcmwgPSBhd2FpdCB0aGlzLmxvYWRJbWFnZUFzRGF0YVVSTCh1cmxPckRhdGFVcmwpO1xuICAgIGNvbnN0IHBhZ2VTaXplID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIuX3BhZ2VzW3BhZ2VUb01vZGlmeV0ucGRmUGFnZS52aWV3O1xuICAgIGNvbnN0IGxlZnREaW0gPSBwYWdlU2l6ZVswXTtcbiAgICBjb25zdCBib3R0b21EaW0gPSBwYWdlU2l6ZVsxXTtcbiAgICBjb25zdCByaWdodERpbSA9IHBhZ2VTaXplWzJdO1xuICAgIGNvbnN0IHRvcERpbSA9IHBhZ2VTaXplWzNdO1xuICAgIGNvbnN0IHdpZHRoID0gcmlnaHREaW0gLSBsZWZ0RGltO1xuICAgIGNvbnN0IGhlaWdodCA9IHRvcERpbSAtIGJvdHRvbURpbTtcbiAgICBjb25zdCBpbWFnZVdpZHRoID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8ucGRmVmlld2VyLl9wYWdlc1twYWdlVG9Nb2RpZnldLmRpdi5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBpbWFnZUhlaWdodCA9IHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LnBkZlZpZXdlci5fcGFnZXNbcGFnZVRvTW9kaWZ5XS5kaXYuY2xpZW50SGVpZ2h0O1xuICAgIGNvbnN0IGxlZnRQZGYgPSB0aGlzLmNvbnZlcnRUb1BERkNvb3JkaW5hdGVzKGxlZnQsIHdpZHRoLCAwLCBpbWFnZVdpZHRoKTtcbiAgICBjb25zdCBib3R0b21QZGYgPSB0aGlzLmNvbnZlcnRUb1BERkNvb3JkaW5hdGVzKGJvdHRvbSwgaGVpZ2h0LCAwLCBpbWFnZUhlaWdodCk7XG4gICAgY29uc3QgcmlnaHRQZGYgPSB0aGlzLmNvbnZlcnRUb1BERkNvb3JkaW5hdGVzKHJpZ2h0LCB3aWR0aCwgd2lkdGgsIGltYWdlV2lkdGgpO1xuICAgIGNvbnN0IHRvcFBkZiA9IHRoaXMuY29udmVydFRvUERGQ29vcmRpbmF0ZXModG9wLCBoZWlnaHQsIGhlaWdodCwgaW1hZ2VIZWlnaHQpO1xuXG4gICAgY29uc3Qgc3RhbXBBbm5vdGF0aW9uOiBTdGFtcEVkaXRvckFubm90YXRpb24gPSB7XG4gICAgICBhbm5vdGF0aW9uVHlwZTogMTMsXG4gICAgICBwYWdlSW5kZXg6IHBhZ2VUb01vZGlmeSxcbiAgICAgIGJpdG1hcFVybDogZGF0YVVybCxcbiAgICAgIHJlY3Q6IFtsZWZ0UGRmLCBib3R0b21QZGYsIHJpZ2h0UGRmLCB0b3BQZGZdLFxuICAgICAgcm90YXRpb246IHJvdGF0aW9uID8/IDAsXG4gICAgICBpc0NvcHk6IHRydWUsXG4gICAgfTtcbiAgICB0aGlzLmFkZEVkaXRvckFubm90YXRpb24oc3RhbXBBbm5vdGF0aW9uKTtcbiAgICBhd2FpdCB0aGlzLnNsZWVwKDEwKTtcbiAgICB0aGlzLnN3aXRjaEFubm90YXRpb25FZHRvck1vZGUocHJldmlvdXNBbm5vdGF0aW9uRWRpdG9yTW9kZSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgYWRkSGlnaGxpZ2h0VG9Bbm5vdGF0aW9uTGF5ZXIoXG4gICAgY29sb3I6IG51bWJlcltdLFxuICAgIHBhZ2U6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICBsZWZ0OiBudW1iZXIgfCBzdHJpbmcsXG4gICAgYm90dG9tOiBudW1iZXIgfCBzdHJpbmcsXG4gICAgcmlnaHQ6IG51bWJlciB8IHN0cmluZyxcbiAgICB0b3A6IG51bWJlciB8IHN0cmluZyxcbiAgICB0aGlja25lc3M6IG51bWJlciA9IDEyLFxuICAgIHJvdGF0aW9uOiAwIHwgOTAgfCAxODAgfCAyNzAgPSAwLFxuICAgIG9wYWNpdHk6IG51bWJlciA9IDAuNSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgUERGIHZpZXdlciBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBwYWdlVG9Nb2RpZnk6IG51bWJlcjtcbiAgICBpZiAocGFnZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAocGFnZSAhPT0gdGhpcy5jdXJyZW50UGFnZUluZGV4KCkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZW5kZXJQYWdlKHBhZ2UpO1xuICAgICAgfVxuICAgICAgcGFnZVRvTW9kaWZ5ID0gcGFnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFnZVRvTW9kaWZ5ID0gdGhpcy5jdXJyZW50UGFnZUluZGV4KCkgPz8gMDtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2aW91c0Fubm90YXRpb25FZGl0b3JNb2RlID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIuYW5ub3RhdGlvbkVkaXRvck1vZGU7XG4gICAgdGhpcy5zd2l0Y2hBbm5vdGF0aW9uRWR0b3JNb2RlKDkpOyAvLyBBbm5vdGF0aW9uRWRpdG9yVHlwZS5ISUdITElHSFRcblxuICAgIGNvbnN0IHBhZ2VTaXplID0gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIuX3BhZ2VzW3BhZ2VUb01vZGlmeV0ucGRmUGFnZS52aWV3O1xuICAgIGNvbnN0IGxlZnREaW0gPSBwYWdlU2l6ZVswXTtcbiAgICBjb25zdCBib3R0b21EaW0gPSBwYWdlU2l6ZVsxXTtcbiAgICBjb25zdCByaWdodERpbSA9IHBhZ2VTaXplWzJdO1xuICAgIGNvbnN0IHRvcERpbSA9IHBhZ2VTaXplWzNdO1xuICAgIGNvbnN0IHdpZHRoID0gcmlnaHREaW0gLSBsZWZ0RGltO1xuICAgIGNvbnN0IGhlaWdodCA9IHRvcERpbSAtIGJvdHRvbURpbTtcbiAgICBjb25zdCBwYWdlV2lkdGggPSB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wZGZWaWV3ZXIuX3BhZ2VzW3BhZ2VUb01vZGlmeV0uZGl2LmNsaWVudFdpZHRoO1xuICAgIGNvbnN0IHBhZ2VIZWlnaHQgPSB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wZGZWaWV3ZXIuX3BhZ2VzW3BhZ2VUb01vZGlmeV0uZGl2LmNsaWVudEhlaWdodDtcblxuICAgIGNvbnN0IGxlZnRQZGYgPSB0aGlzLmNvbnZlcnRUb1BERkNvb3JkaW5hdGVzKGxlZnQsIHdpZHRoLCAwLCBwYWdlV2lkdGgpO1xuICAgIGNvbnN0IGJvdHRvbVBkZiA9IHRoaXMuY29udmVydFRvUERGQ29vcmRpbmF0ZXMoYm90dG9tLCBoZWlnaHQsIDAsIHBhZ2VIZWlnaHQpO1xuICAgIGNvbnN0IHJpZ2h0UGRmID0gdGhpcy5jb252ZXJ0VG9QREZDb29yZGluYXRlcyhyaWdodCwgd2lkdGgsIHdpZHRoLCBwYWdlV2lkdGgpO1xuICAgIGNvbnN0IHRvcFBkZiA9IHRoaXMuY29udmVydFRvUERGQ29vcmRpbmF0ZXModG9wLCBoZWlnaHQsIGhlaWdodCwgcGFnZUhlaWdodCk7XG5cbiAgICAvLyBDcmVhdGUgcXVhZFBvaW50cyBvYmplY3Qgd2l0aCBudW1lcmljIGtleXMgKG1hdGNoaW5nIGV4cG9ydCBmb3JtYXQpXG4gICAgY29uc3QgcXVhZFBvaW50czogYW55ID0ge307XG4gICAgcXVhZFBvaW50c1swXSA9IGxlZnRQZGY7IC8vIHgxIC0gbGVmdCBlZGdlIHN0YXJ0XG4gICAgcXVhZFBvaW50c1sxXSA9IHRvcFBkZjsgLy8geTEgLSB0b3AgZWRnZSBzdGFydFxuICAgIHF1YWRQb2ludHNbMl0gPSByaWdodFBkZjsgLy8geDIgLSByaWdodCBlZGdlIGVuZFxuICAgIHF1YWRQb2ludHNbM10gPSB0b3BQZGY7IC8vIHkyIC0gdG9wIGVkZ2UgZW5kXG4gICAgcXVhZFBvaW50c1s0XSA9IGxlZnRQZGY7IC8vIHgzIC0gbGVmdCBlZGdlIHN0YXJ0IChib3R0b20pXG4gICAgcXVhZFBvaW50c1s1XSA9IGJvdHRvbVBkZjsgLy8geTMgLSBib3R0b20gZWRnZSBzdGFydFxuICAgIHF1YWRQb2ludHNbNl0gPSByaWdodFBkZjsgLy8geDQgLSByaWdodCBlZGdlIGVuZCAoYm90dG9tKVxuICAgIHF1YWRQb2ludHNbN10gPSBib3R0b21QZGY7IC8vIHk0IC0gYm90dG9tIGVkZ2UgZW5kXG5cbiAgICBjb25zdCBoaWdobGlnaHRBbm5vdGF0aW9uOiBIaWdobGlnaHRFZGl0b3JBbm5vdGF0aW9uID0ge1xuICAgICAgYW5ub3RhdGlvblR5cGU6IDksXG4gICAgICBjb2xvcjogY29sb3IsXG4gICAgICBvcGFjaXR5OiBvcGFjaXR5LFxuICAgICAgdGhpY2tuZXNzOiB0aGlja25lc3MsXG4gICAgICBxdWFkUG9pbnRzOiBxdWFkUG9pbnRzLFxuICAgICAgb3V0bGluZXM6IFtcbiAgICAgICAgW1xuICAgICAgICAgIC8vIFNpbmdsZSBvdXRsaW5lIHJlY3RhbmdsZVxuICAgICAgICAgIGxlZnRQZGYsXG4gICAgICAgICAgYm90dG9tUGRmLCAvLyBCb3R0b20tbGVmdFxuICAgICAgICAgIGxlZnRQZGYsXG4gICAgICAgICAgdG9wUGRmLCAvLyBUb3AtbGVmdFxuICAgICAgICAgIHJpZ2h0UGRmLFxuICAgICAgICAgIHRvcFBkZiwgLy8gVG9wLXJpZ2h0XG4gICAgICAgICAgcmlnaHRQZGYsXG4gICAgICAgICAgYm90dG9tUGRmLCAvLyBCb3R0b20tcmlnaHRcbiAgICAgICAgXSxcbiAgICAgIF0sXG4gICAgICBwYWdlSW5kZXg6IHBhZ2VUb01vZGlmeSxcbiAgICAgIHJlY3Q6IFtsZWZ0UGRmLCBib3R0b21QZGYsIHJpZ2h0UGRmLCB0b3BQZGZdLFxuICAgICAgcm90YXRpb246IHJvdGF0aW9uLFxuICAgICAgaXNDb3B5OiB0cnVlLFxuICAgIH07XG5cbiAgICB0aGlzLmFkZEVkaXRvckFubm90YXRpb24oaGlnaGxpZ2h0QW5ub3RhdGlvbik7XG4gICAgYXdhaXQgdGhpcy5zbGVlcCgxMCk7XG4gICAgdGhpcy5zd2l0Y2hBbm5vdGF0aW9uRWR0b3JNb2RlKHByZXZpb3VzQW5ub3RhdGlvbkVkaXRvck1vZGUpO1xuICB9XG5cbiAgcHVibGljIGN1cnJlbnRQYWdlSW5kZXgoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2aWV3ZXIgPSB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uPy5wZGZWaWV3ZXI7XG4gICAgaWYgKHZpZXdlcikge1xuICAgICAgcmV0dXJuIHZpZXdlci5jdXJyZW50UGFnZU51bWJlciAtIDE7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRUb1BERkNvb3JkaW5hdGVzKHZhbHVlOiBab29tVHlwZSwgbWF4VmFsdWU6IG51bWJlciwgZGVmYXVsdFZhbHVlOiBudW1iZXIsIGltYWdlTWF4VmFsdWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICh2YWx1ZS5lbmRzV2l0aCgnJScpKSB7XG4gICAgICAgIHJldHVybiAocGFyc2VJbnQodmFsdWUsIDEwKSAvIDEwMCkgKiBtYXhWYWx1ZTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUuZW5kc1dpdGgoJ3B4JykpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCAxMCkgKiAobWF4VmFsdWUgLyBpbWFnZU1heFZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHN3aXRjaEFubm90YXRpb25FZHRvck1vZGUobW9kZTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbj8uZXZlbnRCdXMuZGlzcGF0Y2goJ3N3aXRjaGFubm90YXRpb25lZGl0b3Jtb2RlJywgeyBtb2RlIH0pO1xuICB9XG5cbiAgcHVibGljIHNldCBlZGl0b3JGb250U2l6ZShzaXplOiBudW1iZXIpIHtcbiAgICB0aGlzLnNldEVkaXRvclByb3BlcnR5KEFubm90YXRpb25FZGl0b3JQYXJhbXNUeXBlLkZSRUVURVhUX1NJWkUsIHNpemUpO1xuICB9XG5cbiAgcHVibGljIHNldCBlZGl0b3JGb250Q29sb3IoY29sb3I6IHN0cmluZykge1xuICAgIHRoaXMuc2V0RWRpdG9yUHJvcGVydHkoQW5ub3RhdGlvbkVkaXRvclBhcmFtc1R5cGUuRlJFRVRFWFRfQ09MT1IsIGNvbG9yKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXQgZWRpdG9ySW5rQ29sb3IoY29sb3I6IHN0cmluZykge1xuICAgIHRoaXMuc2V0RWRpdG9yUHJvcGVydHkoQW5ub3RhdGlvbkVkaXRvclBhcmFtc1R5cGUuSU5LX0NPTE9SLCBjb2xvcik7XG4gIH1cblxuICBwdWJsaWMgc2V0IGVkaXRvcklua09wYWNpdHkob3BhY2l0eTogbnVtYmVyKSB7XG4gICAgdGhpcy5zZXRFZGl0b3JQcm9wZXJ0eShBbm5vdGF0aW9uRWRpdG9yUGFyYW1zVHlwZS5JTktfT1BBQ0lUWSwgb3BhY2l0eSk7XG4gIH1cblxuICBwdWJsaWMgc2V0IGVkaXRvcklua1RoaWNrbmVzcyh0aGlja25lc3M6IG51bWJlcikge1xuICAgIHRoaXMuc2V0RWRpdG9yUHJvcGVydHkoQW5ub3RhdGlvbkVkaXRvclBhcmFtc1R5cGUuSU5LX1RISUNLTkVTUywgdGhpY2tuZXNzKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXQgZWRpdG9ySGlnaGxpZ2h0Q29sb3IoY29sb3I6IHN0cmluZykge1xuICAgIHRoaXMuc2V0RWRpdG9yUHJvcGVydHkoQW5ub3RhdGlvbkVkaXRvclBhcmFtc1R5cGUuSElHSExJR0hUX0NPTE9SLCBjb2xvcik7XG4gIH1cblxuICBwdWJsaWMgc2V0IGVkaXRvckhpZ2hsaWdodERlZmF1bHRDb2xvcihjb2xvcjogc3RyaW5nKSB7XG4gICAgdGhpcy5zZXRFZGl0b3JQcm9wZXJ0eShBbm5vdGF0aW9uRWRpdG9yUGFyYW1zVHlwZS5ISUdITElHSFRfREVGQVVMVF9DT0xPUiwgY29sb3IpO1xuICB9XG5cbiAgcHVibGljIHNldCBlZGl0b3JIaWdobGlnaHRTaG93QWxsKHNob3dBbGw6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnNldEVkaXRvclByb3BlcnR5KEFubm90YXRpb25FZGl0b3JQYXJhbXNUeXBlLkhJR0hMSUdIVF9TSE9XX0FMTCwgc2hvd0FsbCk7XG4gIH1cblxuICBwdWJsaWMgc2V0IGVkaXRvckhpZ2hsaWdodFRoaWNrbmVzcyh0aGlja25lc3M6IG51bWJlcikge1xuICAgIHRoaXMuc2V0RWRpdG9yUHJvcGVydHkoQW5ub3RhdGlvbkVkaXRvclBhcmFtc1R5cGUuSElHSExJR0hUX1RISUNLTkVTUywgdGhpY2tuZXNzKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRFZGl0b3JQcm9wZXJ0eShlZGl0b3JQcm9wZXJ0eVR5cGU6IG51bWJlciwgdmFsdWU6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LmV2ZW50QnVzLmRpc3BhdGNoKCdzd2l0Y2hhbm5vdGF0aW9uZWRpdG9ycGFyYW1zJywgeyB0eXBlOiBlZGl0b3JQcm9wZXJ0eVR5cGUsIHZhbHVlIH0pO1xuICAgIHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24/LmV2ZW50QnVzLmRpc3BhdGNoKCdhbm5vdGF0aW9uZWRpdG9ycGFyYW1zY2hhbmdlZCcsIHsgZGV0YWlsczogW1tlZGl0b3JQcm9wZXJ0eVR5cGUsIHZhbHVlXV0gfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q3VycmVudFBhZ2UoKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuUERGVmlld2VyQXBwbGljYXRpb24pIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbi5wYWdlID8/IDE7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGFnZUNvdW50KCk6IG51bWJlciB7XG4gICAgaWYgKCF0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuUERGVmlld2VyQXBwbGljYXRpb24ucGFnZXNDb3VudCA/PyAwO1xuICB9XG5cbiAgcHVibGljIG1vdmVQYWdlKGZyb21JbmRleDogbnVtYmVyLCB0b0luZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuUERGVmlld2VyQXBwbGljYXRpb24pIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1BERiB2aWV3ZXIgbm90IGluaXRpYWxpemVkJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgcGFnZSByZW9yZGVyaW5nIGlzIGVuYWJsZWRcbiAgICBjb25zdCBlbmFibGVQYWdlUmVvcmRlcmluZyA9IChnbG9iYWxUaGlzIGFzIGFueSkucGRmRGVmYXVsdE9wdGlvbnM/LmVuYWJsZVBhZ2VSZW9yZGVyaW5nO1xuICAgIGlmICghZW5hYmxlUGFnZVJlb3JkZXJpbmcpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1BhZ2UgcmVvcmRlcmluZyBpcyBub3QgZW5hYmxlZC4gU2V0IHBkZkRlZmF1bHRPcHRpb25zLmVuYWJsZVBhZ2VSZW9yZGVyaW5nID0gdHJ1ZScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIGluZGljZXMgKDEtYmFzZWQpXG4gICAgY29uc3QgcGFnZUNvdW50ID0gdGhpcy5nZXRQYWdlQ291bnQoKTtcbiAgICBpZiAoZnJvbUluZGV4IDwgMSB8fCBmcm9tSW5kZXggPiBwYWdlQ291bnQgfHwgdG9JbmRleCA8IDEgfHwgdG9JbmRleCA+IHBhZ2VDb3VudCkge1xuICAgICAgY29uc29sZS5lcnJvcihgSW52YWxpZCBwYWdlIGluZGljZXMuIGZyb21JbmRleDogJHtmcm9tSW5kZXh9LCB0b0luZGV4OiAke3RvSW5kZXh9LCBwYWdlQ291bnQ6ICR7cGFnZUNvdW50fWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChmcm9tSW5kZXggPT09IHRvSW5kZXgpIHtcbiAgICAgIHJldHVybjsgLy8gTm8gbW92ZW1lbnQgbmVlZGVkXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIENhbGwgdGhlIG1vdmVQYWdlIGZ1bmN0aW9uIGZyb20gYXBwLmpzXG4gICAgICBpZiAodGhpcy5QREZWaWV3ZXJBcHBsaWNhdGlvbi5tb3ZlUGFnZSkge1xuICAgICAgICB0aGlzLlBERlZpZXdlckFwcGxpY2F0aW9uLm1vdmVQYWdlKGZyb21JbmRleCwgdG9JbmRleCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdtb3ZlUGFnZSBmdW5jdGlvbiBub3QgYXZhaWxhYmxlIGluIFBERiB2aWV3ZXIgYXBwbGljYXRpb24nKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgbW92aW5nIHBhZ2U6JywgZXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIl19