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.
292 lines • 35.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/secondary-toolbar/pdf-secondary-toolbar/pdf-secondary-toolbar.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter, TemplateRef, ElementRef, HostListener, NgZone, } from '@angular/core';
import { PDFNotificationService } from './../../pdf-notification-service';
export class PdfSecondaryToolbarComponent {
/**
* @param {?} element
* @param {?} notificationService
* @param {?} ngZone
*/
constructor(element, notificationService, ngZone) {
this.element = element;
this.notificationService = notificationService;
this.ngZone = ngZone;
this.showPresentationModeButton = true;
this.showOpenFileButton = true;
this.showPrintButton = true;
this.showDownloadButton = true;
this.showBookmarkButton = true;
this.showPagingButtons = true;
this.showRotateButton = true;
this.showHandToolButton = true;
this.showScrollingButton = true;
this.showSpreadButton = true;
this.showPropertiesButton = true;
this.spreadChange = new EventEmitter();
this.secondaryMenuIsEmpty = new EventEmitter();
this.disablePreviousPage = true;
this.disableNextPage = true;
/** @type {?} */
const subscription = this.notificationService.onPDFJSInit.subscribe((/**
* @return {?}
*/
() => {
this.onPdfJsInit();
subscription.unsubscribe();
}));
}
/**
* @return {?}
*/
onPdfJsInit() {
/** @type {?} */
const PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
PDFViewerApplication.eventBus.on('pagechanging', (/**
* @return {?}
*/
() => {
this.updateUIState();
}));
PDFViewerApplication.eventBus.on('pagerendered', (/**
* @return {?}
*/
() => {
this.updateUIState();
}));
}
/**
* @return {?}
*/
updateUIState() {
setTimeout((/**
* @return {?}
*/
() => {
/** @type {?} */
const PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
/** @type {?} */
const currentPage = PDFViewerApplication.pdfViewer.currentPageNumber;
console.log('Upate - current page ' + currentPage + ' pages: ' + PDFViewerApplication.pagesCount);
/** @type {?} */
const previousButton = (/** @type {?} */ (document.getElementById('previousPage')));
if (previousButton) {
this.disablePreviousPage = Number(currentPage) <= 1;
previousButton.disabled = this.disablePreviousPage;
console.log('Previous.disabled is ' + this.disablePreviousPage);
}
/** @type {?} */
const nextButton = (/** @type {?} */ (document.getElementById('previousPage')));
if (nextButton) {
this.disableNextPage = currentPage === PDFViewerApplication.pagesCount;
nextButton.disabled = this.disableNextPage;
}
}));
}
/**
* @param {?} newSpread
* @return {?}
*/
onSpreadChange(newSpread) {
this.spreadChange.emit(newSpread);
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
setTimeout((/**
* @return {?}
*/
() => this.checkVisibility()));
}
/**
* @return {?}
*/
onResize() {
setTimeout((/**
* @return {?}
*/
() => this.checkVisibility()));
}
/**
* @return {?}
*/
ngAfterViewInit() {
setTimeout((/**
* @return {?}
*/
() => this.checkVisibility()));
}
/**
* @return {?}
*/
ngOnInit() {
setTimeout((/**
* @return {?}
*/
() => this.checkVisibility()));
}
/**
* @return {?}
*/
checkVisibility() {
/** @type {?} */
let visibleButtons = 0;
/** @type {?} */
const e = (/** @type {?} */ (this.element.nativeElement));
/** @type {?} */
const f = e.children.item(0);
if (f) {
/** @type {?} */
const g = f.children.item(0);
if (g && g instanceof HTMLElement) {
visibleButtons = this.checkVisibilityRecursively(g);
}
}
this.secondaryMenuIsEmpty.emit(visibleButtons === 0);
}
/**
* @private
* @param {?} e
* @return {?}
*/
checkVisibilityRecursively(e) {
if (e.style.display === 'none') {
return 0;
}
if (e.classList.contains('hidden')) {
return 0;
}
if (e.classList.contains('invisible')) {
return 0;
}
/** @type {?} */
const style = window.getComputedStyle(e);
if (style.display === 'none') {
return 0;
}
if (e instanceof HTMLButtonElement || e instanceof HTMLAnchorElement) {
return 1;
}
/** @type {?} */
let count = 0;
/** @type {?} */
const children = e.children;
if (children && children.length) {
for (let i = 0; i < children.length && count === 0; i++) {
/** @type {?} */
const child = children.item(i);
if (child && child instanceof HTMLElement) {
count += this.checkVisibilityRecursively(child);
}
}
}
return count;
}
/**
* @return {?}
*/
previousPage() {
/** @type {?} */
const PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
PDFViewerApplication.eventBus.dispatch('previouspage');
}
/**
* @return {?}
*/
nextPage() {
/** @type {?} */
const PDFViewerApplication = ((/** @type {?} */ (window))).PDFViewerApplication;
PDFViewerApplication.eventBus.dispatch('nextpage');
}
}
PdfSecondaryToolbarComponent.decorators = [
{ type: Component, args: [{
selector: 'pdf-secondary-toolbar',
template: "<ng-container [ngTemplateOutlet]=\"customSecondaryToolbar ? customSecondaryToolbar : defaultSecondaryToolbar\"> </ng-container>\n\n<ng-template #defaultSecondaryToolbar>\n <div\n id=\"secondaryToolbar\"\n class=\"secondaryToolbar hidden doorHangerRight\"\n [style.top]=\"secondaryToolbarTop\"\n [style.transform]=\"'scale(' + mobileFriendlyZoomScale + ')'\"\n [style.transformOrigin]=\"'right top'\"\n >\n <div id=\"secondaryToolbarButtonContainer\">\n <button\n type=\"button\"\n id=\"secondaryPresentationMode\"\n [class.invisible]=\"!showPresentationModeButton\"\n class=\"secondaryToolbarButton visibleLargeView\"\n title=\"Switch to Presentation Mode\"\n data-l10n-id=\"presentation_mode\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z\" />\n </svg>\n <span data-l10n-id=\"presentation_mode_label\">Presentation Mode</span>\n </button>\n\n <button\n type=\"button\"\n id=\"secondaryOpenFile\"\n [class.invisible]=\"!showOpenFileButton\"\n class=\"secondaryToolbarButton visibleMediumView\"\n title=\"Open File\"\n data-l10n-id=\"open_file\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M14,2L20,8V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2H14M18,20V9H13V4H6V20H18M12,12L16,16H13.5V19H10.5V16H8L12,12Z\" />\n </svg>\n <span data-l10n-id=\"open_file_label\">Open</span>\n </button>\n\n <button\n type=\"button\"\n id=\"secondaryPrint\"\n class=\"secondaryToolbarButton visibleSmallView\"\n [class.invisible]=\"!showPrintButton\"\n title=\"Print\"\n data-l10n-id=\"print\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M18,3H6V7H18M19,12A1,1 0 0,1 18,11A1,1 0 0,1 19,10A1,1 0 0,1 20,11A1,1 0 0,1 19,12M16,19H8V14H16M19,8H5A3,3 0 0,0 2,11V17H6V21H18V17H22V11A3,3 0 0,0 19,8Z\" />\n </svg>\n <span data-l10n-id=\"print_label\">Print</span>\n </button>\n\n <button\n type=\"button\"\n id=\"secondaryDownload\"\n class=\"secondaryToolbarButton visibleSmallView\"\n [class.invisible]=\"!showDownloadButton\"\n title=\"Download\"\n data-l10n-id=\"download\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M14,2L20,8V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2H14M18,20V9H13V4H6V20H18M12,19L8,15H10.5V12H13.5V15H16L12,19Z\" />\n </svg>\n <span data-l10n-id=\"download_label\">Download</span>\n </button>\n\n <a\n href=\"#\"\n id=\"secondaryViewBookmark\"\n class=\"secondaryToolbarButton bookmark visibleTinyView\"\n [class.invisible]=\"!showBookmarkButton\"\n title=\"Current view (copy or open in new window)\"\n data-l10n-id=\"bookmark\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M17,18L12,15.82L7,18V5H17M17,3H7A2,2 0 0,0 5,5V21L12,18L19,21V5C19,3.89 18.1,3 17,3Z\" />\n </svg>\n <span data-l10n-id=\"bookmark_label\">Current View</span>\n </a>\n\n <div class=\"horizontalToolbarSeparator visibleLargeView\"></div>\n\n <button\n type=\"button\"\n [class.invisible]=\"!showPagingButtons\"\n id=\"firstPage\"\n class=\"secondaryToolbarButton firstPage visibleLargeView\"\n title=\"Go to First Page\"\n data-l10n-id=\"first_page\"\n >\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M18.41,16.59L13.82,12L18.41,7.41L17,6L11,12L17,18L18.41,16.59M6,6H8V18H6V6Z\" />\n </svg>\n <span data-l10n-id=\"first_page_label\">Go to First Page</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showPagingButtons\"\n id=\"previousPage\"\n class=\"secondaryToolbarButton previousPage visibleTinyView\"\n title=\"Go to Previous Page\"\n data-l10n-id=\"previous\"\n (click)=\"previousPage()\"\n >\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z\" />\n </svg>\n <span data-l10n-id=\"previous_label\">Go to Previous Page</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showPagingButtons\"\n [disabled]=\"disableNextPage\"\n id=\"nextPage\"\n class=\"secondaryToolbarButton nextPage visibleTinyView\"\n title=\"Go to Next Page\"\n data-l10n-id=\"next\"\n (click)=\"nextPage()\"\n >\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z\" />\n </svg>\n <span data-l10n-id=\"next_label\">Go to Next Page</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showPagingButtons\"\n id=\"lastPage\"\n class=\"secondaryToolbarButton lastPage visibleLargeView\"\n title=\"Go to Last Page\"\n data-l10n-id=\"last_page\"\n >\n <svg style=\"width:24px;height:24px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M5.59,7.41L10.18,12L5.59,16.59L7,18L13,12L7,6L5.59,7.41M16,6H18V18H16V6Z\" />\n </svg>\n <span data-l10n-id=\"last_page_label\">Go to Last Page</span>\n </button>\n\n <div [class.invisible]=\"!showRotateButton\" class=\"horizontalToolbarSeparator visibleXLView\"></div>\n\n <button\n type=\"button\"\n [class.invisible]=\"!showRotateButton\"\n id=\"pageRotateCw\"\n class=\"secondaryToolbarButton rotateCw visibleXLView\"\n title=\"Rotate Clockwise\"\n data-l10n-id=\"page_rotate_cw\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M12 3C7.03 3 3 7.03 3 12S7.03 21 12 21C14 21 15.92 20.34 17.5 19.14L16.06 17.7C14.87 18.54 13.45 19 12 19C8.13 19 5 15.87 5 12S8.13 5 12 5 19 8.13 19 12H16L20 16L24 12H21C21 7.03 16.97 3 12 3\" />\n </svg>\n <span data-l10n-id=\"page_rotate_cw_label\">Rotate Clockwise</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showRotateButton\"\n id=\"pageRotateCcw\"\n class=\"secondaryToolbarButton rotateCcw visibleXLView\"\n title=\"Rotate Counterclockwise\"\n data-l10n-id=\"page_rotate_ccw\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M12 3C7.03 3 3 7.03 3 12H0L4 16L8 12H5C5 8.13 8.13 5 12 5S19 8.13 19 12 15.87 19 12 19C10.55 19 9.13 18.54 7.94 17.7L6.5 19.14C8.08 20.34 10 21 12 21C16.97 21 21 16.97 21 12S16.97 3 12 3\" />\n </svg>\n <span data-l10n-id=\"page_rotate_ccw_label\">Rotate Counterclockwise</span>\n </button>\n\n <div class=\"horizontalToolbarSeparator visibleXXLView\" [class.invisible]=\"!showHandToolButton\"></div>\n\n <button\n type=\"button\"\n [class.invisible]=\"!showHandToolButton\"\n id=\"cursorSelectTool\"\n class=\"secondaryToolbarButton toggled visibleXXLView\"\n title=\"Enable Text Selection Tool\"\n data-l10n-id=\"cursor_text_select_tool\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M2 4C2 2.89 2.9 2 4 2H7V4H4V7H2V4M22 4V7H20V4H17V2H20C21.1 2 22 2.89 22 4M2 20V17H4V20H7V22H4C2.9 22 2 21.11 2 20M10 2H14V4H10V2M10 20H14V22H10V20M2 10H4V14H2V10M18.5 13C20.4 13 22 14.6 22 16.5C22 19.1 18.5 23 18.5 23C18.5 23 15 19.1 15 16.5C15 14.6 16.6 13 18.5 13M18.5 17.8C19.2 17.8 19.8 17.2 19.7 16.6C19.7 16 19.1 15.4 18.5 15.4C17.9 15.4 17.3 15.9 17.3 16.6C17.3 17.2 17.8 17.8 18.5 17.8M20 10H22V12.34C21.42 11.84 20.74 11.45 20 11.23V10Z\" />\n </svg>\n <span data-l10n-id=\"cursor_text_select_tool_label\">Text Selection Tool</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showHandToolButton\"\n id=\"cursorHandTool\"\n class=\"secondaryToolbarButton visibleXXLView\"\n title=\"Enable Hand Tool\"\n data-l10n-id=\"cursor_hand_tool\"\n >\n <svg style=\"width:22px;height:22px\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M13,6V11H18V7.75L22.25,12L18,16.25V13H13V18H16.25L12,22.25L7.75,18H11V13H6V16.25L1.75,12L6,7.75V11H11V6H7.75L12,1.75L16.25,6H13Z\" />\n </svg>\n <span data-l10n-id=\"cursor_hand_tool_label\">Hand Tool</span>\n </button>\n\n <div [class.invisible]=\"!showScrollingButton\" class=\"horizontalToolbarSeparator\"></div>\n\n <button\n type=\"button\"\n [class.invisible]=\"!showScrollingButton\"\n id=\"scrollVertical\"\n class=\"secondaryToolbarButton scrollVertical toggled\"\n title=\"Use Vertical Scrolling\"\n data-l10n-id=\"scroll_vertical\"\n >\n <span data-l10n-id=\"scroll_vertical_label\">Vertical Scrolling</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showScrollingButton\"\n id=\"scrollHorizontal\"\n class=\"secondaryToolbarButton scrollHorizontal\"\n title=\"Use Horizontal Scrolling\"\n data-l10n-id=\"scroll_horizontal\"\n >\n <span data-l10n-id=\"scroll_horizontal_label\">Horizontal Scrolling</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showScrollingButton\"\n id=\"scrollWrapped\"\n class=\"secondaryToolbarButton scrollWrapped\"\n title=\"Use Wrapped Scrolling\"\n data-l10n-id=\"scroll_wrapped\"\n >\n <span data-l10n-id=\"scroll_wrapped_label\">Wrapped Scrolling</span>\n </button>\n\n <div [class.invisible]=\"!showSpreadButton\" class=\"horizontalToolbarSeparator\"></div>\n\n <button\n type=\"button\"\n [class.invisible]=\"!showSpreadButton\"\n id=\"spreadNone\"\n class=\"secondaryToolbarButton spreadNone toggled\"\n title=\"Do not join page spreads\"\n data-l10n-id=\"spread_none\"\n (click)=\"onSpreadChange('off')\"\n >\n <span data-l10n-id=\"spread_none_label\">No Spreads</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showSpreadButton\"\n id=\"spreadOdd\"\n class=\"secondaryToolbarButton spreadOdd\"\n title=\"Join page spreads starting with odd-numbered pages\"\n data-l10n-id=\"spread_odd\"\n (click)=\"onSpreadChange('odd')\"\n >\n <span data-l10n-id=\"spread_odd_label\">Odd Spreads</span>\n </button>\n <button\n type=\"button\"\n [class.invisible]=\"!showSpreadButton\"\n id=\"spreadEven\"\n class=\"secondaryToolbarButton spreadEven\"\n title=\"Join page spreads starting with even-numbered pages\"\n data-l10n-id=\"spread_even\"\n (click)=\"onSpreadChange('even')\"\n >\n <span data-l10n-id=\"spread_even_label\">Even Spreads</span>\n </button>\n\n <div [class.invisible]=\"!showPropertiesButton\" class=\"horizontalToolbarSeparator spreadModeButtons\"></div>\n\n <button\n type=\"button\"\n [class.invisible]=\"!showPropertiesButton\"\n id=\"documentProperties\"\n class=\"secondaryToolbarButton documentProperties\"\n title=\"Document Properties\u2026\"\n data-l10n-id=\"document_properties\"\n >\n <span data-l10n-id=\"document_properties_label\">Document Properties\u2026</span>\n </button>\n </div>\n </div>\n</ng-template>\n",
styles: ["svg{position:absolute;display:inline-block;top:0;left:0}"]
}] }
];
/** @nocollapse */
PdfSecondaryToolbarComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: PDFNotificationService },
{ type: NgZone }
];
PdfSecondaryToolbarComponent.propDecorators = {
customSecondaryToolbar: [{ type: Input }],
secondaryToolbarTop: [{ type: Input }],
mobileFriendlyZoomScale: [{ type: Input }],
showPresentationModeButton: [{ type: Input }],
showOpenFileButton: [{ type: Input }],
showPrintButton: [{ type: Input }],
showDownloadButton: [{ type: Input }],
showBookmarkButton: [{ type: Input }],
showPagingButtons: [{ type: Input }],
showRotateButton: [{ type: Input }],
showHandToolButton: [{ type: Input }],
showScrollingButton: [{ type: Input }],
showSpreadButton: [{ type: Input }],
showPropertiesButton: [{ type: Input }],
spreadChange: [{ type: Output }],
secondaryMenuIsEmpty: [{ type: Output }],
onResize: [{ type: HostListener, args: ['window:resize',] }]
};
if (false) {
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.customSecondaryToolbar;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.secondaryToolbarTop;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.mobileFriendlyZoomScale;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showPresentationModeButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showOpenFileButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showPrintButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showDownloadButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showBookmarkButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showPagingButtons;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showRotateButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showHandToolButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showScrollingButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showSpreadButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.showPropertiesButton;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.spreadChange;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.secondaryMenuIsEmpty;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.disablePreviousPage;
/** @type {?} */
PdfSecondaryToolbarComponent.prototype.disableNextPage;
/**
* @type {?}
* @private
*/
PdfSecondaryToolbarComponent.prototype.element;
/**
* @type {?}
* @private
*/
PdfSecondaryToolbarComponent.prototype.notificationService;
/**
* @type {?}
* @private
*/
PdfSecondaryToolbarComponent.prototype.ngZone;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGRmLXNlY29uZGFyeS10b29sYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1leHRlbmRlZC1wZGYtdmlld2VyLyIsInNvdXJjZXMiOlsibGliL3NlY29uZGFyeS10b29sYmFyL3BkZi1zZWNvbmRhcnktdG9vbGJhci9wZGYtc2Vjb25kYXJ5LXRvb2xiYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFHWixXQUFXLEVBQ1gsVUFBVSxFQUNWLFlBQVksRUFFWixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFPMUUsTUFBTSxPQUFPLDRCQUE0Qjs7Ozs7O0lBcUR2QyxZQUFvQixPQUFtQixFQUFVLG1CQUEyQyxFQUFVLE1BQWM7UUFBaEcsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQUFVLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBd0I7UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBMUM3RywrQkFBMEIsR0FBRyxJQUFJLENBQUM7UUFHbEMsdUJBQWtCLEdBQUcsSUFBSSxDQUFDO1FBRzFCLG9CQUFlLEdBQUcsSUFBSSxDQUFDO1FBR3ZCLHVCQUFrQixHQUFHLElBQUksQ0FBQztRQUcxQix1QkFBa0IsR0FBRyxJQUFJLENBQUM7UUFHMUIsc0JBQWlCLEdBQUcsSUFBSSxDQUFDO1FBR3pCLHFCQUFnQixHQUFHLElBQUksQ0FBQztRQUd4Qix1QkFBa0IsR0FBRyxJQUFJLENBQUM7UUFHMUIsd0JBQW1CLEdBQUcsSUFBSSxDQUFDO1FBRzNCLHFCQUFnQixHQUFHLElBQUksQ0FBQztRQUd4Qix5QkFBb0IsR0FBRyxJQUFJLENBQUM7UUFHNUIsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRzFDLHlCQUFvQixHQUFHLElBQUksWUFB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LDBEQUNpQzs7SUFFakMsMERBQ2lDOztJQUVqQyx5REFDZ0M7O0lBRWhDLHdEQUMrQjs7SUFFL0IsMERBQ2lDOztJQUVqQywyREFDa0M7O0lBRWxDLHdEQUMrQjs7SUFFL0IsNERBQ21DOztJQUVuQyxvREFDaUQ7O0lBRWpELDREQUMwRDs7SUFFMUQsMkRBQWtDOztJQUVsQyx1REFBOEI7Ozs7O0lBRWxCLCtDQUEyQjs7Ozs7SUFBRSwyREFBbUQ7Ozs7O0lBQUUsOENBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgRWxlbWVudFJlZixcbiAgSG9zdExpc3RlbmVyLFxuICBBZnRlclZpZXdJbml0LFxuICBOZ1pvbmUsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSVBERlZpZXdlckFwcGxpY2F0aW9uIH0gZnJvbSAnLi4vLi4vb3B0aW9ucy9wZGYtdmlld2VyLWFwcGxpY2F0aW9uJztcbmltcG9ydCB7IFVwZGF0ZVVJU3RhdGVFdmVudCB9IGZyb20gJy4uLy4uL2V2ZW50cy91cGRhdGUtdWktc3RhdGUtZXZlbnQnO1xuaW1wb3J0IHsgUERGTm90aWZpY2F0aW9uU2VydmljZSB9IGZyb20gJy4vLi4vLi4vcGRmLW5vdGlmaWNhdGlvbi1zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncGRmLXNlY29uZGFyeS10b29sYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3BkZi1zZWNvbmRhcnktdG9vbGJhci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3BkZi1zZWNvbmRhcnktdG9vbGJhci5jb21wb25lbnQuY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFBkZlNlY29uZGFyeVRvb2xiYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCB7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjdXN0b21TZWNvbmRhcnlUb29sYmFyOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZWNvbmRhcnlUb29sYmFyVG9wO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBtb2JpbGVGcmllbmRseVpvb21TY2FsZTogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzaG93UHJlc2VudGF0aW9uTW9kZUJ1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3dPcGVuRmlsZUJ1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3dQcmludEJ1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3dEb3dubG9hZEJ1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3dCb29rbWFya0J1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3dQYWdpbmdCdXR0b25zID0gdHJ1ZTtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgc2hvd1JvdGF0ZUJ1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3dIYW5kVG9vbEJ1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3dTY3JvbGxpbmdCdXR0b24gPSB0cnVlO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzaG93U3ByZWFkQnV0dG9uID0gdHJ1ZTtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgc2hvd1Byb3BlcnRpZXNCdXR0b24gPSB0cnVlO1xuXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgc3ByZWFkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBzZWNvbmRhcnlNZW51SXNFbXB0eSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICBwdWJsaWMgZGlzYWJsZVByZXZpb3VzUGFnZSA9IHRydWU7XG5cbiAgcHVibGljIGRpc2FibGVOZXh0UGFnZSA9IHRydWU7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmLCBwcml2YXRlIG5vdGlmaWNhdGlvblNlcnZpY2U6IFBERk5vdGlmaWNhdGlvblNlcnZpY2UsIHByaXZhdGUgbmdab25lOiBOZ1pvbmUpIHtcbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2Uub25QREZKU0luaXQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMub25QZGZKc0luaXQoKTtcbiAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uUGRmSnNJbml0KCk6IHZvaWQge1xuICAgIGNvbnN0IFBERlZpZXdlckFwcGxpY2F0aW9uOiBJUERGVmlld2VyQXBwbGljYXRpb24gPSAod2luZG93IGFzIGFueSkuUERGVmlld2VyQXBwbGljYXRpb247XG4gICAgUERGVmlld2VyQXBwbGljYXRpb24uZXZlbnRCdXMub24oJ3BhZ2VjaGFuZ2luZycsICgpID0+IHtcbiAgICAgIHRoaXMudXBkYXRlVUlTdGF0ZSgpO1xuICAgIH0pO1xuICAgIFBERlZpZXdlckFwcGxpY2F0aW9uLmV2ZW50QnVzLm9uKCdwYWdlcmVuZGVyZWQnLCAoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVVJU3RhdGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVVSVN0YXRlKCk6IHZvaWQge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICAgIGNvbnN0IGN1cnJlbnRQYWdlID0gUERGVmlld2VyQXBwbGljYXRpb24ucGRmVmlld2VyLmN1cnJlbnRQYWdlTnVtYmVyO1xuICAgICAgY29uc29sZS5sb2coJ1VwYXRlIC0gY3VycmVudCBwYWdlICcgKyBjdXJyZW50UGFnZSArICcgcGFnZXM6ICcgKyBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wYWdlc0NvdW50KTtcbiAgICAgIGNvbnN0IHByZXZpb3VzQnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ByZXZpb3VzUGFnZScpIGFzIEhUTUxCdXR0b25FbGVtZW50O1xuICAgICAgaWYgKHByZXZpb3VzQnV0dG9uKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZVByZXZpb3VzUGFnZSA9IE51bWJlcihjdXJyZW50UGFnZSkgPD0gMTtcbiAgICAgICAgcHJldmlvdXNCdXR0b24uZGlzYWJsZWQgPSB0aGlzLmRpc2FibGVQcmV2aW91c1BhZ2U7XG4gICAgICAgIGNvbnNvbGUubG9nKCdQcmV2aW91cy5kaXNhYmxlZCBpcyAnICsgdGhpcy5kaXNhYmxlUHJldmlvdXNQYWdlKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5leHRCdXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHJldmlvdXNQYWdlJykgYXMgSFRNTEJ1dHRvbkVsZW1lbnQ7XG4gICAgICBpZiAobmV4dEJ1dHRvbikge1xuICAgICAgICB0aGlzLmRpc2FibGVOZXh0UGFnZSA9IGN1cnJlbnRQYWdlID09PSBQREZWaWV3ZXJBcHBsaWNhdGlvbi5wYWdlc0NvdW50O1xuICAgICAgICBuZXh0QnV0dG9uLmRpc2FibGVkID0gdGhpcy5kaXNhYmxlTmV4dFBhZ2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgb25TcHJlYWRDaGFuZ2UobmV3U3ByZWFkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnNwcmVhZENoYW5nZS5lbWl0KG5ld1NwcmVhZCk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jaGVja1Zpc2liaWxpdHkoKSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJylcbiAgcHVibGljIG9uUmVzaXplKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jaGVja1Zpc2liaWxpdHkoKSk7XG4gIH1cblxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jaGVja1Zpc2liaWxpdHkoKSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNoZWNrVmlzaWJpbGl0eSgpKTtcbiAgfVxuXG4gIHB1YmxpYyBjaGVja1Zpc2liaWxpdHkoKTogdm9pZCB7XG4gICAgbGV0IHZpc2libGVCdXR0b25zID0gMDtcbiAgICBjb25zdCBlID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgY29uc3QgZiA9IGUuY2hpbGRyZW4uaXRlbSgwKTtcbiAgICBpZiAoZikge1xuICAgICAgY29uc3QgZyA9IGYuY2hpbGRyZW4uaXRlbSgwKTtcbiAgICAgIGlmIChnICYmIGcgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICB2aXNpYmxlQnV0dG9ucyA9IHRoaXMuY2hlY2tWaXNpYmlsaXR5UmVjdXJzaXZlbHkoZyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuc2Vjb25kYXJ5TWVudUlzRW1wdHkuZW1pdCh2aXNpYmxlQnV0dG9ucyA9PT0gMCk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrVmlzaWJpbGl0eVJlY3Vyc2l2ZWx5KGU6IEhUTUxFbGVtZW50KTogbnVtYmVyIHtcbiAgICBpZiAoZS5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAoZS5jbGFzc0xpc3QuY29udGFpbnMoJ2hpZGRlbicpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaWYgKGUuY2xhc3NMaXN0LmNvbnRhaW5zKCdpbnZpc2libGUnKSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlKTtcbiAgICBpZiAoc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBpZiAoZSBpbnN0YW5jZW9mIEhUTUxCdXR0b25FbGVtZW50IHx8IGUgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCkge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIGxldCBjb3VudCA9IDA7XG4gICAgY29uc3QgY2hpbGRyZW4gPSBlLmNoaWxkcmVuO1xuICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoICYmIGNvdW50ID09PSAwOyBpKyspIHtcbiAgICAgICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbi5pdGVtKGkpO1xuICAgICAgICBpZiAoY2hpbGQgJiYgY2hpbGQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgIGNvdW50ICs9IHRoaXMuY2hlY2tWaXNpYmlsaXR5UmVjdXJzaXZlbHkoY2hpbGQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIHB1YmxpYyBwcmV2aW91c1BhZ2UoKTogdm9pZCB7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBQREZWaWV3ZXJBcHBsaWNhdGlvbi5ldmVudEJ1cy5kaXNwYXRjaCgncHJldmlvdXNwYWdlJyk7XG4gIH1cblxuICBwdWJsaWMgbmV4dFBhZ2UoKTogdm9pZCB7XG4gICAgY29uc3QgUERGVmlld2VyQXBwbGljYXRpb246IElQREZWaWV3ZXJBcHBsaWNhdGlvbiA9ICh3aW5kb3cgYXMgYW55KS5QREZWaWV3ZXJBcHBsaWNhdGlvbjtcbiAgICBQREZWaWV3ZXJBcHBsaWNhdGlvbi5ldmVudEJ1cy5kaXNwYXRjaCgnbmV4dHBhZ2UnKTtcbiAgfVxufVxuIl19