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.
428 lines • 65 kB
JavaScript
import { Subject } from 'rxjs';
import { NgxExtendedPdfViewerComponent } from './ngx-extended-pdf-viewer.component';
export class NgxExtendedPdfViewerService {
constructor() {
this.recalculateSize$ = new Subject();
}
findMultiple(text, options = {}) {
options = {
...options,
findMultipleSearchTexts: true,
};
const searchString = text.join('\n') + '\n';
return this.find(searchString, options);
}
find(text, options = {}) {
if (!NgxExtendedPdfViewerComponent.ngxExtendedPdfViewerInitialized) {
// tslint:disable-next-line:quotemark
console.error("The PDF viewer hasn't finished initializing. Please call find() later.");
return false;
}
else {
const highlightAllCheckbox = document.getElementById('findHighlightAll');
if (highlightAllCheckbox) {
highlightAllCheckbox.checked = options.highlightAll || false;
}
const findPageRange = document.getElementById('findRange');
if (findPageRange) {
findPageRange.value = options.pageRange || '';
}
const findCurrentPageCheckbox = document.getElementById('findCurrentPage');
if (findCurrentPageCheckbox) {
findCurrentPageCheckbox.checked = options.currentPage || false;
}
const matchCaseCheckbox = document.getElementById('findMatchCase');
if (matchCaseCheckbox) {
matchCaseCheckbox.checked = options.matchCase || false;
}
const entireWordCheckbox = document.getElementById('findEntireWord');
if (entireWordCheckbox) {
entireWordCheckbox.checked = options.wholeWords || false;
}
const findIgnoreAccentsCheckbox = document.getElementById('findIgnoreAccents');
if (findIgnoreAccentsCheckbox) {
findIgnoreAccentsCheckbox.checked = options.ignoreAccents || false;
}
const multipleSearchTerms = options.findMultipleSearchTexts || text.includes('\n') || false;
const findMultipleSearchTextsCheckbox = document.getElementById('findMultipleSearchTexts');
if (findMultipleSearchTextsCheckbox) {
findMultipleSearchTextsCheckbox.checked = multipleSearchTerms;
}
const individualWordsModeCheckbox = document.getElementById('individualWordsMode');
if (individualWordsModeCheckbox) {
individualWordsModeCheckbox.checked = false;
}
const fuzzySearchCheckbox = document.getElementById('findFuzzy');
if (fuzzySearchCheckbox) {
fuzzySearchCheckbox.checked = options.fuzzySearch || false;
}
const inputField = multipleSearchTerms ? document.getElementById('findInputMultiline') : document.getElementById('findInput');
if (inputField) {
if (inputField instanceof HTMLTextAreaElement) {
inputField.value = text;
// todo dirty hack!
inputField.classList.remove('hidden');
document.getElementById('findInput')?.classList.add('hidden');
document.getElementById('individualWordsModeLabel')?.classList.remove('hidden');
document.getElementById('individualWordsMode')?.classList.remove('hidden');
// end of the dirty hack
}
else if (inputField instanceof HTMLInputElement) {
inputField.value = text;
// todo dirty hack!
inputField.classList.remove('hidden');
document.getElementById('findInputMultiline')?.classList.add('hidden');
document.getElementById('individualWordsModeLabel')?.classList.add('hidden');
document.getElementById('individualWordsMode')?.classList.add('hidden');
// end of the dirty hack
}
inputField.dispatchEvent(new Event('input'));
return true;
}
else {
// tslint:disable-next-line:quotemark
console.error("Unexpected error: the input field used to search isn't part of the DOM.");
return false;
}
}
}
findNext() {
if (!NgxExtendedPdfViewerComponent.ngxExtendedPdfViewerInitialized) {
// tslint:disable-next-line:quotemark
console.error("The PDF viewer hasn't finished initializing. Please call findNext() later.");
return false;
}
else {
const button = document.getElementById('findNext');
if (button) {
button.click();
return true;
}
return false;
}
}
findPrevious() {
if (!NgxExtendedPdfViewerComponent.ngxExtendedPdfViewerInitialized) {
// tslint:disable-next-line:quotemark
console.error("The PDF viewer hasn't finished initializing. Please call findPrevious() later.");
return false;
}
else {
const button = document.getElementById('findPrevious');
if (button) {
button.click();
return true;
}
return false;
}
}
print(printRange) {
const PDFViewerApplication = window.PDFViewerApplication;
const alreadyThere = !!window['isInPDFPrintRange'] && !printRange;
if (!alreadyThere) {
if (!printRange) {
printRange = {};
}
this.setPrintRange(printRange);
}
window.printPDF();
if (!alreadyThere) {
PDFViewerApplication.eventBus.on('afterprint', () => {
this.removePrintRange();
});
}
}
removePrintRange() {
window['isInPDFPrintRange'] = undefined;
window['filteredPageCount'] = undefined;
}
setPrintRange(printRange) {
const PDFViewerApplication = window.PDFViewerApplication;
window['isInPDFPrintRange'] = (page) => this.isInPDFPrintRange(page, printRange);
window['filteredPageCount'] = this.filteredPageCount(PDFViewerApplication.pagesCount, printRange);
}
filteredPageCount(pageCount, range) {
let result = 0;
for (let page = 1; 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) {
const e = printRange.excluded;
if (e.some((p) => p === page)) {
return false;
}
}
if (printRange.included) {
if (!printRange.included.some((p) => p === page)) {
return false;
}
}
return true;
}
async getPageAsLines(pageNumber) {
const PDFViewerApplication = window.PDFViewerApplication;
const pdfDocument = 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) {
const direction = countLTR > 0 ? (countRTL > 0 ? 'both' : 'ltr') : countRTL > 0 ? 'rtl' : undefined;
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;
}
async getPageAsText(pageNumber) {
const PDFViewerApplication = window.PDFViewerApplication;
const pdfDocument = 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('');
}
getPageAsImage(pageNumber, scale, background, backgroundColorToReplace = '#FFFFFF') {
const PDFViewerApplication = window.PDFViewerApplication;
const pdfDocument = PDFViewerApplication.pdfDocument;
const pagePromise = pdfDocument.getPage(pageNumber);
const imagePromise = (pdfPage) => Promise.resolve(this.draw(pdfPage, scale, background, backgroundColorToReplace));
return pagePromise.then(imagePromise);
}
draw(pdfPage, scale, background, backgroundColorToReplace = '#FFFFFF') {
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,
};
const renderTask = pdfPage.render(renderContext);
const dataUrlPromise = () => Promise.resolve(canvas.toDataURL());
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;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
return { ctx, canvas };
}
async getCurrentDocumentAsBlob() {
const PDFViewerApplication = window.PDFViewerApplication;
return await PDFViewerApplication.export();
}
async getFormData(currentFormValues = true) {
const PDFViewerApplication = window.PDFViewerApplication;
const pdf = 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 = PDFViewerApplication.pdfDocument.annotationStorage.getValue(a.id, a.fieldName + '/' + a.exportValue, '');
a.value = currentValue?.value;
}
else if (a.radioButton) {
const currentValue = PDFViewerApplication.pdfDocument.annotationStorage.getValue(a.id, a.fieldName + '/' + a.fieldValue, '');
a.value = currentValue?.value;
}
else {
const currentValue = 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
* or if it's out of range
*/
addPageToRenderQueue(pageIndex) {
const PDFViewerApplication = window.PDFViewerApplication;
return PDFViewerApplication.pdfViewer.addPageToRenderQueue(pageIndex);
}
isRenderQueueEmpty() {
const scrolledDown = true;
const renderExtra = false;
const PDFViewerApplication = window.PDFViewerApplication;
const nextPage = PDFViewerApplication.pdfViewer.renderingQueue.getHighestPriority(PDFViewerApplication.pdfViewer._getVisiblePages(), PDFViewerApplication.pdfViewer._pages, scrolledDown, renderExtra);
return !nextPage;
}
hasPageBeenRendered(pageIndex) {
const PDFViewerApplication = window.PDFViewerApplication;
const pages = PDFViewerApplication.pdfViewer._pages;
if (pages.length > pageIndex && pageIndex >= 0) {
const pageView = pages[pageIndex];
const isLoading = pageView.renderingState === 3;
return !isLoading;
}
return false;
}
currentlyRenderedPages() {
const PDFViewerApplication = window.PDFViewerApplication;
const pages = PDFViewerApplication.pdfViewer._pages;
return pages.filter((page) => page.renderingState === 3).map((page) => page.id);
}
numberOfPages() {
const PDFViewerApplication = window.PDFViewerApplication;
const pages = PDFViewerApplication.pdfViewer._pages;
return pages.length;
}
getCurrentlyVisiblePageNumbers() {
const app = window.PDFViewerApplication;
const pages = app.pdfViewer._getVisiblePages().views;
return pages?.map((page) => page.id);
}
recalculateSize() {
this.recalculateSize$.next();
}
async listLayers() {
const PDFViewerApplication = window.PDFViewerApplication;
const optionalContentConfig = await 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) {
const PDFViewerApplication = window.PDFViewerApplication;
const optionalContentConfig = await 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);
PDFViewerApplication.eventBus.dispatch('optionalcontentconfig', {
source: this,
promise: Promise.resolve(optionalContentConfig),
});
}
}
scrollPageIntoView(pageNumber, pageSpot) {
const PDFViewerApplication = window.PDFViewerApplication;
const viewer = PDFViewerApplication.pdfViewer;
viewer.scrollPagePosIntoView(pageNumber, pageSpot);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1leHRlbmRlZC1wZGYtdmlld2VyL3NyYy9saWIvbmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBNENwRixNQUFNLE9BQU8sMkJBQTJCO0lBQXhDO1FBQ1MscUJBQWdCLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQTJjaEQsQ0FBQztJQXpjUSxZQUFZLENBQUMsSUFBbUIsRUFBRSxVQUF1QixFQUFFO1FBQ2hFLE9BQU8sR0FBRztZQUNSLEdBQUcsT0FBTztZQUNWLHVCQUF1QixFQUFFLElBQUk7U0FDOUIsQ0FBQztRQUNGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzVDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVNLElBQUksQ0FBQyxJQUFZLEVBQUUsVUFBdUIsRUFBRTtRQUNqRCxJQUFJLENBQUMsNkJBQTZCLENBQUMsK0JBQStCLEVBQUU7WUFDbEUscUNBQXFDO1lBQ3JDLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztZQUN4RixPQUFPLEtBQUssQ0FBQztTQUNkO2FBQU07WUFDTCxNQUFNLG9CQUFvQixHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQXFCLENBQUM7WUFDN0YsSUFBSSxvQkFBb0IsRUFBRTtnQkFDeEIsb0JBQW9CLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFD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Q3RDLE1BQU0sb0JBQW9CLEdBQTJCLE1BQWMsQ0FBQyxvQkFBb0IsQ0FBQztRQUN6RixNQUFNLHFCQUFxQixHQUFHLE1BQU0sb0JBQW9CLENBQUMsU0FBUyxDQUFDLDRCQUE0QixDQUFDO1FBQ2hHLElBQUkscUJBQXFCLEVBQUU7WUFDekIsSUFBSSxTQUFTLEdBQUcscUJBQXFCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNoRSxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLGFBQWEsT0FBTyxJQUFJLENBQUMsQ0FBQztZQUNsRSxJQUFJLFFBQVEsRUFBRTtnQkFDWixTQUFTLEdBQUksUUFBNkIsQ0FBQyxPQUFPLENBQUM7Z0JBQ2xELFFBQTZCLENBQUMsT0FBTyxHQUFHLENBQUMsU0FBUyxDQUFDO2FBQ3JEO1lBQ0QscUJBQXFCLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3pELG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLEVBQUU7Z0JBQzlELE1BQU0sRUFBRSxJQUFJO2dCQUNaLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDO2FBQ2hELENBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQztJQUVNLGtCQUFrQixDQUFDLFVBQWtCLEVBQUUsUUFBNEQ7UUFDeEcsTUFBTSxvQkFBb0IsR0FBMkIsTUFBYyxDQUFDLG9CQUFvQixDQUFDO1FBQ3pGLE1BQU0sTUFBTSxHQUFHLG9CQUFvQixDQUFDLFNBQWdCLENBQUM7UUFDckQsTUFBTSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNyRCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOZ3hFeHRlbmRlZFBkZlZpZXdlckNvbXBvbmVudCB9IGZyb20gJy4vbmd4LWV4dGVuZGVkLXBkZi12aWV3ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFBkZkxheWVyIH0gZnJvbSAnLi9vcHRpb25zL29wdGlvbmFsX2NvbnRlbnRfY29uZmlnJztcbmltcG9ydCB7IFBERlByaW50UmFuZ2UgfSBmcm9tICcuL29wdGlvbnMvcGRmLXByaW50LXJhbmdlJztcbmltcG9ydCB7IElQREZWaWV3ZXJBcHBsaWNhdGlvbiwgUERGRG9jdW1lbnRQcm94eSwgVGV4dEl0ZW0sIFRleHRNYXJrZWRDb250ZW50IH0gZnJvbSAnLi9vcHRpb25zL3BkZi12aWV3ZXItYXBwbGljYXRpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZpbmRPcHRpb25zIHtcbiAgaGlnaGxpZ2h0QWxsPzogYm9vbGVhbjtcbiAgbWF0Y2hDYXNlPzogYm9vbGVhbjtcbiAgd2hvbGVXb3Jkcz86IGJvb2xlYW47XG4gIGlnbm9yZUFjY2VudHM/OiBib29sZWFuO1xuICBmaW5kTXVsdGlwbGVTZWFyY2hUZXh0cz86IGJvb2xlYW47XG4gIGZ1enp5U2VhcmNoPzogYm9vbGVhbjtcbiAgY3VycmVudFBhZ2U/OiBib29sZWFuOyAvLyBzZWFyY2ggb25seSBpbiB0aGUgY3VycmVudCBwYWdlXG4gIHBhZ2VSYW5nZT86IHN0cmluZzsgLy8gcGFnZSByYW5nZSBkZWZpbml0aW9uLCBlLmcuIFwiMlwiLCBcIjIsMyw0XCIsIFwiNS02XCIgb3IgXCIyLDUtNiw3XCJcbn1cblxuaW50ZXJmYWNlIERyYXdDb250ZXh0IHtcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUERGRXhwb3J0U2NhbGVGYWN0b3Ige1xuICB3aWR0aD86IG51bWJlcjtcbiAgaGVpZ2h0PzogbnVtYmVyO1xuICBzY2FsZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaW5lIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICBkaXJlY3Rpb246ICdsdHInIHwgJ3J0bCcgfCAnYm90aCcgfCB1bmRlZmluZWQ7XG4gIHRleHQ6IHN0cmluZztcbn1cbmV4cG9ydCBpbnRlcmZhY2UgU2VjdGlvbiB7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICB3aWR0aDogbnVtYmVyO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgZGlyZWN0aW9uOiAnbHRyJyB8ICdydGwnIHwgJ2JvdGgnIHwgdW5kZWZpbmVkO1xuICBsaW5lczogQXJyYXk8TGluZT47XG59XG5cbmV4cG9ydCBjbGFzcyBOZ3hFeHRlbmRlZFBkZlZpZXdlclNlcnZpY2Uge1xuICBwdWJsaWMgcmVjYWxjdWxhdGVTaXplJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcHVibGljIGZpbmRNdWx0aXBsZSh0ZXh0OiBBcnJheTxzdHJpbmc+LCBvcHRpb25zOiBGaW5kT3B0aW9ucyA9IHt9KTogYm9vbGVhbiB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBmaW5kTXVsdGlwbGVTZWFyY2hUZXh0czogdHJ1ZSxcbiAgICB9O1xuICAgIGNvbnN0IHNlYXJjaFN0cmluZyA9IHRleHQuam9pbignXFxuJykgKyAnXFxuJztcbiAgICByZXR1cm4gdGhpcy5maW5kKHNlYXJjaFN0cmluZywgb3B0aW9ucyk7XG4gIH1cblxuICBwdWJsaWMgZmluZCh0ZXh0OiBzdHJpbmcsIG9wdGlvbnM6IEZpbmRPcHRpb25zID0ge30pOiBib29sZWFuIHtcbiAgICBpZiAoIU5neEV4dGVuZGVkUGRmVmlld2VyQ29tcG9uZW50Lm5neEV4dGVuZGVkUGRmVmlld2VySW5pdGlhbGl6ZWQpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpxdW90ZW1hcmtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaGUgUERGIHZpZXdlciBoYXNuJ3QgZmluaXNoZWQgaW5pdGlhbGl6aW5nLiBQbGVhc2UgY2FsbCBmaW5kKCkgbGF0ZXIuXCIpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoaWdobGlnaHRBbGxDaGVja2JveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaW5kSGlnaGxpZ2h0QWxsJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgIGlmIChoaWdobGlnaHRBbGxDaGVja2JveCkge1xuICAgICAgICBoaWdobGlnaHRBbGxDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy5oaWdobGlnaHRBbGwgfHwgZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBmaW5kUGFnZVJhbmdlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRSYW5nZScpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICBpZiAoZmluZFBhZ2VSYW5nZSkge1xuICAgICAgICBmaW5kUGFnZVJhbmdlLnZhbHVlID0gb3B0aW9ucy5wYWdlUmFuZ2UgfHwgJyc7XG4gICAgICB9XG4gICAgICBjb25zdCBmaW5kQ3VycmVudFBhZ2VDaGVja2JveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaW5kQ3VycmVudFBhZ2UnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgaWYgKGZpbmRDdXJyZW50UGFnZUNoZWNrYm94KSB7XG4gICAgICAgIGZpbmRDdXJyZW50UGFnZUNoZWNrYm94LmNoZWNrZWQgPSBvcHRpb25zLmN1cnJlbnRQYWdlIHx8IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtYXRjaENhc2VDaGVja2JveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaW5kTWF0Y2hDYXNlJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgIGlmIChtYXRjaENhc2VDaGVja2JveCkge1xuICAgICAgICBtYXRjaENhc2VDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy5tYXRjaENhc2UgfHwgZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBlbnRpcmVXb3JkQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZEVudGlyZVdvcmQnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgaWYgKGVudGlyZVdvcmRDaGVja2JveCkge1xuICAgICAgICBlbnRpcmVXb3JkQ2hlY2tib3guY2hlY2tlZCA9IG9wdGlvbnMud2hvbGVXb3JkcyB8fCBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbmRJZ25vcmVBY2NlbnRzQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElnbm9yZUFjY2VudHMnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgaWYgKGZpbmRJZ25vcmVBY2NlbnRzQ2hlY2tib3gpIHtcbiAgICAgICAgZmluZElnbm9yZUFjY2VudHNDaGVja2JveC5jaGVja2VkID0gb3B0aW9ucy5pZ25vcmVBY2NlbnRzIHx8IGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgbXVsdGlwbGVTZWFyY2hUZXJtcyA9IG9wdGlvbnMuZmluZE11bHRpcGxlU2VhcmNoVGV4dHMgfHwgdGV4dC5pbmNsdWRlcygnXFxuJykgfHwgZmFsc2U7XG4gICAgICBjb25zdCBmaW5kTXVsdGlwbGVTZWFyY2hUZXh0c0NoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRNdWx0aXBsZVNlYXJjaFRleHRzJykgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgIGlmIChmaW5kTXVsdGlwbGVTZWFyY2hUZXh0c0NoZWNrYm94KSB7XG4gICAgICAgIGZpbmRNdWx0aXBsZVNlYXJjaFRleHRzQ2hlY2tib3guY2hlY2tlZCA9IG11bHRpcGxlU2VhcmNoVGVybXM7XG4gICAgICB9XG4gICAgICBjb25zdCBpbmRpdmlkdWFsV29yZHNNb2RlQ2hlY2tib3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW5kaXZpZHVhbFdvcmRzTW9kZScpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICBpZiAoaW5kaXZpZHVhbFdvcmRzTW9kZUNoZWNrYm94KSB7XG4gICAgICAgIGluZGl2aWR1YWxXb3Jkc01vZGVDaGVja2JveC5jaGVja2VkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBmdXp6eVNlYXJjaENoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRGdXp6eScpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICBpZiAoZnV6enlTZWFyY2hDaGVja2JveCkge1xuICAgICAgICBmdXp6eVNlYXJjaENoZWNrYm94LmNoZWNrZWQgPSBvcHRpb25zLmZ1enp5U2VhcmNoIHx8IGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5wdXRGaWVsZCA9IG11bHRpcGxlU2VhcmNoVGVybXMgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0TXVsdGlsaW5lJykgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0Jyk7XG4gICAgICBpZiAoaW5wdXRGaWVsZCkge1xuICAgICAgICBpZiAoaW5wdXRGaWVsZCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQpIHtcbiAgICAgICAgICBpbnB1dEZpZWxkLnZhbHVlID0gdGV4dDtcblxuICAgICAgICAgIC8vIHRvZG8gZGlydHkgaGFjayFcbiAgICAgICAgICBpbnB1dEZpZWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0JykgYXMgSFRNTElucHV0RWxlbWVudCk/LmNsYXNzTGlzdC5hZGQoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW5kaXZpZHVhbFdvcmRzTW9kZUxhYmVsJykgYXMgSFRNTElucHV0RWxlbWVudCk/LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW5kaXZpZHVhbFdvcmRzTW9kZScpIGFzIEhUTUxJbnB1dEVsZW1lbnQpPy5jbGFzc0xpc3QucmVtb3ZlKCdoaWRkZW4nKTtcbiAgICAgICAgICAvLyBlbmQgb2YgdGhlIGRpcnR5IGhhY2tcbiAgICAgICAgfSBlbHNlIGlmIChpbnB1dEZpZWxkIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xuICAgICAgICAgIGlucHV0RmllbGQudmFsdWUgPSB0ZXh0O1xuICAgICAgICAgIC8vIHRvZG8gZGlydHkgaGFjayFcbiAgICAgICAgICBpbnB1dEZpZWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmluZElucHV0TXVsdGlsaW5lJykgYXMgSFRNTElucHV0RWxlbWVudCk/LmNsYXNzTGlzdC5hZGQoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW5kaXZpZHVhbFdvcmRzTW9kZUxhYmVsJykgYXMgSFRNTElucHV0RWxlbWVudCk/LmNsYXNzTGlzdC5hZGQoJ2hpZGRlbicpO1xuICAgICAgICAgIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW5kaXZpZHVhbFdvcmRzTW9kZScpIGFzIEhUTUxJbnB1dEVsZW1lbnQpPy5jbGFzc0xpc3QuYWRkKCdoaWRkZW4nKTtcbiAgICAgICAgICAvLyBlbmQgb2YgdGhlIGRpcnR5IGhhY2tcbiAgICAgICAgfVxuICAgICAgICBpbnB1dEZpZWxkLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdpbnB1dCcpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6cXVvdGVtYXJrXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJVbmV4cGVjdGVkIGVycm9yOiB0aGUgaW5wdXQgZmllbGQgdXNlZCB0byBzZWFyY2ggaXNuJ3QgcGFydCBvZiB0aGUgRE9NLlwiKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBmaW5kTmV4dCgpOiBib29sZWFuIHtcbiAgICBpZiAoIU5neEV4dGVuZGVkUGRmVmlld2VyQ29tcG9uZW50Lm5neEV4dGVuZGVkUGRmVmlld2VySW5pdGlhbGl6ZWQpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpxdW90ZW1hcmtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJUaGUgUERGIHZpZXdlciBoYXNuJ3QgZmluaXNoZWQgaW5pdGlhbGl6aW5nLiBQbGVhc2UgY2FsbCBmaW5kTmV4dCgpIGxhdGVyLlwiKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmROZXh0Jyk7XG4gICAgICBpZiAoYnV0dG9uKSB7XG4gICAgICAgIGJ1dHRvbi5jbGljaygpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZmluZFByZXZpb3VzKCk6IGJvb2xlYW4ge1xuICAgIGlmICghTmd4RXh0ZW5kZWRQZGZWaWV3ZXJDb21wb25lbnQubmd4RXh0ZW5kZWRQZGZWaWV3ZXJJbml0aWFsaXplZCkge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnF1b3RlbWFya1xuICAgICAgY29uc29sZS5lcnJvcihcIlRoZSBQREYgdmlld2VyIGhhc24ndCBmaW5pc2hlZCBpbml0aWFsaXppbmcuIFBsZWFzZSBjYWxsIGZpbmRQcmV2aW91cygpIGxhdGVyLlwiKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbmRQcmV2aW91cycpO1xuICAgICAgaWYgKGJ1dHRvbikge1xuICAgICAgICBidXR0b24uY2xpY2soKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHByaW50KHByaW50UmFuZ2U/OiBQREZQcmludFJhbmdlKSB7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBjb25zdCBhbHJlYWR5VGhlcmUgPSAhIXdpbmRvd1snaXNJblBERlByaW50UmFuZ2UnXSAmJiAhcHJpbnRSYW5nZTtcbiAgICBpZiAoIWFscmVhZHlUaGVyZSkge1xuICAgICAgaWYgKCFwcmludFJhbmdlKSB7XG4gICAgICAgIHByaW50UmFuZ2UgPSB7fSBhcyBQREZQcmludFJhbmdlO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRQcmludFJhbmdlKHByaW50UmFuZ2UpO1xuICAgIH1cbiAgICAod2luZG93IGFzIGFueSkucHJpbnRQREYoKTtcbiAgICBpZiAoIWFscmVhZHlUaGVyZSkge1xuICAgICAgUERGVmlld2VyQXBwbGljYXRpb24uZXZlbnRCdXMub24oJ2FmdGVycHJpbnQnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMucmVtb3ZlUHJpbnRSYW5nZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlbW92ZVByaW50UmFuZ2UoKSB7XG4gICAgd2luZG93Wydpc0luUERGUHJpbnRSYW5nZSddID0gdW5kZWZpbmVkO1xuICAgIHdpbmRvd1snZmlsdGVyZWRQYWdlQ291bnQnXSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRQcmludFJhbmdlKHByaW50UmFuZ2U6IFBERlByaW50UmFuZ2UpIHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIHdpbmRvd1snaXNJblBERlByaW50UmFuZ2UnXSA9IChwYWdlOiBudW1iZXIpID0+IHRoaXMuaXNJblBERlByaW50UmFuZ2UocGFnZSwgcHJpbnRSYW5nZSBhcyBQREZQcmludFJhbmdlKTtcbiAgICB3aW5kb3dbJ2ZpbHRlcmVkUGFnZUNvdW50J10gPSB0aGlzLmZpbHRlcmVkUGFnZUNvdW50KFBERlZpZXdlckFwcGxpY2F0aW9uLnBhZ2VzQ291bnQsIHByaW50UmFuZ2UpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlcmVkUGFnZUNvdW50KHBhZ2VDb3VudDogbnVtYmVyLCByYW5nZTogUERGUHJpbnRSYW5nZSk6IG51bWJlciB7XG4gICAgbGV0IHJlc3VsdCA9IDA7XG4gICAgZm9yIChsZXQgcGFnZSA9IDE7IHBhZ2UgPD0gcGFnZUNvdW50OyBwYWdlKyspIHtcbiAgICAgIGlmICh0aGlzLmlzSW5QREZQcmludFJhbmdlKHBhZ2UsIHJhbmdlKSkge1xuICAgICAgICByZXN1bHQrKztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBpc0luUERGUHJpbnRSYW5nZShwYWdlSW5kZXg6IG51bWJlciwgcHJpbnRSYW5nZTogUERGUHJpbnRSYW5nZSkge1xuICAgIGNvbnN0IHBhZ2UgPSBwYWdlSW5kZXggKyAxO1xuICAgIGlmIChwcmludFJhbmdlLmZyb20pIHtcbiAgICAgIGlmIChwYWdlIDwgcHJpbnRSYW5nZS5mcm9tKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHByaW50UmFuZ2UudG8pIHtcbiAgICAgIGlmIChwYWdlID4gcHJpbnRSYW5nZS50bykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcmludFJhbmdlLmV4Y2x1ZGVkKSB7XG4gICAgICBjb25zdCBlID0gcHJpbnRSYW5nZS5leGNsdWRlZCBhcyBBcnJheTxudW1iZXI+O1xuICAgICAgaWYgKGUuc29tZSgocCkgPT4gcCA9PT0gcGFnZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocHJpbnRSYW5nZS5pbmNsdWRlZCkge1xuICAgICAgaWYgKCFwcmludFJhbmdlLmluY2x1ZGVkLnNvbWUoKHApID0+IHAgPT09IHBhZ2UpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0UGFnZUFzTGluZXMocGFnZU51bWJlcjogbnVtYmVyKTogUHJvbWlzZTxBcnJheTxMaW5lPj4ge1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBJUERGVmlld2VyQXBwbGljYXRpb24gPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG4gICAgY29uc3QgcGRmRG9jdW1lbnQgPSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZEb2N1bWVudDtcblxuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBwZGZEb2N1bWVudC5nZXRQYWdlKHBhZ2VOdW1iZXIpO1xuICAgIGNvbnN0IHRleHRTbmlwcGV0cyA9IChhd2FpdCBwYWdlLmdldFRleHRDb250ZW50KCkpLml0ZW1zIC8vXG4gICAgICAuZmlsdGVyKChpbmZvKSA9PiAhaW5mb1sndHlwZSddKTsgLy8gaWdub3JlIHRoZSBUZXh0TWFya2VkQ29udGVudCBpdGVtc1xuXG4gICAgY29uc3Qgc25pcHBldHMgPSB0ZXh0U25pcHBldHMgYXMgQXJyYXk8VGV4dEl0ZW0+O1xuXG4gICAgbGV0IG1pblggPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICBsZXQgbWluWSA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgIGxldCBtYXhYID0gTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVI7XG4gICAgbGV0IG1heFkgPSBOdW1iZXIuTUlOX1NBRkVfSU5URUdFUjtcbiAgICBsZXQgY291bnRMVFIgPSAwO1xuICAgIGxldCBjb3VudFJUTCA9IDA7XG4gICAgbGV0IHRleHQgPSAnJztcbiAgICBsZXQgbGluZXMgPSBuZXcgQXJyYXk8TGluZT4oKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNuaXBwZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjdXJyZW50U25pcHBldCA9IHNuaXBwZXRzW2ldO1xuICAgICAgaWYgKCFjdXJyZW50U25pcHBldC5oYXNFT0wpIHtcbiAgICAgICAgY29uc3QgeCA9IGN1cnJlbnRTbmlwcGV0LnRyYW5zZm9ybVs0XTtcbiAgICAgICAgY29uc3QgeSA9IC1jdXJyZW50U25pcHBldC50cmFuc2Zvcm1bNV07XG4gICAgICAgIGNvbnN0IHdpZHRoID0gY3VycmVudFNuaXBwZXQud2lkdGg7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IGN1cnJlbnRTbmlwcGV0LmhlaWdodDtcbiAgICAgICAgbWluWCA9IE1hdGgubWluKG1pblgsIHgpO1xuICAgICAgICBtaW5ZID0gTWF0aC5taW4obWluWSwgeSk7XG4gICAgICAgIG1heFggPSBNYXRoLm1heChtYXhYLCB4ICsgd2lkdGgpO1xuICAgICAgICBtYXhZID0gTWF0aC5tYXgobWF4WSwgeSArIGhlaWdodCk7XG4gICAgICAgIHRleHQgKz0gY3VycmVudFNuaXBwZXQuc3RyO1xuICAgICAgICBpZiAoY3VycmVudFNuaXBwZXQuZGlyID09PSAncnRsJykge1xuICAgICAgICAgIGNvdW50UlRMKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN1cnJlbnRTbmlwcGV0LmRpciA9PT0gJ2x0cicpIHtcbiAgICAgICAgICBjb3VudExUUisrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxldCBhZGRJdCA9IGkgPT09IHNuaXBwZXRzLmxlbmd0aCAtIDEgfHwgY3VycmVudFNuaXBwZXQuaGFzRU9MO1xuICAgICAgaWYgKGFkZEl0KSB7XG4gICAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IGNvdW50TFRSID4gMCA/IChjb3VudFJUTCA+IDAgPyAnYm90aCcgOiAnbHRyJykgOiBjb3VudFJUTCA+IDAgPyAncnRsJyA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgbGluZSA9IHtcbiAgICAgICAgICBkaXJlY3Rpb24sXG4gICAgICAgICAgeDogbWluWCxcbiAgICAgICAgICB5OiBtaW5ZLFxuICAgICAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZLFxuICAgICAgICAgIHRleHQ6IHRleHQudHJpbSgpLFxuICAgICAgICB9IGFzIExpbmU7XG4gICAgICAgIGxpbmVzLnB1c2gobGluZSk7XG4gICAgICAgIG1pblggPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICAgICAgbWluWSA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgICAgICBtYXhYID0gTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVI7XG4gICAgICAgIG1heFkgPSBOdW1iZXIuTUlOX1NBRkVfSU5URUdFUjtcbiAgICAgICAgY291bnRMVFIgPSAwO1xuICAgICAgICBjb3VudFJUTCA9IDA7XG4gICAgICAgIHRleHQgPSAnJztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpbmVzO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldFBhZ2VBc1RleHQocGFnZU51bWJlcjogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBkZkRvY3VtZW50ID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmRG9jdW1lbnQ7XG5cbiAgICBjb25zdCBwYWdlID0gYXdhaXQgcGRmRG9jdW1lbnQuZ2V0UGFnZShwYWdlTnVtYmVyKTtcbiAgICBjb25zdCB0ZXh0U25pcHBldHMgPSAoYXdhaXQgcGFnZS5nZXRUZXh0Q29udGVudCgpKS5pdGVtcztcbiAgICByZXR1cm4gdGhpcy5jb252ZXJ0VGV4dEluZm9Ub1RleHQodGV4dFNuaXBwZXRzKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydFRleHRJbmZvVG9UZXh0KHRleHRJbmZvSXRlbXM6IEFycmF5PFRleHRJdGVtIHwgVGV4dE1hcmtlZENvbnRlbnQ+KTogc3RyaW5nIHtcbiAgICBpZiAoIXRleHRJbmZvSXRlbXMpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIHRleHRJbmZvSXRlbXNcbiAgICAgIC5maWx0ZXIoKGluZm8pID0+ICFpbmZvWyd0eXBlJ10pXG4gICAgICAubWFwKChpbmZvOiBUZXh0SXRlbSkgPT4gKGluZm8uaGFzRU9MID8gaW5mby5zdHIgKyAnXFxuJyA6IGluZm8uc3RyKSlcbiAgICAgIC5qb2luKCcnKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRQYWdlQXNJbWFnZShwYWdlTnVtYmVyOiBudW1iZXIsIHNjYWxlOiBQREZFeHBvcnRTY2FsZUZhY3RvciwgYmFja2dyb3VuZD86IHN0cmluZywgYmFja2dyb3VuZENvbG9yVG9SZXBsYWNlOiBzdHJpbmcgPSAnI0ZGRkZGRicpOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBJUERGVmlld2VyQXBwbGljYXRpb24gPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG4gICAgY29uc3QgcGRmRG9jdW1lbnQgPSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZEb2N1bWVudDtcbiAgICBjb25zdCBwYWdlUHJvbWlzZTogUHJvbWlzZTxhbnk+ID0gcGRmRG9jdW1lbnQuZ2V0UGFnZShwYWdlTnVtYmVyKTtcbiAgICBjb25zdCBpbWFnZVByb21pc2UgPSAocGRmUGFnZSkgPT4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuZHJhdyhwZGZQYWdlLCBzY2FsZSwgYmFja2dyb3VuZCwgYmFja2dyb3VuZENvbG9yVG9SZXBsYWNlKSk7XG5cbiAgICByZXR1cm4gcGFnZVByb21pc2UudGhlbihpbWFnZVByb21pc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBkcmF3KHBkZlBhZ2U6IGFueSwgc2NhbGU6IFBERkV4cG9ydFNjYWxlRmFjdG9yLCBiYWNrZ3JvdW5kPzogc3RyaW5nLCBiYWNrZ3JvdW5kQ29sb3JUb1JlcGxhY2U6IHN0cmluZyA9ICcjRkZGRkZGJyk6IFByb21pc2U8SFRNTENhbnZhc0VsZW1lbnQ+IHtcbiAgICBsZXQgem9vbUZhY3RvciA9IDE7XG4gICAgaWYgKHNjYWxlLnNjYWxlKSB7XG4gICAgICB6b29tRmFjdG9yID0gc2NhbGUuc2NhbGU7XG4gICAgfSBlbHNlIGlmIChzY2FsZS53aWR0aCkge1xuICAgICAgem9vbUZhY3RvciA9IHNjYWxlLndpZHRoIC8gcGRmUGFnZS5nZXRWaWV3cG9ydCh7IHNjYWxlOiAxIH0pLndpZHRoO1xuICAgIH0gZWxzZSBpZiAoc2NhbGUuaGVpZ2h0KSB7XG4gICAgICB6b29tRmFjdG9yID0gc2NhbGUuaGVpZ2h0IC8gcGRmUGFnZS5nZXRWaWV3cG9ydCh7IHNjYWxlOiAxIH0pLmhlaWdodDtcbiAgICB9XG4gICAgY29uc3Qgdmlld3BvcnQgPSBwZGZQYWdlLmdldFZpZXdwb3J0KHtcbiAgICAgIHNjYWxlOiB6b29tRmFjdG9yLFxuICAgIH0pO1xuICAgIGNvbnN0IHsgY3R4LCBjYW52YXMgfSA9IHRoaXMuZ2V0UGFnZURyYXdDb250ZXh0KHZpZXdwb3J0LndpZHRoLCB2aWV3cG9ydC5oZWlnaHQpO1xuICAgIGNvbnN0IGRyYXdWaWV3cG9ydCA9IHZpZXdwb3J0LmNsb25lKCk7XG5cbiAgICBjb25zdCByZW5kZXJDb250ZXh0ID0ge1xuICAgICAgY2FudmFzQ29udGV4dDogY3R4LFxuICAgICAgdmlld3BvcnQ6IGRyYXdWaWV3cG9ydCxcbiAgICAgIGJhY2tncm91bmQsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3JUb1JlcGxhY2UsXG4gICAgfTtcbiAgICBjb25zdCByZW5kZXJUYXNrID0gcGRmUGFnZS5yZW5kZXIocmVuZGVyQ29udGV4dCk7XG5cbiAgICBjb25zdCBkYXRhVXJsUHJvbWlzZSA9ICgpID0+IFByb21pc2UucmVzb2x2ZShjYW52YXMudG9EYXRhVVJMKCkpO1xuXG4gICAgcmV0dXJuIHJlbmRlclRhc2sucHJvbWlzZS50aGVuKGRhdGFVcmxQcm9taXNlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UGFnZURyYXdDb250ZXh0KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogRHJhd0NvbnRleHQge1xuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHsgYWxwaGE6IHRydWUgfSk7XG4gICAgaWYgKCFjdHgpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogcXVvdGVtYXJrXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBjcmVhdGUgdGhlIDJkIGNvbnRleHRcIik7XG4gICAgfVxuXG4gICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICBjYW52YXMuc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGA7XG4gICAgY2FudmFzLnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG5cbiAgICByZXR1cm4geyBjdHgsIGNhbnZhcyB9O1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldEN1cnJlbnREb2N1bWVudEFzQmxvYigpOiBQcm9taXNlPEJsb2I+IHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIHJldHVybiBhd2FpdCBQREZWaWV3ZXJBcHBsaWNhdGlvbi5leHBvcnQoKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRGb3JtRGF0YShjdXJyZW50Rm9ybVZhbHVlcyA9IHRydWUpOiBQcm9taXNlPEFycmF5PE9iamVjdD4+IHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBkZjogUERGRG9jdW1lbnRQcm94eSB8IHVuZGVmaW5lZCA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZkRvY3VtZW50O1xuICAgIC8vIHNjcmVlbiBEUEkgLyBQREYgRFBJXG4gICAgY29uc3QgZHBpUmF0aW8gPSA5NiAvIDcyO1xuICAgIGNvbnN0IHJlc3VsdDogQXJyYXk8T2JqZWN0PiA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IHBkZj8ubnVtUGFnZXM7IGkrKykge1xuICAgICAgLy8gdHJhY2sgdGhlIGN1cnJlbnQgcGFnZVxuICAgICAgY29uc3QgY3VycmVudFBhZ2UgLyogOiBQREZQYWdlUHJveHkgKi8gPSBhd2FpdCBwZGYuZ2V0UGFnZShpKTtcbiAgICAgIGNvbnN0IGFubm90YXRpb25zID0gYXdhaXQgY3VycmVudFBhZ2UuZ2V0QW5ub3RhdGlvbnMoKTtcblxuICAgICAgYW5ub3RhdGlvbnNcbiAgICAgICAgLmZpbHRlcigoYSkgPT4gYS5zdWJ0eXBlID09PSAnV2lkZ2V0JykgLy8gZ2V0IHRoZSBmb3JtIGZpZWxkIGFubm90YXRpb25zIG9ubHlcbiAgICAgICAgLm1hcCgoYSkgPT4gKHsgLi4uYSB9KSkgLy8gb25seSBleHBvc2UgY29waWVzIG9mIHRoZSBhbm5vdGF0aW9ucyB0byBhdm9pZCBzaWRlLWVmZmVjdHNcbiAgICAgICAgLmZvckVhY2goKGEpID0+IHtcbiAgICAgICAgICAvLyBnZXQgdGhlIHJlY3RhbmdsZSB0aGF0IHJlcHJlc2VudCB0aGUgc2luZ2xlIGZpZWxkXG4gICAgICAgICAgLy8gYW5kIHJlc2l6ZSBpdCBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgRFBJXG4gICAgICAgICAgY29uc3QgZmllbGRSZWN0OiBBcnJheTxudW1iZXI+ID0gY3VycmVudFBhZ2UuZ2V0Vmlld3BvcnQoeyBzY2FsZTogZHBpUmF0aW8gfSkuY29udmVydFRvVmlld3BvcnRSZWN0YW5nbGUoYS5yZWN0KTtcblxuICAgICAgICAgIC8vIGFkZCB0aGUgY29ycmVzcG9uZGluZyBpbnB1dFxuICAgICAgICAgIGlmIChjdXJyZW50Rm9ybVZhbHVlcyAmJiBhLmZpZWxkTmFtZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKGEuZXhwb3J0VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWU6IGFueSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZkRvY3VtZW50LmFubm90YXRpb25TdG9yYWdlLmdldFZhbHVlKGEuaWQsIGEuZmllbGROYW1lICsgJy8nICsgYS5leHBvcnRWYWx1ZSwgJycpO1xuICAgICAgICAgICAgICAgIGEudmFsdWUgPSBjdXJyZW50VmFsdWU/LnZhbHVlO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGEucmFkaW9CdXR0b24pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWU6IGFueSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZkRvY3VtZW50LmFubm90YXRpb25TdG9yYWdlLmdldFZhbHVlKGEuaWQsIGEuZmllbGROYW1lICsgJy8nICsgYS5maWVsZFZhbHVlLCAnJyk7XG4gICAgICAgICAgICAgICAgYS52YWx1ZSA9IGN1cnJlbnRWYWx1ZT8udmFsdWU7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFZhbHVlOiBhbnkgPSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZEb2N1bWVudC5hbm5vdGF0aW9uU3RvcmFnZS5nZXRWYWx1ZShhLmlkLCBhLmZpZWxkTmFtZSwgJycpO1xuICAgICAgICAgICAgICAgIGEudmFsdWUgPSBjdXJyZW50VmFsdWU/LnZhbHVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgLy8ganVzdCBpZ25vcmUgaXRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2goeyBmaWVsZEFubm90YXRpb246IGEsIGZpZWxkUmVjdCwgcGFnZU51bWJlcjogaSB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBhZ2UgdG8gdGhlIHJlbmRlcmluZyBxdWV1ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZUluZGV4IEluZGV4IG9mIHRoZSBwYWdlIHRvIHJlbmRlclxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gZmFsc2UsIGlmIHRoZSBwYWdlIGhhcyBhbHJlYWR5IGJlZW4gcmVuZGVyZWRcbiAgICogb3IgaWYgaXQncyBvdXQgb2YgcmFuZ2VcbiAgICovXG4gIHB1YmxpYyBhZGRQYWdlVG9SZW5kZXJRdWV1ZShwYWdlSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBJUERGVmlld2VyQXBwbGljYXRpb24gPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG4gICAgcmV0dXJuIFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5hZGRQYWdlVG9SZW5kZXJRdWV1ZShwYWdlSW5kZXgpO1xuICB9XG5cbiAgcHVibGljIGlzUmVuZGVyUXVldWVFbXB0eSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBzY3JvbGxlZERvd24gPSB0cnVlO1xuICAgIGNvbnN0IHJlbmRlckV4dHJhID0gZmFsc2U7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBjb25zdCBuZXh0UGFnZSA9IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5yZW5kZXJpbmdRdWV1ZS5nZXRIaWdoZXN0UHJpb3JpdHkoXG4gICAgICBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIuX2dldFZpc2libGVQYWdlcygpLFxuICAgICAgUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLl9wYWdlcyxcbiAgICAgIHNjcm9sbGVkRG93bixcbiAgICAgIHJlbmRlckV4dHJhXG4gICAgKTtcbiAgICByZXR1cm4gIW5leHRQYWdlO1xuICB9XG5cbiAgcHVibGljIGhhc1BhZ2VCZWVuUmVuZGVyZWQocGFnZUluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBhZ2VzID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLl9wYWdlcztcbiAgICBpZiAocGFnZXMubGVuZ3RoID4gcGFnZUluZGV4ICYmIHBhZ2VJbmRleCA+PSAwKSB7XG4gICAgICBjb25zdCBwYWdlVmlldyA9IHBhZ2VzW3BhZ2VJbmRleF07XG4gICAgICBjb25zdCBpc0xvYWRpbmcgPSBwYWdlVmlldy5yZW5kZXJpbmdTdGF0ZSA9PT0gMztcbiAgICAgIHJldHVybiAhaXNMb2FkaW5nO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgY3VycmVudGx5UmVuZGVyZWRQYWdlcygpOiBBcnJheTxudW1iZXI+IHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBhZ2VzID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLl9wYWdlcztcbiAgICByZXR1cm4gcGFnZXMuZmlsdGVyKChwYWdlKSA9PiBwYWdlLnJlbmRlcmluZ1N0YXRlID09PSAzKS5tYXAoKHBhZ2UpID0+IHBhZ2UuaWQpO1xuICB9XG5cbiAgcHVibGljIG51bWJlck9mUGFnZXMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBhZ2VzID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLl9wYWdlcztcbiAgICByZXR1cm4gcGFnZXMubGVuZ3RoO1xuICB9XG5cbiAgcHVibGljIGdldEN1cnJlbnRseVZpc2libGVQYWdlTnVtYmVycygpOiBBcnJheTxudW1iZXI+IHtcbiAgICBjb25zdCBhcHAgPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb24gYXMgSVBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IHBhZ2VzID0gKGFwcC5wZGZWaWV3ZXIuX2dldFZpc2libGVQYWdlcygpIGFzIGFueSkudmlld3MgYXMgQXJyYXk8YW55PjtcbiAgICByZXR1cm4gcGFnZXM/Lm1hcCgocGFnZSkgPT4gcGFnZS5pZCk7XG4gIH1cblxuICBwdWJsaWMgcmVjYWxjdWxhdGVTaXplKCk6IHZvaWQge1xuICAgIHRoaXMucmVjYWxjdWxhdGVTaXplJC5uZXh0KCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdExheWVycygpOiBQcm9taXNlPEFycmF5PFBkZkxheWVyPiB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBJUERGVmlld2VyQXBwbGljYXRpb24gPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG5cbiAgICBjb25zdCBvcHRpb25hbENvbnRlbnRDb25maWcgPSBhd2FpdCBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIub3B0aW9uYWxDb250ZW50Q29uZmlnUHJvbWlzZTtcbiAgICBpZiAob3B0aW9uYWxDb250ZW50Q29uZmlnKSB7XG4gICAgICBjb25zdCBsZXZlbERhdGEgPSBvcHRpb25hbENvbnRlbnRDb25maWcuZ2V0T3JkZXIoKTtcbiAgICAgIGNvbnN0IGxheWVySWRzID0gbGV2ZWxEYXRhLmZpbHRlcigoZ3JvdXBJZCkgPT4gdHlwZW9mIGdyb3VwSWQgIT09ICdvYmplY3QnKTtcbiAgICAgIHJldHVybiBsYXllcklkcy5tYXAoKGxheWVySWQpID0+IHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gb3B0aW9uYWxDb250ZW50Q29uZmlnLmdldEdyb3VwKGxheWVySWQpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxheWVySWQ6IGxheWVySWQsXG4gICAgICAgICAgbmFtZTogY29uZmlnLm5hbWUsXG4gICAgICAgICAgdmlzaWJsZTogY29uZmlnLnZpc2libGUsXG4gICAgICAgIH0gYXMgUGRmTGF5ZXI7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyB0b2dnbGVMYXllcihsYXllcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBQREZWaWV3ZXJBcHBsaWNhdGlvbjogSVBERlZpZXdlckFwcGxpY2F0aW9uID0gKHdpbmRvdyBhcyBhbnkpLlBERlZpZXdlckFwcGxpY2F0aW9uO1xuICAgIGNvbnN0IG9wdGlvbmFsQ29udGVudENvbmZpZyA9IGF3YWl0IFBERlZpZXdlckFwcGxpY2F0aW9uLnBkZlZpZXdlci5vcHRpb25hbENvbnRlbnRDb25maWdQcm9taXNlO1xuICAgIGlmIChvcHRpb25hbENvbnRlbnRDb25maWcpIHtcbiAgICAgIGxldCBpc1Zpc2libGUgPSBvcHRpb25hbENvbnRlbnRDb25maWcuZ2V0R3JvdXAobGF5ZXJJZCkudmlzaWJsZTtcbiAgICAgIGNvbnN0IGNoZWNrYm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgaW5wdXRbaWQ9JyR7bGF5ZXJJZH0nXWApO1xuICAgICAgaWYgKGNoZWNrYm94KSB7XG4gICAgICAgIGlzVmlzaWJsZSA9IChjaGVja2JveCBhcyBIVE1MSW5wdXRFbGVtZW50KS5jaGVja2VkO1xuICAgICAgICAoY2hlY2tib3ggYXMgSFRNTElucHV0RWxlbWVudCkuY2hlY2tlZCA9ICFpc1Zpc2libGU7XG4gICAgICB9XG4gICAgICBvcHRpb25hbENvbnRlbnRDb25maWcuc2V0VmlzaWJpbGl0eShsYXllcklkLCAhaXNWaXNpYmxlKTtcbiAgICAgIFBERlZpZXdlckFwcGxpY2F0aW9uLmV2ZW50QnVzLmRpc3BhdGNoKCdvcHRpb25hbGNvbnRlbnRjb25maWcnLCB7XG4gICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgcHJvbWlzZTogUHJvbWlzZS5yZXNvbHZlKG9wdGlvbmFsQ29udGVudENvbmZpZyksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2Nyb2xsUGFnZUludG9WaWV3KHBhZ2VOdW1iZXI6IG51bWJlciwgcGFnZVNwb3Q/OiB7IHRvcD86IG51bWJlciB8IHN0cmluZzsgbGVmdD86IG51bWJlciB8IHN0cmluZyB9KTogdm9pZCB7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBjb25zdCB2aWV3ZXIgPSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wZGZWaWV3ZXIgYXMgYW55O1xuICAgIHZpZXdlci5zY3JvbGxQYWdlUG9zSW50b1ZpZXcocGFnZU51bWJlciwgcGFnZVNwb3QpO1xuICB9XG59XG4iXX0=