Some checks failed
		
		
	
	Types tests / Test (lts/*) (push) Has been cancelled
				
			Lint / Lint (lts/*) (push) Has been cancelled
				
			CodeQL / Analyze (javascript) (push) Has been cancelled
				
			CI / Test (20) (push) Has been cancelled
				
			CI / Test (22) (push) Has been cancelled
				
			CI / Test (24) (push) Has been cancelled
				
			
		
			
				
	
	
		
			3208 lines
		
	
	
		
			96 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			3208 lines
		
	
	
		
			96 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Copyright 2012 Mozilla Foundation
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
 | 
						|
/** @typedef {import("./interfaces.js").IL10n} IL10n */
 | 
						|
// eslint-disable-next-line max-len
 | 
						|
/** @typedef {import("../src/display/api.js").PDFDocumentProxy} PDFDocumentProxy */
 | 
						|
// eslint-disable-next-line max-len
 | 
						|
/** @typedef {import("../src/display/api.js").PDFDocumentLoadingTask} PDFDocumentLoadingTask */
 | 
						|
 | 
						|
import {
 | 
						|
  animationStarted,
 | 
						|
  apiPageLayoutToViewerModes,
 | 
						|
  apiPageModeToSidebarView,
 | 
						|
  AutoPrintRegExp,
 | 
						|
  CursorTool,
 | 
						|
  DEFAULT_SCALE_VALUE,
 | 
						|
  docStyle,
 | 
						|
  getActiveOrFocusedElement,
 | 
						|
  isValidRotation,
 | 
						|
  isValidScrollMode,
 | 
						|
  isValidSpreadMode,
 | 
						|
  normalizeWheelEventDirection,
 | 
						|
  parseQueryString,
 | 
						|
  ProgressBar,
 | 
						|
  RenderingStates,
 | 
						|
  ScrollMode,
 | 
						|
  SidebarView,
 | 
						|
  SpreadMode,
 | 
						|
  TextLayerMode,
 | 
						|
} from "./ui_utils.js";
 | 
						|
import {
 | 
						|
  AnnotationEditorType,
 | 
						|
  build,
 | 
						|
  FeatureTest,
 | 
						|
  getDocument,
 | 
						|
  getFilenameFromUrl,
 | 
						|
  getPdfFilenameFromUrl,
 | 
						|
  GlobalWorkerOptions,
 | 
						|
  InvalidPDFException,
 | 
						|
  isDataScheme,
 | 
						|
  isPdfFile,
 | 
						|
  OutputScale,
 | 
						|
  PDFWorker,
 | 
						|
  ResponseException,
 | 
						|
  shadow,
 | 
						|
  stopEvent,
 | 
						|
  TouchManager,
 | 
						|
  updateUrlHash,
 | 
						|
  version,
 | 
						|
} from "pdfjs-lib";
 | 
						|
import { AppOptions, OptionKind } from "./app_options.js";
 | 
						|
import { EventBus, FirefoxEventBus } from "./event_utils.js";
 | 
						|
import { ExternalServices, initCom, MLManager } from "web-external_services";
 | 
						|
import {
 | 
						|
  ImageAltTextSettings,
 | 
						|
  NewAltTextManager,
 | 
						|
} from "web-new_alt_text_manager";
 | 
						|
import { LinkTarget, PDFLinkService } from "./pdf_link_service.js";
 | 
						|
import { AltTextManager } from "web-alt_text_manager";
 | 
						|
import { AnnotationEditorParams } from "web-annotation_editor_params";
 | 
						|
import { CaretBrowsingMode } from "./caret_browsing.js";
 | 
						|
import { CommentManager } from "./comment_manager.js";
 | 
						|
import { DownloadManager } from "web-download_manager";
 | 
						|
import { EditorUndoBar } from "./editor_undo_bar.js";
 | 
						|
import { OverlayManager } from "./overlay_manager.js";
 | 
						|
import { PasswordPrompt } from "./password_prompt.js";
 | 
						|
import { PDFAttachmentViewer } from "web-pdf_attachment_viewer";
 | 
						|
import { PDFCursorTools } from "web-pdf_cursor_tools";
 | 
						|
import { PDFDocumentProperties } from "web-pdf_document_properties";
 | 
						|
import { PDFFindBar } from "web-pdf_find_bar";
 | 
						|
import { PDFFindController } from "./pdf_find_controller.js";
 | 
						|
import { PDFHistory } from "./pdf_history.js";
 | 
						|
import { PDFLayerViewer } from "web-pdf_layer_viewer";
 | 
						|
import { PDFOutlineViewer } from "web-pdf_outline_viewer";
 | 
						|
import { PDFPresentationMode } from "web-pdf_presentation_mode";
 | 
						|
import { PDFPrintServiceFactory } from "web-print_service";
 | 
						|
import { PDFRenderingQueue } from "./pdf_rendering_queue.js";
 | 
						|
import { PDFScriptingManager } from "./pdf_scripting_manager.js";
 | 
						|
import { PDFSidebar } from "web-pdf_sidebar";
 | 
						|
import { PDFThumbnailViewer } from "web-pdf_thumbnail_viewer";
 | 
						|
import { PDFViewer } from "./pdf_viewer.js";
 | 
						|
import { Preferences } from "web-preferences";
 | 
						|
import { SecondaryToolbar } from "web-secondary_toolbar";
 | 
						|
import { SignatureManager } from "web-signature_manager";
 | 
						|
import { Toolbar } from "web-toolbar";
 | 
						|
import { ViewHistory } from "./view_history.js";
 | 
						|
 | 
						|
const FORCE_PAGES_LOADED_TIMEOUT = 10000; // ms
 | 
						|
 | 
						|
const ViewOnLoad = {
 | 
						|
  UNKNOWN: -1,
 | 
						|
  PREVIOUS: 0, // Default value.
 | 
						|
  INITIAL: 1,
 | 
						|
};
 | 
						|
 | 
						|
const PDFViewerApplication = {
 | 
						|
  initialBookmark: document.location.hash.substring(1),
 | 
						|
  _initializedCapability: {
 | 
						|
    ...Promise.withResolvers(),
 | 
						|
    settled: false,
 | 
						|
  },
 | 
						|
  appConfig: null,
 | 
						|
  /** @type {PDFDocumentProxy} */
 | 
						|
  pdfDocument: null,
 | 
						|
  /** @type {PDFDocumentLoadingTask} */
 | 
						|
  pdfLoadingTask: null,
 | 
						|
  printService: null,
 | 
						|
  /** @type {PDFViewer} */
 | 
						|
  pdfViewer: null,
 | 
						|
  /** @type {PDFThumbnailViewer} */
 | 
						|
  pdfThumbnailViewer: null,
 | 
						|
  /** @type {PDFRenderingQueue} */
 | 
						|
  pdfRenderingQueue: null,
 | 
						|
  /** @type {PDFPresentationMode} */
 | 
						|
  pdfPresentationMode: null,
 | 
						|
  /** @type {PDFDocumentProperties} */
 | 
						|
  pdfDocumentProperties: null,
 | 
						|
  /** @type {PDFLinkService} */
 | 
						|
  pdfLinkService: null,
 | 
						|
  /** @type {PDFHistory} */
 | 
						|
  pdfHistory: null,
 | 
						|
  /** @type {PDFSidebar} */
 | 
						|
  pdfSidebar: null,
 | 
						|
  /** @type {PDFOutlineViewer} */
 | 
						|
  pdfOutlineViewer: null,
 | 
						|
  /** @type {PDFAttachmentViewer} */
 | 
						|
  pdfAttachmentViewer: null,
 | 
						|
  /** @type {PDFLayerViewer} */
 | 
						|
  pdfLayerViewer: null,
 | 
						|
  /** @type {PDFCursorTools} */
 | 
						|
  pdfCursorTools: null,
 | 
						|
  /** @type {PDFScriptingManager} */
 | 
						|
  pdfScriptingManager: null,
 | 
						|
  /** @type {ViewHistory} */
 | 
						|
  store: null,
 | 
						|
  /** @type {DownloadManager} */
 | 
						|
  downloadManager: null,
 | 
						|
  /** @type {OverlayManager} */
 | 
						|
  overlayManager: null,
 | 
						|
  /** @type {Preferences} */
 | 
						|
  preferences: new Preferences(),
 | 
						|
  /** @type {Toolbar} */
 | 
						|
  toolbar: null,
 | 
						|
  /** @type {SecondaryToolbar} */
 | 
						|
  secondaryToolbar: null,
 | 
						|
  /** @type {EventBus} */
 | 
						|
  eventBus: null,
 | 
						|
  /** @type {IL10n} */
 | 
						|
  l10n: null,
 | 
						|
  /** @type {AnnotationEditorParams} */
 | 
						|
  annotationEditorParams: null,
 | 
						|
  /** @type {ImageAltTextSettings} */
 | 
						|
  imageAltTextSettings: null,
 | 
						|
  isInitialViewSet: false,
 | 
						|
  isViewerEmbedded: window.parent !== window,
 | 
						|
  url: "",
 | 
						|
  baseUrl: "",
 | 
						|
  mlManager: null,
 | 
						|
  _downloadUrl: "",
 | 
						|
  _eventBusAbortController: null,
 | 
						|
  _windowAbortController: null,
 | 
						|
  _globalAbortController: new AbortController(),
 | 
						|
  documentInfo: null,
 | 
						|
  metadata: null,
 | 
						|
  _contentDispositionFilename: null,
 | 
						|
  _contentLength: null,
 | 
						|
  _saveInProgress: false,
 | 
						|
  _wheelUnusedTicks: 0,
 | 
						|
  _wheelUnusedFactor: 1,
 | 
						|
  _touchManager: null,
 | 
						|
  _touchUnusedTicks: 0,
 | 
						|
  _touchUnusedFactor: 1,
 | 
						|
  _PDFBug: null,
 | 
						|
  _hasAnnotationEditors: false,
 | 
						|
  _title: document.title,
 | 
						|
  _printAnnotationStoragePromise: null,
 | 
						|
  _isCtrlKeyDown: false,
 | 
						|
  _caretBrowsing: null,
 | 
						|
  _isScrolling: false,
 | 
						|
  editorUndoBar: null,
 | 
						|
  _printPermissionPromise: null,
 | 
						|
 | 
						|
  // Called once when the document is loaded.
 | 
						|
  async initialize(appConfig) {
 | 
						|
    this.appConfig = appConfig;
 | 
						|
 | 
						|
    // Ensure that `Preferences`, and indirectly `AppOptions`, have initialized
 | 
						|
    // before creating e.g. the various viewer components.
 | 
						|
    try {
 | 
						|
      await this.preferences.initializedPromise;
 | 
						|
    } catch (ex) {
 | 
						|
      console.error("initialize:", ex);
 | 
						|
    }
 | 
						|
    if (AppOptions.get("pdfBugEnabled")) {
 | 
						|
      await this._parseHashParams();
 | 
						|
    }
 | 
						|
 | 
						|
    let mode;
 | 
						|
    switch (AppOptions.get("viewerCssTheme")) {
 | 
						|
      case 1:
 | 
						|
        mode = "light";
 | 
						|
        break;
 | 
						|
      case 2:
 | 
						|
        mode = "dark";
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    if (mode) {
 | 
						|
      docStyle.setProperty("color-scheme", mode);
 | 
						|
    }
 | 
						|
 | 
						|
    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
 | 
						|
      if (AppOptions.get("enableFakeMLManager")) {
 | 
						|
        this.mlManager =
 | 
						|
          MLManager.getFakeMLManager?.({
 | 
						|
            enableGuessAltText: AppOptions.get("enableGuessAltText"),
 | 
						|
            enableAltTextModelDownload: AppOptions.get(
 | 
						|
              "enableAltTextModelDownload"
 | 
						|
            ),
 | 
						|
          }) || null;
 | 
						|
      }
 | 
						|
    } else if (PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
      if (AppOptions.get("enableAltText")) {
 | 
						|
        // We want to load the image-to-text AI engine as soon as possible.
 | 
						|
        this.mlManager = new MLManager({
 | 
						|
          enableGuessAltText: AppOptions.get("enableGuessAltText"),
 | 
						|
          enableAltTextModelDownload: AppOptions.get(
 | 
						|
            "enableAltTextModelDownload"
 | 
						|
          ),
 | 
						|
          altTextLearnMoreUrl: AppOptions.get("altTextLearnMoreUrl"),
 | 
						|
        });
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    // Ensure that the `L10n`-instance has been initialized before creating
 | 
						|
    // e.g. the various viewer components.
 | 
						|
    this.l10n = await this.externalServices.createL10n();
 | 
						|
    document.getElementsByTagName("html")[0].dir = this.l10n.getDirection();
 | 
						|
    // Connect Fluent, when necessary, and translate what we already have.
 | 
						|
    if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
      this.l10n.translate(appConfig.appContainer || document.documentElement);
 | 
						|
    }
 | 
						|
 | 
						|
    if (
 | 
						|
      this.isViewerEmbedded &&
 | 
						|
      AppOptions.get("externalLinkTarget") === LinkTarget.NONE
 | 
						|
    ) {
 | 
						|
      // Prevent external links from "replacing" the viewer,
 | 
						|
      // when it's embedded in e.g. an <iframe> or an <object>.
 | 
						|
      AppOptions.set("externalLinkTarget", LinkTarget.TOP);
 | 
						|
    }
 | 
						|
    await this._initializeViewerComponents();
 | 
						|
 | 
						|
    // Bind the various event handlers *after* the viewer has been
 | 
						|
    // initialized, to prevent errors if an event arrives too soon.
 | 
						|
    this.bindEvents();
 | 
						|
    this.bindWindowEvents();
 | 
						|
 | 
						|
    this._initializedCapability.settled = true;
 | 
						|
    this._initializedCapability.resolve();
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Potentially parse special debugging flags in the hash section of the URL.
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  async _parseHashParams() {
 | 
						|
    const hash = document.location.hash.substring(1);
 | 
						|
    if (!hash) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const { mainContainer, viewerContainer } = this.appConfig,
 | 
						|
      params = parseQueryString(hash);
 | 
						|
 | 
						|
    const loadPDFBug = async () => {
 | 
						|
      if (this._PDFBug) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      const { PDFBug } =
 | 
						|
        typeof PDFJSDev === "undefined"
 | 
						|
          ? await import(AppOptions.get("debuggerSrc")) // eslint-disable-line no-unsanitized/method
 | 
						|
          : await __raw_import__(AppOptions.get("debuggerSrc"));
 | 
						|
 | 
						|
      this._PDFBug = PDFBug;
 | 
						|
    };
 | 
						|
 | 
						|
    // Parameters that need to be handled manually.
 | 
						|
    if (params.get("disableworker") === "true") {
 | 
						|
      try {
 | 
						|
        GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc");
 | 
						|
 | 
						|
        typeof PDFJSDev === "undefined" // eslint-disable-line no-unused-expressions
 | 
						|
          ? await import("pdfjs/pdf.worker.js")
 | 
						|
          : await __raw_import__(PDFWorker.workerSrc);
 | 
						|
 | 
						|
        // Ensure that the "fake" worker won't be ignored.
 | 
						|
        AppOptions.set("workerPort", null);
 | 
						|
      } catch (ex) {
 | 
						|
        console.error("_parseHashParams:", ex);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (params.has("textlayer")) {
 | 
						|
      switch (params.get("textlayer")) {
 | 
						|
        case "off":
 | 
						|
          AppOptions.set("textLayerMode", TextLayerMode.DISABLE);
 | 
						|
          break;
 | 
						|
        case "visible":
 | 
						|
        case "shadow":
 | 
						|
        case "hover":
 | 
						|
          viewerContainer.classList.add(`textLayer-${params.get("textlayer")}`);
 | 
						|
          try {
 | 
						|
            await loadPDFBug();
 | 
						|
            this._PDFBug.loadCSS();
 | 
						|
          } catch (ex) {
 | 
						|
            console.error("_parseHashParams:", ex);
 | 
						|
          }
 | 
						|
          break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (params.has("pdfbug")) {
 | 
						|
      const enabled = params.get("pdfbug").split(",");
 | 
						|
      try {
 | 
						|
        await loadPDFBug();
 | 
						|
        this._PDFBug.init(mainContainer, enabled);
 | 
						|
      } catch (ex) {
 | 
						|
        console.error("_parseHashParams:", ex);
 | 
						|
      }
 | 
						|
 | 
						|
      const debugOpts = { pdfBug: true, fontExtraProperties: true };
 | 
						|
      if (globalThis.StepperManager?.enabled) {
 | 
						|
        debugOpts.minDurationToUpdateCanvas = 0;
 | 
						|
      }
 | 
						|
      AppOptions.setAll(debugOpts);
 | 
						|
    }
 | 
						|
    // It is not possible to change locale for the (various) extension builds.
 | 
						|
    if (
 | 
						|
      (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
 | 
						|
      params.has("locale")
 | 
						|
    ) {
 | 
						|
      AppOptions.set("localeProperties", { lang: params.get("locale") });
 | 
						|
    }
 | 
						|
 | 
						|
    // Parameters that can be handled automatically.
 | 
						|
    const opts = {
 | 
						|
      disableAutoFetch: x => x === "true",
 | 
						|
      disableFontFace: x => x === "true",
 | 
						|
      disableHistory: x => x === "true",
 | 
						|
      disableRange: x => x === "true",
 | 
						|
      disableStream: x => x === "true",
 | 
						|
      verbosity: x => x | 0,
 | 
						|
    };
 | 
						|
 | 
						|
    // Set some specific preferences for tests.
 | 
						|
    if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
 | 
						|
      Object.assign(opts, {
 | 
						|
        capCanvasAreaFactor: x => parseInt(x),
 | 
						|
        docBaseUrl: x => x,
 | 
						|
        enableAltText: x => x === "true",
 | 
						|
        enableAutoLinking: x => x === "true",
 | 
						|
        enableComment: x => x === "true",
 | 
						|
        enableFakeMLManager: x => x === "true",
 | 
						|
        enableGuessAltText: x => x === "true",
 | 
						|
        enablePermissions: x => x === "true",
 | 
						|
        enableUpdatedAddImage: x => x === "true",
 | 
						|
        highlightEditorColors: x => x,
 | 
						|
        maxCanvasPixels: x => parseInt(x),
 | 
						|
        spreadModeOnLoad: x => parseInt(x),
 | 
						|
        supportsCaretBrowsingMode: x => x === "true",
 | 
						|
        viewerCssTheme: x => parseInt(x),
 | 
						|
        forcePageColors: x => x === "true",
 | 
						|
        pageColorsBackground: x => x,
 | 
						|
        pageColorsForeground: x => x,
 | 
						|
        localeProperties: x => ({ lang: x }),
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    for (const name in opts) {
 | 
						|
      const check = opts[name],
 | 
						|
        key = name.toLowerCase();
 | 
						|
 | 
						|
      if (params.has(key)) {
 | 
						|
        AppOptions.set(name, check(params.get(key)));
 | 
						|
      }
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  async _initializeViewerComponents() {
 | 
						|
    const { appConfig, externalServices, l10n, mlManager } = this;
 | 
						|
    const abortSignal = this._globalAbortController.signal;
 | 
						|
 | 
						|
    const eventBus =
 | 
						|
      typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")
 | 
						|
        ? new FirefoxEventBus(
 | 
						|
            AppOptions.get("allowedGlobalEvents"),
 | 
						|
            externalServices,
 | 
						|
            AppOptions.get("isInAutomation")
 | 
						|
          )
 | 
						|
        : new EventBus();
 | 
						|
    this.eventBus = AppOptions.eventBus = eventBus;
 | 
						|
 | 
						|
    mlManager?.setEventBus(eventBus, abortSignal);
 | 
						|
 | 
						|
    const overlayManager = (this.overlayManager = new OverlayManager());
 | 
						|
 | 
						|
    const renderingQueue = (this.pdfRenderingQueue = new PDFRenderingQueue());
 | 
						|
    renderingQueue.onIdle = this._cleanup.bind(this);
 | 
						|
 | 
						|
    const linkService = (this.pdfLinkService = new PDFLinkService({
 | 
						|
      eventBus,
 | 
						|
      externalLinkTarget: AppOptions.get("externalLinkTarget"),
 | 
						|
      externalLinkRel: AppOptions.get("externalLinkRel"),
 | 
						|
      ignoreDestinationZoom: AppOptions.get("ignoreDestinationZoom"),
 | 
						|
    }));
 | 
						|
 | 
						|
    const downloadManager = (this.downloadManager = new DownloadManager());
 | 
						|
 | 
						|
    const findController = (this.findController = new PDFFindController({
 | 
						|
      linkService,
 | 
						|
      eventBus,
 | 
						|
      updateMatchesCountOnProgress:
 | 
						|
        typeof PDFJSDev === "undefined"
 | 
						|
          ? !window.isGECKOVIEW
 | 
						|
          : !PDFJSDev.test("GECKOVIEW"),
 | 
						|
    }));
 | 
						|
 | 
						|
    const pdfScriptingManager = (this.pdfScriptingManager =
 | 
						|
      new PDFScriptingManager({
 | 
						|
        eventBus,
 | 
						|
        externalServices,
 | 
						|
        docProperties: this._scriptingDocProperties.bind(this),
 | 
						|
      }));
 | 
						|
 | 
						|
    const container = appConfig.mainContainer,
 | 
						|
      viewer = appConfig.viewerContainer;
 | 
						|
    const annotationEditorMode = AppOptions.get("annotationEditorMode");
 | 
						|
    const hasForcedColors =
 | 
						|
      AppOptions.get("forcePageColors") ||
 | 
						|
      window.matchMedia("(forced-colors: active)").matches;
 | 
						|
    const pageColors = hasForcedColors
 | 
						|
      ? {
 | 
						|
          background: AppOptions.get("pageColorsBackground"),
 | 
						|
          foreground: AppOptions.get("pageColorsForeground"),
 | 
						|
        }
 | 
						|
      : null;
 | 
						|
 | 
						|
    let altTextManager;
 | 
						|
    if (AppOptions.get("enableUpdatedAddImage")) {
 | 
						|
      altTextManager = appConfig.newAltTextDialog
 | 
						|
        ? new NewAltTextManager(
 | 
						|
            appConfig.newAltTextDialog,
 | 
						|
            overlayManager,
 | 
						|
            eventBus
 | 
						|
          )
 | 
						|
        : null;
 | 
						|
    } else {
 | 
						|
      altTextManager = appConfig.altTextDialog
 | 
						|
        ? new AltTextManager(
 | 
						|
            appConfig.altTextDialog,
 | 
						|
            container,
 | 
						|
            overlayManager,
 | 
						|
            eventBus
 | 
						|
          )
 | 
						|
        : null;
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.editorUndoBar) {
 | 
						|
      this.editorUndoBar = new EditorUndoBar(appConfig.editorUndoBar, eventBus);
 | 
						|
    }
 | 
						|
 | 
						|
    const signatureManager =
 | 
						|
      AppOptions.get("enableSignatureEditor") && appConfig.addSignatureDialog
 | 
						|
        ? new SignatureManager(
 | 
						|
            appConfig.addSignatureDialog,
 | 
						|
            appConfig.editSignatureDialog,
 | 
						|
            appConfig.annotationEditorParams?.editorSignatureAddSignature ||
 | 
						|
              null,
 | 
						|
            overlayManager,
 | 
						|
            l10n,
 | 
						|
            externalServices.createSignatureStorage(eventBus, abortSignal),
 | 
						|
            eventBus
 | 
						|
          )
 | 
						|
        : null;
 | 
						|
 | 
						|
    const ltr = appConfig.viewerContainer
 | 
						|
      ? getComputedStyle(appConfig.viewerContainer).direction === "ltr"
 | 
						|
      : true;
 | 
						|
    const commentManager =
 | 
						|
      AppOptions.get("enableComment") && appConfig.editCommentDialog
 | 
						|
        ? new CommentManager(
 | 
						|
            appConfig.editCommentDialog,
 | 
						|
            {
 | 
						|
              learnMoreUrl: AppOptions.get("commentLearnMoreUrl"),
 | 
						|
              sidebar:
 | 
						|
                appConfig.annotationEditorParams?.editorCommentsSidebar || null,
 | 
						|
              sidebarResizer:
 | 
						|
                appConfig.annotationEditorParams
 | 
						|
                  ?.editorCommentsSidebarResizer || null,
 | 
						|
              commentsList:
 | 
						|
                appConfig.annotationEditorParams?.editorCommentsSidebarList ||
 | 
						|
                null,
 | 
						|
              commentCount:
 | 
						|
                appConfig.annotationEditorParams?.editorCommentsSidebarCount ||
 | 
						|
                null,
 | 
						|
              sidebarTitle:
 | 
						|
                appConfig.annotationEditorParams?.editorCommentsSidebarTitle ||
 | 
						|
                null,
 | 
						|
              closeButton:
 | 
						|
                appConfig.annotationEditorParams
 | 
						|
                  ?.editorCommentsSidebarCloseButton || null,
 | 
						|
              commentToolbarButton:
 | 
						|
                appConfig.toolbar?.editorCommentButton || null,
 | 
						|
            },
 | 
						|
            eventBus,
 | 
						|
            linkService,
 | 
						|
            overlayManager,
 | 
						|
            ltr,
 | 
						|
            hasForcedColors
 | 
						|
          )
 | 
						|
        : null;
 | 
						|
 | 
						|
    const enableHWA = AppOptions.get("enableHWA"),
 | 
						|
      maxCanvasPixels = AppOptions.get("maxCanvasPixels"),
 | 
						|
      maxCanvasDim = AppOptions.get("maxCanvasDim"),
 | 
						|
      capCanvasAreaFactor = AppOptions.get("capCanvasAreaFactor");
 | 
						|
    const pdfViewer = (this.pdfViewer = new PDFViewer({
 | 
						|
      container,
 | 
						|
      viewer,
 | 
						|
      viewerAlert: appConfig.viewerAlert,
 | 
						|
      eventBus,
 | 
						|
      renderingQueue,
 | 
						|
      linkService,
 | 
						|
      downloadManager,
 | 
						|
      altTextManager,
 | 
						|
      commentManager,
 | 
						|
      signatureManager,
 | 
						|
      editorUndoBar: this.editorUndoBar,
 | 
						|
      findController,
 | 
						|
      scriptingManager:
 | 
						|
        AppOptions.get("enableScripting") && pdfScriptingManager,
 | 
						|
      l10n,
 | 
						|
      textLayerMode: AppOptions.get("textLayerMode"),
 | 
						|
      annotationMode: AppOptions.get("annotationMode"),
 | 
						|
      annotationEditorMode,
 | 
						|
      annotationEditorHighlightColors: AppOptions.get("highlightEditorColors"),
 | 
						|
      enableHighlightFloatingButton: AppOptions.get(
 | 
						|
        "enableHighlightFloatingButton"
 | 
						|
      ),
 | 
						|
      enableUpdatedAddImage: AppOptions.get("enableUpdatedAddImage"),
 | 
						|
      enableNewAltTextWhenAddingImage: AppOptions.get(
 | 
						|
        "enableNewAltTextWhenAddingImage"
 | 
						|
      ),
 | 
						|
      imageResourcesPath: AppOptions.get("imageResourcesPath"),
 | 
						|
      enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
 | 
						|
      maxCanvasPixels,
 | 
						|
      maxCanvasDim,
 | 
						|
      capCanvasAreaFactor,
 | 
						|
      enableDetailCanvas: AppOptions.get("enableDetailCanvas"),
 | 
						|
      enablePermissions: AppOptions.get("enablePermissions"),
 | 
						|
      enableOptimizedPartialRendering: AppOptions.get(
 | 
						|
        "enableOptimizedPartialRendering"
 | 
						|
      ),
 | 
						|
      pageColors,
 | 
						|
      mlManager,
 | 
						|
      abortSignal,
 | 
						|
      enableHWA,
 | 
						|
      supportsPinchToZoom: this.supportsPinchToZoom,
 | 
						|
      enableAutoLinking: AppOptions.get("enableAutoLinking"),
 | 
						|
      minDurationToUpdateCanvas: AppOptions.get("minDurationToUpdateCanvas"),
 | 
						|
    }));
 | 
						|
 | 
						|
    renderingQueue.setViewer(pdfViewer);
 | 
						|
    linkService.setViewer(pdfViewer);
 | 
						|
    pdfScriptingManager.setViewer(pdfViewer);
 | 
						|
 | 
						|
    if (appConfig.sidebar?.thumbnailView) {
 | 
						|
      this.pdfThumbnailViewer = new PDFThumbnailViewer({
 | 
						|
        container: appConfig.sidebar.thumbnailView,
 | 
						|
        eventBus,
 | 
						|
        renderingQueue,
 | 
						|
        linkService,
 | 
						|
        maxCanvasPixels,
 | 
						|
        maxCanvasDim,
 | 
						|
        pageColors,
 | 
						|
        abortSignal,
 | 
						|
        enableHWA,
 | 
						|
      });
 | 
						|
      renderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
 | 
						|
    }
 | 
						|
 | 
						|
    // The browsing history is only enabled when the viewer is standalone,
 | 
						|
    // i.e. not when it is embedded in a web page.
 | 
						|
    if (!this.isViewerEmbedded && !AppOptions.get("disableHistory")) {
 | 
						|
      this.pdfHistory = new PDFHistory({
 | 
						|
        linkService,
 | 
						|
        eventBus,
 | 
						|
      });
 | 
						|
      linkService.setHistory(this.pdfHistory);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!this.supportsIntegratedFind && appConfig.findBar) {
 | 
						|
      this.findBar = new PDFFindBar(
 | 
						|
        appConfig.findBar,
 | 
						|
        appConfig.principalContainer,
 | 
						|
        eventBus
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.annotationEditorParams) {
 | 
						|
      if (annotationEditorMode !== AnnotationEditorType.DISABLE) {
 | 
						|
        const editorSignatureButton = appConfig.toolbar?.editorSignatureButton;
 | 
						|
        if (editorSignatureButton && AppOptions.get("enableSignatureEditor")) {
 | 
						|
          editorSignatureButton.parentElement.hidden = false;
 | 
						|
        }
 | 
						|
        const editorCommentButton = appConfig.toolbar?.editorCommentButton;
 | 
						|
        if (editorCommentButton && AppOptions.get("enableComment")) {
 | 
						|
          editorCommentButton.parentElement.hidden = false;
 | 
						|
        }
 | 
						|
        this.annotationEditorParams = new AnnotationEditorParams(
 | 
						|
          appConfig.annotationEditorParams,
 | 
						|
          eventBus
 | 
						|
        );
 | 
						|
      } else {
 | 
						|
        for (const id of ["editorModeButtons", "editorModeSeparator"]) {
 | 
						|
          document.getElementById(id)?.classList.add("hidden");
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (mlManager && appConfig.secondaryToolbar?.imageAltTextSettingsButton) {
 | 
						|
      this.imageAltTextSettings = new ImageAltTextSettings(
 | 
						|
        appConfig.altTextSettingsDialog,
 | 
						|
        overlayManager,
 | 
						|
        eventBus,
 | 
						|
        mlManager
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.documentProperties) {
 | 
						|
      this.pdfDocumentProperties = new PDFDocumentProperties(
 | 
						|
        appConfig.documentProperties,
 | 
						|
        overlayManager,
 | 
						|
        eventBus,
 | 
						|
        l10n,
 | 
						|
        /* fileNameLookup = */ () => this._docFilename,
 | 
						|
        /* titleLookup = */ () => this._docTitle
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    // NOTE: The cursor-tools are unlikely to be helpful/useful in GeckoView,
 | 
						|
    // in particular the `HandTool` which basically simulates touch scrolling.
 | 
						|
    if (appConfig.secondaryToolbar?.cursorHandToolButton) {
 | 
						|
      this.pdfCursorTools = new PDFCursorTools({
 | 
						|
        container,
 | 
						|
        eventBus,
 | 
						|
        cursorToolOnLoad: AppOptions.get("cursorToolOnLoad"),
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.toolbar) {
 | 
						|
      if (
 | 
						|
        typeof PDFJSDev === "undefined"
 | 
						|
          ? window.isGECKOVIEW
 | 
						|
          : PDFJSDev.test("GECKOVIEW")
 | 
						|
      ) {
 | 
						|
        const nimbusData = JSON.parse(
 | 
						|
          AppOptions.get("nimbusDataStr") || "null"
 | 
						|
        );
 | 
						|
        this.toolbar = new Toolbar(appConfig.toolbar, eventBus, nimbusData);
 | 
						|
      } else {
 | 
						|
        this.toolbar = new Toolbar(
 | 
						|
          appConfig.toolbar,
 | 
						|
          eventBus,
 | 
						|
          AppOptions.get("toolbarDensity")
 | 
						|
        );
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.secondaryToolbar) {
 | 
						|
      if (AppOptions.get("enableAltText")) {
 | 
						|
        appConfig.secondaryToolbar.imageAltTextSettingsButton?.classList.remove(
 | 
						|
          "hidden"
 | 
						|
        );
 | 
						|
        appConfig.secondaryToolbar.imageAltTextSettingsSeparator?.classList.remove(
 | 
						|
          "hidden"
 | 
						|
        );
 | 
						|
      }
 | 
						|
 | 
						|
      this.secondaryToolbar = new SecondaryToolbar(
 | 
						|
        appConfig.secondaryToolbar,
 | 
						|
        eventBus
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (
 | 
						|
      this.supportsFullscreen &&
 | 
						|
      appConfig.secondaryToolbar?.presentationModeButton
 | 
						|
    ) {
 | 
						|
      this.pdfPresentationMode = new PDFPresentationMode({
 | 
						|
        container,
 | 
						|
        pdfViewer,
 | 
						|
        eventBus,
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.passwordOverlay) {
 | 
						|
      this.passwordPrompt = new PasswordPrompt(
 | 
						|
        appConfig.passwordOverlay,
 | 
						|
        overlayManager,
 | 
						|
        this.isViewerEmbedded
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.sidebar?.outlineView) {
 | 
						|
      this.pdfOutlineViewer = new PDFOutlineViewer({
 | 
						|
        container: appConfig.sidebar.outlineView,
 | 
						|
        eventBus,
 | 
						|
        l10n,
 | 
						|
        linkService,
 | 
						|
        downloadManager,
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.sidebar?.attachmentsView) {
 | 
						|
      this.pdfAttachmentViewer = new PDFAttachmentViewer({
 | 
						|
        container: appConfig.sidebar.attachmentsView,
 | 
						|
        eventBus,
 | 
						|
        l10n,
 | 
						|
        downloadManager,
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.sidebar?.layersView) {
 | 
						|
      this.pdfLayerViewer = new PDFLayerViewer({
 | 
						|
        container: appConfig.sidebar.layersView,
 | 
						|
        eventBus,
 | 
						|
        l10n,
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (appConfig.sidebar) {
 | 
						|
      this.pdfSidebar = new PDFSidebar({
 | 
						|
        elements: appConfig.sidebar,
 | 
						|
        eventBus,
 | 
						|
        l10n,
 | 
						|
      });
 | 
						|
      this.pdfSidebar.onToggled = this.forceRendering.bind(this);
 | 
						|
      this.pdfSidebar.onUpdateThumbnails = () => {
 | 
						|
        // Use the rendered pages to set the corresponding thumbnail images.
 | 
						|
        for (const pageView of pdfViewer.getCachedPageViews()) {
 | 
						|
          if (pageView.renderingState === RenderingStates.FINISHED) {
 | 
						|
            this.pdfThumbnailViewer
 | 
						|
              .getThumbnail(pageView.id - 1)
 | 
						|
              ?.setImage(pageView);
 | 
						|
          }
 | 
						|
        }
 | 
						|
        this.pdfThumbnailViewer.scrollThumbnailIntoView(
 | 
						|
          pdfViewer.currentPageNumber
 | 
						|
        );
 | 
						|
      };
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  async run(config) {
 | 
						|
    await this.initialize(config);
 | 
						|
 | 
						|
    const { appConfig, eventBus } = this;
 | 
						|
    let file;
 | 
						|
    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
      const queryString = document.location.search.substring(1);
 | 
						|
      const params = parseQueryString(queryString);
 | 
						|
      file = params.get("file") ?? AppOptions.get("defaultUrl");
 | 
						|
      try {
 | 
						|
        file = new URL(decodeURIComponent(file)).href;
 | 
						|
      } catch {
 | 
						|
        file = encodeURIComponent(file).replaceAll("%2F", "/");
 | 
						|
      }
 | 
						|
      validateFileURL(file);
 | 
						|
    } else if (PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
      file = window.location.href;
 | 
						|
    } else if (PDFJSDev.test("CHROME")) {
 | 
						|
      file = AppOptions.get("defaultUrl");
 | 
						|
    }
 | 
						|
 | 
						|
    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
      const fileInput = (this._openFileInput = document.createElement("input"));
 | 
						|
      fileInput.id = "fileInput";
 | 
						|
      fileInput.hidden = true;
 | 
						|
      fileInput.type = "file";
 | 
						|
      fileInput.value = null;
 | 
						|
      document.body.append(fileInput);
 | 
						|
 | 
						|
      fileInput.addEventListener("change", function (evt) {
 | 
						|
        const { files } = evt.target;
 | 
						|
        if (!files || files.length === 0) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
        eventBus.dispatch("fileinputchange", {
 | 
						|
          source: this,
 | 
						|
          fileInput: evt.target,
 | 
						|
        });
 | 
						|
      });
 | 
						|
 | 
						|
      // Enable dragging-and-dropping a new PDF file onto the viewerContainer.
 | 
						|
      appConfig.mainContainer.addEventListener("dragover", function (evt) {
 | 
						|
        for (const item of evt.dataTransfer.items) {
 | 
						|
          if (item.type === "application/pdf") {
 | 
						|
            evt.dataTransfer.dropEffect =
 | 
						|
              evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move";
 | 
						|
            stopEvent(evt);
 | 
						|
            return;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      });
 | 
						|
      appConfig.mainContainer.addEventListener("drop", function (evt) {
 | 
						|
        if (evt.dataTransfer.files?.[0].type !== "application/pdf") {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
        stopEvent(evt);
 | 
						|
        eventBus.dispatch("fileinputchange", {
 | 
						|
          source: this,
 | 
						|
          fileInput: evt.dataTransfer,
 | 
						|
        });
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (!AppOptions.get("supportsDocumentFonts")) {
 | 
						|
      AppOptions.set("disableFontFace", true);
 | 
						|
      this.l10n.get("pdfjs-web-fonts-disabled").then(msg => {
 | 
						|
        console.warn(msg);
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    const togglePrintingButtons = visible => {
 | 
						|
      appConfig.toolbar?.print?.classList.toggle("hidden", !visible);
 | 
						|
      appConfig.secondaryToolbar?.printButton.classList.toggle(
 | 
						|
        "hidden",
 | 
						|
        !visible
 | 
						|
      );
 | 
						|
    };
 | 
						|
    if (!this.supportsPrinting) {
 | 
						|
      togglePrintingButtons(false);
 | 
						|
    } else {
 | 
						|
      eventBus.on("printingallowed", ({ isAllowed }) =>
 | 
						|
        togglePrintingButtons(isAllowed)
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (!this.supportsFullscreen) {
 | 
						|
      appConfig.secondaryToolbar?.presentationModeButton.classList.add(
 | 
						|
        "hidden"
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (this.supportsIntegratedFind) {
 | 
						|
      appConfig.findBar?.toggleButton?.classList.add("hidden");
 | 
						|
    }
 | 
						|
 | 
						|
    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
      if (file) {
 | 
						|
        this.open({ url: file });
 | 
						|
      } else {
 | 
						|
        this._hideViewBookmark();
 | 
						|
      }
 | 
						|
    } else if (PDFJSDev.test("MOZCENTRAL || CHROME")) {
 | 
						|
      this.setTitleUsingUrl(file, /* downloadUrl = */ file);
 | 
						|
 | 
						|
      this.externalServices.initPassiveLoading();
 | 
						|
    } else {
 | 
						|
      throw new Error("Not implemented: run");
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  get externalServices() {
 | 
						|
    return shadow(this, "externalServices", new ExternalServices());
 | 
						|
  },
 | 
						|
 | 
						|
  get initialized() {
 | 
						|
    return this._initializedCapability.settled;
 | 
						|
  },
 | 
						|
 | 
						|
  get initializedPromise() {
 | 
						|
    return this._initializedCapability.promise;
 | 
						|
  },
 | 
						|
 | 
						|
  updateZoom(steps, scaleFactor, origin) {
 | 
						|
    if (this.pdfViewer.isInPresentationMode) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    this.pdfViewer.updateScale({
 | 
						|
      drawingDelay: AppOptions.get("defaultZoomDelay"),
 | 
						|
      steps,
 | 
						|
      scaleFactor,
 | 
						|
      origin,
 | 
						|
    });
 | 
						|
  },
 | 
						|
 | 
						|
  zoomIn() {
 | 
						|
    this.updateZoom(1);
 | 
						|
  },
 | 
						|
 | 
						|
  zoomOut() {
 | 
						|
    this.updateZoom(-1);
 | 
						|
  },
 | 
						|
 | 
						|
  zoomReset() {
 | 
						|
    if (this.pdfViewer.isInPresentationMode) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    this.pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;
 | 
						|
  },
 | 
						|
 | 
						|
  touchPinchCallback(origin, prevDistance, distance) {
 | 
						|
    if (this.supportsPinchToZoom) {
 | 
						|
      const newScaleFactor = this._accumulateFactor(
 | 
						|
        this.pdfViewer.currentScale,
 | 
						|
        distance / prevDistance,
 | 
						|
        "_touchUnusedFactor"
 | 
						|
      );
 | 
						|
      this.updateZoom(null, newScaleFactor, origin);
 | 
						|
    } else {
 | 
						|
      const PIXELS_PER_LINE_SCALE = 30;
 | 
						|
      const ticks = this._accumulateTicks(
 | 
						|
        (distance - prevDistance) / PIXELS_PER_LINE_SCALE,
 | 
						|
        "_touchUnusedTicks"
 | 
						|
      );
 | 
						|
      this.updateZoom(ticks, null, origin);
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  touchPinchEndCallback() {
 | 
						|
    this._touchUnusedTicks = 0;
 | 
						|
    this._touchUnusedFactor = 1;
 | 
						|
  },
 | 
						|
 | 
						|
  get pagesCount() {
 | 
						|
    return this.pdfDocument ? this.pdfDocument.numPages : 0;
 | 
						|
  },
 | 
						|
 | 
						|
  get page() {
 | 
						|
    return this.pdfViewer.currentPageNumber;
 | 
						|
  },
 | 
						|
 | 
						|
  set page(val) {
 | 
						|
    this.pdfViewer.currentPageNumber = val;
 | 
						|
  },
 | 
						|
 | 
						|
  get supportsPrinting() {
 | 
						|
    return shadow(
 | 
						|
      this,
 | 
						|
      "supportsPrinting",
 | 
						|
      AppOptions.get("supportsPrinting") &&
 | 
						|
        PDFPrintServiceFactory.supportsPrinting
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  get supportsFullscreen() {
 | 
						|
    return shadow(this, "supportsFullscreen", document.fullscreenEnabled);
 | 
						|
  },
 | 
						|
 | 
						|
  get supportsPinchToZoom() {
 | 
						|
    return shadow(
 | 
						|
      this,
 | 
						|
      "supportsPinchToZoom",
 | 
						|
      AppOptions.get("supportsPinchToZoom")
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  get supportsIntegratedFind() {
 | 
						|
    return shadow(
 | 
						|
      this,
 | 
						|
      "supportsIntegratedFind",
 | 
						|
      AppOptions.get("supportsIntegratedFind")
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  get loadingBar() {
 | 
						|
    const barElement = document.getElementById("loadingBar");
 | 
						|
    const bar = barElement ? new ProgressBar(barElement) : null;
 | 
						|
    return shadow(this, "loadingBar", bar);
 | 
						|
  },
 | 
						|
 | 
						|
  get supportsMouseWheelZoomCtrlKey() {
 | 
						|
    return shadow(
 | 
						|
      this,
 | 
						|
      "supportsMouseWheelZoomCtrlKey",
 | 
						|
      AppOptions.get("supportsMouseWheelZoomCtrlKey")
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  get supportsMouseWheelZoomMetaKey() {
 | 
						|
    return shadow(
 | 
						|
      this,
 | 
						|
      "supportsMouseWheelZoomMetaKey",
 | 
						|
      AppOptions.get("supportsMouseWheelZoomMetaKey")
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  get supportsCaretBrowsingMode() {
 | 
						|
    return AppOptions.get("supportsCaretBrowsingMode");
 | 
						|
  },
 | 
						|
 | 
						|
  moveCaret(isUp, select) {
 | 
						|
    this._caretBrowsing ||= new CaretBrowsingMode(
 | 
						|
      this._globalAbortController.signal,
 | 
						|
      this.appConfig.mainContainer,
 | 
						|
      this.appConfig.viewerContainer,
 | 
						|
      this.appConfig.toolbar?.container
 | 
						|
    );
 | 
						|
    this._caretBrowsing.moveCaret(isUp, select);
 | 
						|
  },
 | 
						|
 | 
						|
  setTitleUsingUrl(url = "", downloadUrl = null) {
 | 
						|
    this.url = url;
 | 
						|
    this.baseUrl =
 | 
						|
      typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")
 | 
						|
        ? updateUrlHash(url, "", /* allowRel = */ true)
 | 
						|
        : updateUrlHash(url, "");
 | 
						|
    if (downloadUrl) {
 | 
						|
      this._downloadUrl =
 | 
						|
        // eslint-disable-next-line no-nested-ternary
 | 
						|
        downloadUrl === url
 | 
						|
          ? this.baseUrl
 | 
						|
          : typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")
 | 
						|
            ? updateUrlHash(downloadUrl, "", /* allowRel = */ true)
 | 
						|
            : updateUrlHash(downloadUrl, "");
 | 
						|
    }
 | 
						|
    if (isDataScheme(url)) {
 | 
						|
      this._hideViewBookmark();
 | 
						|
    } else if (
 | 
						|
      typeof PDFJSDev !== "undefined" &&
 | 
						|
      PDFJSDev.test("MOZCENTRAL || CHROME")
 | 
						|
    ) {
 | 
						|
      AppOptions.set("docBaseUrl", this.baseUrl);
 | 
						|
    }
 | 
						|
 | 
						|
    let title = getPdfFilenameFromUrl(url, "");
 | 
						|
    if (!title) {
 | 
						|
      try {
 | 
						|
        title = decodeURIComponent(getFilenameFromUrl(url));
 | 
						|
      } catch {
 | 
						|
        // decodeURIComponent may throw URIError.
 | 
						|
      }
 | 
						|
    }
 | 
						|
    this.setTitle(title || url); // Always fallback to the raw URL.
 | 
						|
  },
 | 
						|
 | 
						|
  setTitle(title = this._title) {
 | 
						|
    this._title = title;
 | 
						|
 | 
						|
    if (this.isViewerEmbedded) {
 | 
						|
      // Embedded PDF viewers should not be changing their parent page's title.
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const editorIndicator =
 | 
						|
      this._hasAnnotationEditors && !this.pdfRenderingQueue.printing;
 | 
						|
    // document.title = `${editorIndicator ? "* " : ""}${title}`;
 | 
						|
      const urlParams = new URLSearchParams(window.location.search);
 | 
						|
      const originalUrl = urlParams.get('original_url');
 | 
						|
      console.log("set title to "+originalUrl)
 | 
						|
      document.title = originalUrl || 'PDF.js viewer with VimiumC';
 | 
						|
  },
 | 
						|
 | 
						|
  get _docFilename() {
 | 
						|
    // Use `this.url` instead of `this.baseUrl` to perform filename detection
 | 
						|
    // based on the reference fragment as ultimate fallback if needed.
 | 
						|
    return this._contentDispositionFilename || getPdfFilenameFromUrl(this.url);
 | 
						|
  },
 | 
						|
 | 
						|
  get _docTitle() {
 | 
						|
    const { documentInfo, metadata } = this;
 | 
						|
 | 
						|
    const title = metadata?.get("dc:title");
 | 
						|
    if (title) {
 | 
						|
      // Ghostscript can produce invalid 'dc:title' Metadata entries:
 | 
						|
      //  - The title may be "Untitled" (fixes bug 1031612).
 | 
						|
      //  - The title may contain incorrectly encoded characters, which thus
 | 
						|
      //    looks broken, hence we ignore the Metadata entry when it contains
 | 
						|
      //    characters from the Specials Unicode block (fixes bug 1605526).
 | 
						|
      if (title !== "Untitled" && !/[\uFFF0-\uFFFF]/g.test(title)) {
 | 
						|
        return title;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return documentInfo.Title;
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  _hideViewBookmark() {
 | 
						|
    const { secondaryToolbar } = this.appConfig;
 | 
						|
    // URL does not reflect proper document location - hiding some buttons.
 | 
						|
    secondaryToolbar?.viewBookmarkButton.classList.add("hidden");
 | 
						|
 | 
						|
    // Avoid displaying multiple consecutive separators in the secondaryToolbar.
 | 
						|
    if (secondaryToolbar?.presentationModeButton.classList.contains("hidden")) {
 | 
						|
      document.getElementById("viewBookmarkSeparator")?.classList.add("hidden");
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Closes opened PDF document.
 | 
						|
   * @returns {Promise} - Returns the promise, which is resolved when all
 | 
						|
   *                      destruction is completed.
 | 
						|
   */
 | 
						|
  async close() {
 | 
						|
    this._unblockDocumentLoadEvent();
 | 
						|
    this._hideViewBookmark();
 | 
						|
 | 
						|
    if (!this.pdfLoadingTask) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (
 | 
						|
      (typeof PDFJSDev === "undefined" ||
 | 
						|
        PDFJSDev.test("GENERIC && !TESTING")) &&
 | 
						|
      this.pdfDocument?.annotationStorage.size > 0 &&
 | 
						|
      this._annotationStorageModified
 | 
						|
    ) {
 | 
						|
      try {
 | 
						|
        // Trigger saving, to prevent data loss in forms; see issue 12257.
 | 
						|
        await this.save();
 | 
						|
      } catch {
 | 
						|
        // Ignoring errors, to ensure that document closing won't break.
 | 
						|
      }
 | 
						|
    }
 | 
						|
    const promises = [];
 | 
						|
 | 
						|
    promises.push(this.pdfLoadingTask.destroy());
 | 
						|
    this.pdfLoadingTask = null;
 | 
						|
 | 
						|
    if (this.pdfDocument) {
 | 
						|
      this.pdfDocument = null;
 | 
						|
 | 
						|
      this.pdfThumbnailViewer?.setDocument(null);
 | 
						|
      this.pdfViewer.setDocument(null);
 | 
						|
      this.pdfLinkService.setDocument(null);
 | 
						|
      this.pdfDocumentProperties?.setDocument(null);
 | 
						|
    }
 | 
						|
    this.pdfLinkService.externalLinkEnabled = true;
 | 
						|
    this.store = null;
 | 
						|
    this.isInitialViewSet = false;
 | 
						|
    this.url = "";
 | 
						|
    this.baseUrl = "";
 | 
						|
    this._downloadUrl = "";
 | 
						|
    this.documentInfo = null;
 | 
						|
    this.metadata = null;
 | 
						|
    this._contentDispositionFilename = null;
 | 
						|
    this._contentLength = null;
 | 
						|
    this._saveInProgress = false;
 | 
						|
    this._hasAnnotationEditors = false;
 | 
						|
 | 
						|
    promises.push(
 | 
						|
      this.pdfScriptingManager.destroyPromise,
 | 
						|
      this.passwordPrompt.close()
 | 
						|
    );
 | 
						|
 | 
						|
    this.setTitle();
 | 
						|
    this.pdfSidebar?.reset();
 | 
						|
    this.pdfOutlineViewer?.reset();
 | 
						|
    this.pdfAttachmentViewer?.reset();
 | 
						|
    this.pdfLayerViewer?.reset();
 | 
						|
 | 
						|
    this.pdfHistory?.reset();
 | 
						|
    this.findBar?.reset();
 | 
						|
    this.toolbar?.reset();
 | 
						|
    this.secondaryToolbar?.reset();
 | 
						|
    this._PDFBug?.cleanup();
 | 
						|
 | 
						|
    await Promise.all(promises);
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Opens a new PDF document.
 | 
						|
   * @param {Object} args - Accepts any/all of the properties from
 | 
						|
   *   {@link DocumentInitParameters}, and also a `originalUrl` string.
 | 
						|
   * @returns {Promise} - Promise that is resolved when the document is opened.
 | 
						|
   */
 | 
						|
  async open(args) {
 | 
						|
    if (this.pdfLoadingTask) {
 | 
						|
      // We need to destroy already opened document.
 | 
						|
      await this.close();
 | 
						|
    }
 | 
						|
    // Set the necessary global worker parameters, using the available options.
 | 
						|
    const workerParams = AppOptions.getAll(OptionKind.WORKER);
 | 
						|
    Object.assign(GlobalWorkerOptions, workerParams);
 | 
						|
 | 
						|
    if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
      if (args.data && isPdfFile(args.filename)) {
 | 
						|
        this._contentDispositionFilename = args.filename;
 | 
						|
      }
 | 
						|
    } else if (args.url) {
 | 
						|
      // The Firefox built-in viewer always calls `setTitleUsingUrl`, before
 | 
						|
      // `initPassiveLoading`, and it never provides an `originalUrl` here.
 | 
						|
      this.setTitleUsingUrl(
 | 
						|
        args.originalUrl || args.url,
 | 
						|
        /* downloadUrl = */ args.url
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    // Set the necessary API parameters, using all the available options.
 | 
						|
    const apiParams = AppOptions.getAll(OptionKind.API);
 | 
						|
    const loadingTask = getDocument({
 | 
						|
      ...apiParams,
 | 
						|
      ...args,
 | 
						|
    });
 | 
						|
    this.pdfLoadingTask = loadingTask;
 | 
						|
 | 
						|
    loadingTask.onPassword = (updateCallback, reason) => {
 | 
						|
      if (this.isViewerEmbedded) {
 | 
						|
        // The load event can't be triggered until the password is entered, so
 | 
						|
        // if the viewer is in an iframe and its visibility depends on the
 | 
						|
        // onload callback then the viewer never shows (bug 1801341).
 | 
						|
        this._unblockDocumentLoadEvent();
 | 
						|
      }
 | 
						|
 | 
						|
      this.pdfLinkService.externalLinkEnabled = false;
 | 
						|
      this.passwordPrompt.setUpdateCallback(updateCallback, reason);
 | 
						|
      this.passwordPrompt.open();
 | 
						|
    };
 | 
						|
 | 
						|
    loadingTask.onProgress = ({ loaded, total }) => {
 | 
						|
      this.progress(loaded / total);
 | 
						|
    };
 | 
						|
 | 
						|
    return loadingTask.promise.then(
 | 
						|
      pdfDocument => {
 | 
						|
        this.load(pdfDocument);
 | 
						|
      },
 | 
						|
      reason => {
 | 
						|
        if (loadingTask !== this.pdfLoadingTask) {
 | 
						|
          return undefined; // Ignore errors for previously opened PDF files.
 | 
						|
        }
 | 
						|
 | 
						|
        let key = "pdfjs-loading-error";
 | 
						|
        if (reason instanceof InvalidPDFException) {
 | 
						|
          key = "pdfjs-invalid-file-error";
 | 
						|
        } else if (reason instanceof ResponseException) {
 | 
						|
          key = reason.missing
 | 
						|
            ? "pdfjs-missing-file-error"
 | 
						|
            : "pdfjs-unexpected-response-error";
 | 
						|
        }
 | 
						|
        return this._documentError(key, { message: reason.message }).then(
 | 
						|
          () => {
 | 
						|
            throw reason;
 | 
						|
          }
 | 
						|
        );
 | 
						|
      }
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  async download() {
 | 
						|
    let data;
 | 
						|
    try {
 | 
						|
      data = await (this.pdfDocument
 | 
						|
        ? this.pdfDocument.getData()
 | 
						|
        : this.pdfLoadingTask.getData());
 | 
						|
    } catch {
 | 
						|
      // When the PDF document isn't ready, simply download using the URL.
 | 
						|
    }
 | 
						|
    this.downloadManager.download(data, this._downloadUrl, this._docFilename);
 | 
						|
  },
 | 
						|
 | 
						|
  async save() {
 | 
						|
    if (this._saveInProgress) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    this._saveInProgress = true;
 | 
						|
    await this.pdfScriptingManager.dispatchWillSave();
 | 
						|
 | 
						|
    try {
 | 
						|
      const data = await this.pdfDocument.saveDocument();
 | 
						|
      this.downloadManager.download(data, this._downloadUrl, this._docFilename);
 | 
						|
    } catch (reason) {
 | 
						|
      // When the PDF document isn't ready, fallback to a "regular" download.
 | 
						|
      console.error(`Error when saving the document:`, reason);
 | 
						|
      await this.download();
 | 
						|
    } finally {
 | 
						|
      await this.pdfScriptingManager.dispatchDidSave();
 | 
						|
      this._saveInProgress = false;
 | 
						|
    }
 | 
						|
 | 
						|
    const editorStats = this.pdfDocument?.annotationStorage.editorStats;
 | 
						|
    if (editorStats) {
 | 
						|
      this.externalServices.reportTelemetry({
 | 
						|
        type: "editing",
 | 
						|
        data: {
 | 
						|
          type: "save",
 | 
						|
          stats: editorStats,
 | 
						|
        },
 | 
						|
      });
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  async downloadOrSave() {
 | 
						|
    // In the Firefox case, this method MUST always trigger a download.
 | 
						|
    // When the user is closing a modified and unsaved document, we display a
 | 
						|
    // prompt asking for saving or not. In case they save, we must wait for
 | 
						|
    // saving to complete before closing the tab.
 | 
						|
    // So in case this function does not trigger a download, we must trigger a
 | 
						|
    // a message and change PdfjsChild.sys.mjs to take it into account.
 | 
						|
    const { classList } = this.appConfig.appContainer;
 | 
						|
    classList.add("wait");
 | 
						|
    await (this.pdfDocument?.annotationStorage.size > 0
 | 
						|
      ? this.save()
 | 
						|
      : this.download());
 | 
						|
    classList.remove("wait");
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Report the error; used for errors affecting loading and/or parsing of
 | 
						|
   * the entire PDF document.
 | 
						|
   */
 | 
						|
  async _documentError(key, moreInfo = null) {
 | 
						|
    this._unblockDocumentLoadEvent();
 | 
						|
 | 
						|
    const message = await this._otherError(
 | 
						|
      key || "pdfjs-loading-error",
 | 
						|
      moreInfo
 | 
						|
    );
 | 
						|
 | 
						|
    this.eventBus.dispatch("documenterror", {
 | 
						|
      source: this,
 | 
						|
      message,
 | 
						|
      reason: moreInfo?.message ?? null,
 | 
						|
    });
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Report the error; used for errors affecting e.g. only a single page.
 | 
						|
   * @param {string} key - The localization key for the error.
 | 
						|
   * @param {Object} [moreInfo] - Further information about the error that is
 | 
						|
   *                              more technical. Should have a 'message' and
 | 
						|
   *                              optionally a 'stack' property.
 | 
						|
   * @returns {string} A (localized) error message that is human readable.
 | 
						|
   */
 | 
						|
  async _otherError(key, moreInfo = null) {
 | 
						|
    const message = await this.l10n.get(key);
 | 
						|
 | 
						|
    const moreInfoText = [`PDF.js v${version || "?"} (build: ${build || "?"})`];
 | 
						|
    if (moreInfo) {
 | 
						|
      moreInfoText.push(`Message: ${moreInfo.message}`);
 | 
						|
 | 
						|
      if (moreInfo.stack) {
 | 
						|
        moreInfoText.push(`Stack: ${moreInfo.stack}`);
 | 
						|
      } else {
 | 
						|
        if (moreInfo.filename) {
 | 
						|
          moreInfoText.push(`File: ${moreInfo.filename}`);
 | 
						|
        }
 | 
						|
        if (moreInfo.lineNumber) {
 | 
						|
          moreInfoText.push(`Line: ${moreInfo.lineNumber}`);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    console.error(`${message}\n\n${moreInfoText.join("\n")}`);
 | 
						|
    return message;
 | 
						|
  },
 | 
						|
 | 
						|
  progress(level) {
 | 
						|
    const percent = Math.round(level * 100);
 | 
						|
    // When we transition from full request to range requests, it's possible
 | 
						|
    // that we discard some of the loaded data. This can cause the loading
 | 
						|
    // bar to move backwards. So prevent this by only updating the bar if it
 | 
						|
    // increases.
 | 
						|
    if (!this.loadingBar || percent <= this.loadingBar.percent) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    this.loadingBar.percent = percent;
 | 
						|
 | 
						|
    // When disableAutoFetch is enabled, it's not uncommon for the entire file
 | 
						|
    // to never be fetched (depends on e.g. the file structure). In this case
 | 
						|
    // the loading bar will not be completely filled, nor will it be hidden.
 | 
						|
    // To prevent displaying a partially filled loading bar permanently, we
 | 
						|
    // hide it when no data has been loaded during a certain amount of time.
 | 
						|
    if (
 | 
						|
      this.pdfDocument?.loadingParams.disableAutoFetch ??
 | 
						|
      AppOptions.get("disableAutoFetch")
 | 
						|
    ) {
 | 
						|
      this.loadingBar.setDisableAutoFetch();
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  load(pdfDocument) {
 | 
						|
    this.pdfDocument = pdfDocument;
 | 
						|
 | 
						|
    this._printPermissionPromise = new Promise(resolve => {
 | 
						|
      this.eventBus.on(
 | 
						|
        "printingallowed",
 | 
						|
        ({ isAllowed }) => {
 | 
						|
          if (
 | 
						|
            typeof PDFJSDev !== "undefined" &&
 | 
						|
            PDFJSDev.test("MOZCENTRAL") &&
 | 
						|
            !isAllowed
 | 
						|
          ) {
 | 
						|
            window.print = () => {
 | 
						|
              console.warn("Printing is not allowed.");
 | 
						|
            };
 | 
						|
          }
 | 
						|
          resolve(isAllowed);
 | 
						|
        },
 | 
						|
        { once: true }
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    pdfDocument.getDownloadInfo().then(({ length }) => {
 | 
						|
      this._contentLength = length; // Ensure that the correct length is used.
 | 
						|
      this.loadingBar?.hide();
 | 
						|
 | 
						|
      firstPagePromise.then(() => {
 | 
						|
        this.eventBus.dispatch("documentloaded", { source: this });
 | 
						|
      });
 | 
						|
    });
 | 
						|
 | 
						|
    // Since the `setInitialView` call below depends on this being resolved,
 | 
						|
    // fetch it early to avoid delaying initial rendering of the PDF document.
 | 
						|
    const pageLayoutPromise = pdfDocument.getPageLayout().catch(() => {
 | 
						|
      /* Avoid breaking initial rendering; ignoring errors. */
 | 
						|
    });
 | 
						|
    const pageModePromise = pdfDocument.getPageMode().catch(() => {
 | 
						|
      /* Avoid breaking initial rendering; ignoring errors. */
 | 
						|
    });
 | 
						|
    const openActionPromise = pdfDocument.getOpenAction().catch(() => {
 | 
						|
      /* Avoid breaking initial rendering; ignoring errors. */
 | 
						|
    });
 | 
						|
 | 
						|
    this.toolbar?.setPagesCount(pdfDocument.numPages, false);
 | 
						|
    this.secondaryToolbar?.setPagesCount(pdfDocument.numPages);
 | 
						|
 | 
						|
    if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) {
 | 
						|
      const baseUrl = updateUrlHash(location, "");
 | 
						|
      // Ignore "data:"-URLs for performance reasons, even though it may cause
 | 
						|
      // internal links to not work perfectly in all cases (see bug 1803050).
 | 
						|
      this.pdfLinkService.setDocument(
 | 
						|
        pdfDocument,
 | 
						|
        isDataScheme(baseUrl) ? null : baseUrl
 | 
						|
      );
 | 
						|
    } else {
 | 
						|
      this.pdfLinkService.setDocument(pdfDocument);
 | 
						|
    }
 | 
						|
    this.pdfDocumentProperties?.setDocument(pdfDocument);
 | 
						|
 | 
						|
    const pdfViewer = this.pdfViewer;
 | 
						|
    pdfViewer.setDocument(pdfDocument);
 | 
						|
    const { firstPagePromise, onePageRendered, pagesPromise } = pdfViewer;
 | 
						|
 | 
						|
    this.pdfThumbnailViewer?.setDocument(pdfDocument);
 | 
						|
 | 
						|
    const storedPromise = (this.store = new ViewHistory(
 | 
						|
      pdfDocument.fingerprints[0]
 | 
						|
    ))
 | 
						|
      .getMultiple({
 | 
						|
        page: null,
 | 
						|
        zoom: DEFAULT_SCALE_VALUE,
 | 
						|
        scrollLeft: "0",
 | 
						|
        scrollTop: "0",
 | 
						|
        rotation: null,
 | 
						|
        sidebarView: SidebarView.UNKNOWN,
 | 
						|
        scrollMode: ScrollMode.UNKNOWN,
 | 
						|
        spreadMode: SpreadMode.UNKNOWN,
 | 
						|
      })
 | 
						|
      .catch(() => {
 | 
						|
        /* Unable to read from storage; ignoring errors. */
 | 
						|
      });
 | 
						|
 | 
						|
    firstPagePromise.then(pdfPage => {
 | 
						|
      this.loadingBar?.setWidth(this.appConfig.viewerContainer);
 | 
						|
      this._initializeAnnotationStorageCallbacks(pdfDocument);
 | 
						|
 | 
						|
      Promise.all([
 | 
						|
        animationStarted,
 | 
						|
        storedPromise,
 | 
						|
        pageLayoutPromise,
 | 
						|
        pageModePromise,
 | 
						|
        openActionPromise,
 | 
						|
      ])
 | 
						|
        .then(async ([timeStamp, stored, pageLayout, pageMode, openAction]) => {
 | 
						|
          const viewOnLoad = AppOptions.get("viewOnLoad");
 | 
						|
 | 
						|
          this._initializePdfHistory({
 | 
						|
            fingerprint: pdfDocument.fingerprints[0],
 | 
						|
            viewOnLoad,
 | 
						|
            initialDest: openAction?.dest,
 | 
						|
          });
 | 
						|
          const initialBookmark = this.initialBookmark;
 | 
						|
 | 
						|
          // Initialize the default values, from user preferences.
 | 
						|
          const zoom = AppOptions.get("defaultZoomValue");
 | 
						|
          let hash = zoom ? `zoom=${zoom}` : null;
 | 
						|
 | 
						|
          let rotation = null;
 | 
						|
          let sidebarView = AppOptions.get("sidebarViewOnLoad");
 | 
						|
          let scrollMode = AppOptions.get("scrollModeOnLoad");
 | 
						|
          let spreadMode = AppOptions.get("spreadModeOnLoad");
 | 
						|
 | 
						|
          if (stored?.page && viewOnLoad !== ViewOnLoad.INITIAL) {
 | 
						|
            hash =
 | 
						|
              `page=${stored.page}&zoom=${zoom || stored.zoom},` +
 | 
						|
              `${stored.scrollLeft},${stored.scrollTop}`;
 | 
						|
 | 
						|
            rotation = parseInt(stored.rotation, 10);
 | 
						|
            // Always let user preference take precedence over the view history.
 | 
						|
            if (sidebarView === SidebarView.UNKNOWN) {
 | 
						|
              sidebarView = stored.sidebarView | 0;
 | 
						|
            }
 | 
						|
            if (scrollMode === ScrollMode.UNKNOWN) {
 | 
						|
              scrollMode = stored.scrollMode | 0;
 | 
						|
            }
 | 
						|
            if (spreadMode === SpreadMode.UNKNOWN) {
 | 
						|
              spreadMode = stored.spreadMode | 0;
 | 
						|
            }
 | 
						|
          }
 | 
						|
          // Always let the user preference/view history take precedence.
 | 
						|
          if (pageMode && sidebarView === SidebarView.UNKNOWN) {
 | 
						|
            sidebarView = apiPageModeToSidebarView(pageMode);
 | 
						|
          }
 | 
						|
          if (
 | 
						|
            pageLayout &&
 | 
						|
            scrollMode === ScrollMode.UNKNOWN &&
 | 
						|
            spreadMode === SpreadMode.UNKNOWN
 | 
						|
          ) {
 | 
						|
            const modes = apiPageLayoutToViewerModes(pageLayout);
 | 
						|
            // TODO: Try to improve page-switching when using the mouse-wheel
 | 
						|
            // and/or arrow-keys before allowing the document to control this.
 | 
						|
            // scrollMode = modes.scrollMode;
 | 
						|
            spreadMode = modes.spreadMode;
 | 
						|
          }
 | 
						|
 | 
						|
          this.setInitialView(hash, {
 | 
						|
            rotation,
 | 
						|
            sidebarView,
 | 
						|
            scrollMode,
 | 
						|
            spreadMode,
 | 
						|
          });
 | 
						|
          this.eventBus.dispatch("documentinit", { source: this });
 | 
						|
 | 
						|
          // For documents with different page sizes, once all pages are
 | 
						|
          // resolved, ensure that the correct location becomes visible on load.
 | 
						|
          // (To reduce the risk, in very large and/or slow loading documents,
 | 
						|
          //  that the location changes *after* the user has started interacting
 | 
						|
          //  with the viewer, wait for either `pagesPromise` or a timeout.)
 | 
						|
          await Promise.race([
 | 
						|
            pagesPromise,
 | 
						|
            new Promise(resolve => {
 | 
						|
              setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT);
 | 
						|
            }),
 | 
						|
          ]);
 | 
						|
          if (!initialBookmark && !hash) {
 | 
						|
            return;
 | 
						|
          }
 | 
						|
          if (pdfViewer.hasEqualPageSizes) {
 | 
						|
            return;
 | 
						|
          }
 | 
						|
          this.initialBookmark = initialBookmark;
 | 
						|
 | 
						|
          // eslint-disable-next-line no-self-assign
 | 
						|
          pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;
 | 
						|
          // Re-apply the initial document location.
 | 
						|
          this.setInitialView(hash);
 | 
						|
        })
 | 
						|
        .catch(() => {
 | 
						|
          // Ensure that the document is always completely initialized,
 | 
						|
          // even if there are any errors thrown above.
 | 
						|
          this.setInitialView();
 | 
						|
        })
 | 
						|
        .then(function () {
 | 
						|
          // At this point, rendering of the initial page(s) should always have
 | 
						|
          // started (and may even have completed).
 | 
						|
          // To prevent any future issues, e.g. the document being completely
 | 
						|
          // blank on load, always trigger rendering here.
 | 
						|
          pdfViewer.update();
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    pagesPromise.then(
 | 
						|
      () => {
 | 
						|
        this._unblockDocumentLoadEvent();
 | 
						|
 | 
						|
        this._initializeAutoPrint(pdfDocument, openActionPromise);
 | 
						|
      },
 | 
						|
      reason => {
 | 
						|
        this._documentError("pdfjs-loading-error", { message: reason.message });
 | 
						|
      }
 | 
						|
    );
 | 
						|
 | 
						|
    onePageRendered.then(data => {
 | 
						|
      this.externalServices.reportTelemetry({
 | 
						|
        type: "pageInfo",
 | 
						|
        timestamp: data.timestamp,
 | 
						|
      });
 | 
						|
 | 
						|
      if (this.pdfOutlineViewer) {
 | 
						|
        pdfDocument.getOutline().then(outline => {
 | 
						|
          if (pdfDocument !== this.pdfDocument) {
 | 
						|
            return; // The document was closed while the outline resolved.
 | 
						|
          }
 | 
						|
          this.pdfOutlineViewer.render({ outline, pdfDocument });
 | 
						|
        });
 | 
						|
      }
 | 
						|
      if (this.pdfAttachmentViewer) {
 | 
						|
        pdfDocument.getAttachments().then(attachments => {
 | 
						|
          if (pdfDocument !== this.pdfDocument) {
 | 
						|
            return; // The document was closed while the attachments resolved.
 | 
						|
          }
 | 
						|
          this.pdfAttachmentViewer.render({ attachments });
 | 
						|
        });
 | 
						|
      }
 | 
						|
      if (this.pdfLayerViewer) {
 | 
						|
        // Ensure that the layers accurately reflects the current state in the
 | 
						|
        // viewer itself, rather than the default state provided by the API.
 | 
						|
        pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => {
 | 
						|
          if (pdfDocument !== this.pdfDocument) {
 | 
						|
            return; // The document was closed while the layers resolved.
 | 
						|
          }
 | 
						|
          this.pdfLayerViewer.render({ optionalContentConfig, pdfDocument });
 | 
						|
        });
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
    this._initializePageLabels(pdfDocument);
 | 
						|
    this._initializeMetadata(pdfDocument);
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  async _scriptingDocProperties(pdfDocument) {
 | 
						|
    if (!this.documentInfo) {
 | 
						|
      // It should be *extremely* rare for metadata to not have been resolved
 | 
						|
      // when this code runs, but ensure that we handle that case here.
 | 
						|
      await new Promise(resolve => {
 | 
						|
        this.eventBus._on("metadataloaded", resolve, { once: true });
 | 
						|
      });
 | 
						|
      if (pdfDocument !== this.pdfDocument) {
 | 
						|
        return null; // The document was closed while the metadata resolved.
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (!this._contentLength) {
 | 
						|
      // Always waiting for the entire PDF document to be loaded will, most
 | 
						|
      // likely, delay sandbox-creation too much in the general case for all
 | 
						|
      // PDF documents which are not provided as binary data to the API.
 | 
						|
      // Hence we'll simply have to trust that the `contentLength` (as provided
 | 
						|
      // by the server), when it exists, is accurate enough here.
 | 
						|
      await new Promise(resolve => {
 | 
						|
        this.eventBus._on("documentloaded", resolve, { once: true });
 | 
						|
      });
 | 
						|
      if (pdfDocument !== this.pdfDocument) {
 | 
						|
        return null; // The document was closed while the downloadInfo resolved.
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return {
 | 
						|
      ...this.documentInfo,
 | 
						|
      baseURL: this.baseUrl,
 | 
						|
      filesize: this._contentLength,
 | 
						|
      filename: this._docFilename,
 | 
						|
      metadata: this.metadata?.getRaw(),
 | 
						|
      authors: this.metadata?.get("dc:creator"),
 | 
						|
      numPages: this.pagesCount,
 | 
						|
      URL: this.url,
 | 
						|
    };
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  async _initializeAutoPrint(pdfDocument, openActionPromise) {
 | 
						|
    const [openAction, jsActions] = await Promise.all([
 | 
						|
      openActionPromise,
 | 
						|
      this.pdfViewer.enableScripting ? null : pdfDocument.getJSActions(),
 | 
						|
    ]);
 | 
						|
 | 
						|
    if (pdfDocument !== this.pdfDocument) {
 | 
						|
      return; // The document was closed while the auto print data resolved.
 | 
						|
    }
 | 
						|
    let triggerAutoPrint = openAction?.action === "Print";
 | 
						|
 | 
						|
    if (jsActions) {
 | 
						|
      console.warn("Warning: JavaScript support is not enabled");
 | 
						|
 | 
						|
      // Hack to support auto printing.
 | 
						|
      for (const name in jsActions) {
 | 
						|
        if (triggerAutoPrint) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        switch (name) {
 | 
						|
          case "WillClose":
 | 
						|
          case "WillSave":
 | 
						|
          case "DidSave":
 | 
						|
          case "WillPrint":
 | 
						|
          case "DidPrint":
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        triggerAutoPrint = jsActions[name].some(js => AutoPrintRegExp.test(js));
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (triggerAutoPrint) {
 | 
						|
      this.triggerPrinting();
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  async _initializeMetadata(pdfDocument) {
 | 
						|
    const { info, metadata, contentDispositionFilename, contentLength } =
 | 
						|
      await pdfDocument.getMetadata();
 | 
						|
 | 
						|
    if (pdfDocument !== this.pdfDocument) {
 | 
						|
      return; // The document was closed while the metadata resolved.
 | 
						|
    }
 | 
						|
    if (info.collectedSignatureCertificates) {
 | 
						|
      this.externalServices.reportTelemetry({
 | 
						|
        type: "signatureCertificates",
 | 
						|
        data: info.collectedSignatureCertificates,
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    this.documentInfo = info;
 | 
						|
    this.metadata = metadata;
 | 
						|
    this._contentDispositionFilename ??= contentDispositionFilename;
 | 
						|
    this._contentLength ??= contentLength; // See `getDownloadInfo`-call above.
 | 
						|
 | 
						|
    // Provides some basic debug information
 | 
						|
    console.log(
 | 
						|
      `PDF ${pdfDocument.fingerprints[0]} [${info.PDFFormatVersion} ` +
 | 
						|
        `${(metadata?.get("pdf:producer") || info.Producer || "-").trim()} / ` +
 | 
						|
        `${(metadata?.get("xmp:creatortool") || info.Creator || "-").trim()}` +
 | 
						|
        `] (PDF.js: ${version || "?"} [${build || "?"}])`
 | 
						|
    );
 | 
						|
    const pdfTitle = this._docTitle;
 | 
						|
 | 
						|
    if (pdfTitle) {
 | 
						|
      this.setTitle(
 | 
						|
        `${pdfTitle} - ${this._contentDispositionFilename || this._title}`
 | 
						|
      );
 | 
						|
    } else if (this._contentDispositionFilename) {
 | 
						|
      this.setTitle(this._contentDispositionFilename);
 | 
						|
    }
 | 
						|
 | 
						|
    if (
 | 
						|
      info.IsXFAPresent &&
 | 
						|
      !info.IsAcroFormPresent &&
 | 
						|
      !pdfDocument.isPureXfa
 | 
						|
    ) {
 | 
						|
      if (pdfDocument.loadingParams.enableXfa) {
 | 
						|
        console.warn("Warning: XFA Foreground documents are not supported");
 | 
						|
      } else {
 | 
						|
        console.warn("Warning: XFA support is not enabled");
 | 
						|
      }
 | 
						|
    } else if (
 | 
						|
      (info.IsAcroFormPresent || info.IsXFAPresent) &&
 | 
						|
      !this.pdfViewer.renderForms
 | 
						|
    ) {
 | 
						|
      console.warn("Warning: Interactive form support is not enabled");
 | 
						|
    }
 | 
						|
 | 
						|
    if (info.IsSignaturesPresent) {
 | 
						|
      console.warn("Warning: Digital signatures validation is not supported");
 | 
						|
    }
 | 
						|
 | 
						|
    this.eventBus.dispatch("metadataloaded", { source: this });
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  async _initializePageLabels(pdfDocument) {
 | 
						|
    if (
 | 
						|
      typeof PDFJSDev === "undefined"
 | 
						|
        ? window.isGECKOVIEW
 | 
						|
        : PDFJSDev.test("GECKOVIEW")
 | 
						|
    ) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const labels = await pdfDocument.getPageLabels();
 | 
						|
 | 
						|
    if (pdfDocument !== this.pdfDocument) {
 | 
						|
      return; // The document was closed while the page labels resolved.
 | 
						|
    }
 | 
						|
    if (!labels || AppOptions.get("disablePageLabels")) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const numLabels = labels.length;
 | 
						|
    // Ignore page labels that correspond to standard page numbering,
 | 
						|
    // or page labels that are all empty.
 | 
						|
    let standardLabels = 0,
 | 
						|
      emptyLabels = 0;
 | 
						|
    for (let i = 0; i < numLabels; i++) {
 | 
						|
      const label = labels[i];
 | 
						|
      if (label === (i + 1).toString()) {
 | 
						|
        standardLabels++;
 | 
						|
      } else if (label === "") {
 | 
						|
        emptyLabels++;
 | 
						|
      } else {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (standardLabels >= numLabels || emptyLabels >= numLabels) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const { pdfViewer, pdfThumbnailViewer, toolbar } = this;
 | 
						|
 | 
						|
    pdfViewer.setPageLabels(labels);
 | 
						|
    pdfThumbnailViewer?.setPageLabels(labels);
 | 
						|
 | 
						|
    // Changing toolbar page display to use labels and we need to set
 | 
						|
    // the label of the current page.
 | 
						|
    toolbar?.setPagesCount(numLabels, true);
 | 
						|
    toolbar?.setPageNumber(
 | 
						|
      pdfViewer.currentPageNumber,
 | 
						|
      pdfViewer.currentPageLabel
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  _initializePdfHistory({ fingerprint, viewOnLoad, initialDest = null }) {
 | 
						|
    if (!this.pdfHistory) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    this.pdfHistory.initialize({
 | 
						|
      fingerprint,
 | 
						|
      resetHistory: viewOnLoad === ViewOnLoad.INITIAL,
 | 
						|
      updateUrl: AppOptions.get("historyUpdateUrl"),
 | 
						|
    });
 | 
						|
 | 
						|
    if (this.pdfHistory.initialBookmark) {
 | 
						|
      this.initialBookmark = this.pdfHistory.initialBookmark;
 | 
						|
 | 
						|
      this.initialRotation = this.pdfHistory.initialRotation;
 | 
						|
    }
 | 
						|
 | 
						|
    // Always let the browser history/document hash take precedence.
 | 
						|
    if (
 | 
						|
      initialDest &&
 | 
						|
      !this.initialBookmark &&
 | 
						|
      viewOnLoad === ViewOnLoad.UNKNOWN
 | 
						|
    ) {
 | 
						|
      this.initialBookmark = JSON.stringify(initialDest);
 | 
						|
      // TODO: Re-factor the `PDFHistory` initialization to remove this hack
 | 
						|
      // that's currently necessary to prevent weird initial history state.
 | 
						|
      this.pdfHistory.push({ explicitDest: initialDest, pageNumber: null });
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  _initializeAnnotationStorageCallbacks(pdfDocument) {
 | 
						|
    if (pdfDocument !== this.pdfDocument) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const { annotationStorage } = pdfDocument;
 | 
						|
 | 
						|
    annotationStorage.onSetModified = () => {
 | 
						|
      window.addEventListener("beforeunload", beforeUnload);
 | 
						|
 | 
						|
      if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
        this._annotationStorageModified = true;
 | 
						|
      }
 | 
						|
    };
 | 
						|
    annotationStorage.onResetModified = () => {
 | 
						|
      window.removeEventListener("beforeunload", beforeUnload);
 | 
						|
 | 
						|
      if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
        delete this._annotationStorageModified;
 | 
						|
      }
 | 
						|
    };
 | 
						|
    annotationStorage.onAnnotationEditor = typeStr => {
 | 
						|
      this._hasAnnotationEditors = !!typeStr;
 | 
						|
      this.setTitle();
 | 
						|
    };
 | 
						|
  },
 | 
						|
 | 
						|
  setInitialView(
 | 
						|
    storedHash,
 | 
						|
    { rotation, sidebarView, scrollMode, spreadMode } = {}
 | 
						|
  ) {
 | 
						|
    const setRotation = angle => {
 | 
						|
      if (isValidRotation(angle)) {
 | 
						|
        this.pdfViewer.pagesRotation = angle;
 | 
						|
      }
 | 
						|
    };
 | 
						|
    const setViewerModes = (scroll, spread) => {
 | 
						|
      if (isValidScrollMode(scroll)) {
 | 
						|
        this.pdfViewer.scrollMode = scroll;
 | 
						|
      }
 | 
						|
      if (isValidSpreadMode(spread)) {
 | 
						|
        this.pdfViewer.spreadMode = spread;
 | 
						|
      }
 | 
						|
    };
 | 
						|
    this.isInitialViewSet = true;
 | 
						|
    this.pdfSidebar?.setInitialView(sidebarView);
 | 
						|
 | 
						|
    setViewerModes(scrollMode, spreadMode);
 | 
						|
 | 
						|
    if (this.initialBookmark) {
 | 
						|
      setRotation(this.initialRotation);
 | 
						|
      delete this.initialRotation;
 | 
						|
 | 
						|
      this.pdfLinkService.setHash(this.initialBookmark);
 | 
						|
      this.initialBookmark = null;
 | 
						|
    } else if (storedHash) {
 | 
						|
      setRotation(rotation);
 | 
						|
 | 
						|
      this.pdfLinkService.setHash(storedHash);
 | 
						|
    }
 | 
						|
 | 
						|
    // Ensure that the correct page number is displayed in the UI,
 | 
						|
    // even if the active page didn't change during document load.
 | 
						|
    this.toolbar?.setPageNumber(
 | 
						|
      this.pdfViewer.currentPageNumber,
 | 
						|
      this.pdfViewer.currentPageLabel
 | 
						|
    );
 | 
						|
    this.secondaryToolbar?.setPageNumber(this.pdfViewer.currentPageNumber);
 | 
						|
 | 
						|
    if (!this.pdfViewer.currentScaleValue) {
 | 
						|
      // Scale was not initialized: invalid bookmark or scale was not specified.
 | 
						|
      // Setting the default one.
 | 
						|
      this.pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  _cleanup() {
 | 
						|
    if (!this.pdfDocument) {
 | 
						|
      return; // run cleanup when document is loaded
 | 
						|
    }
 | 
						|
    this.pdfViewer.cleanup();
 | 
						|
    this.pdfThumbnailViewer?.cleanup();
 | 
						|
 | 
						|
    this.pdfDocument.cleanup(
 | 
						|
      /* keepLoadedFonts = */ AppOptions.get("fontExtraProperties")
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  forceRendering() {
 | 
						|
    this.pdfRenderingQueue.printing = !!this.printService;
 | 
						|
    this.pdfRenderingQueue.isThumbnailViewEnabled =
 | 
						|
      this.pdfSidebar?.visibleView === SidebarView.THUMBS;
 | 
						|
    this.pdfRenderingQueue.renderHighestPriority();
 | 
						|
  },
 | 
						|
 | 
						|
  beforePrint() {
 | 
						|
    this._printAnnotationStoragePromise = this.pdfScriptingManager
 | 
						|
      .dispatchWillPrint()
 | 
						|
      .catch(() => {
 | 
						|
        /* Avoid breaking printing; ignoring errors. */
 | 
						|
      })
 | 
						|
      .then(() => this.pdfDocument?.annotationStorage.print);
 | 
						|
 | 
						|
    if (this.printService) {
 | 
						|
      // There is no way to suppress beforePrint/afterPrint events,
 | 
						|
      // but PDFPrintService may generate double events -- this will ignore
 | 
						|
      // the second event that will be coming from native window.print().
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!this.supportsPrinting || !this.pdfViewer.printingAllowed) {
 | 
						|
      this._otherError("pdfjs-printing-not-supported");
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    // The beforePrint is a sync method and we need to know layout before
 | 
						|
    // returning from this method. Ensure that we can get sizes of the pages.
 | 
						|
    if (!this.pdfViewer.pageViewsReady) {
 | 
						|
      this.l10n.get("pdfjs-printing-not-ready").then(msg => {
 | 
						|
        // eslint-disable-next-line no-alert
 | 
						|
        window.alert(msg);
 | 
						|
      });
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    this.printService = PDFPrintServiceFactory.createPrintService({
 | 
						|
      pdfDocument: this.pdfDocument,
 | 
						|
      pagesOverview: this.pdfViewer.getPagesOverview(),
 | 
						|
      printContainer: this.appConfig.printContainer,
 | 
						|
      printResolution: AppOptions.get("printResolution"),
 | 
						|
      printAnnotationStoragePromise: this._printAnnotationStoragePromise,
 | 
						|
    });
 | 
						|
    this.forceRendering();
 | 
						|
    // Disable the editor-indicator during printing (fixes bug 1790552).
 | 
						|
    this.setTitle();
 | 
						|
 | 
						|
    this.printService.layout();
 | 
						|
 | 
						|
    if (this._hasAnnotationEditors) {
 | 
						|
      this.externalServices.reportTelemetry({
 | 
						|
        type: "editing",
 | 
						|
        data: {
 | 
						|
          type: "print",
 | 
						|
          stats: this.pdfDocument?.annotationStorage.editorStats,
 | 
						|
        },
 | 
						|
      });
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  afterPrint() {
 | 
						|
    if (this._printAnnotationStoragePromise) {
 | 
						|
      this._printAnnotationStoragePromise.then(() => {
 | 
						|
        this.pdfScriptingManager.dispatchDidPrint();
 | 
						|
      });
 | 
						|
      this._printAnnotationStoragePromise = null;
 | 
						|
    }
 | 
						|
 | 
						|
    if (this.printService) {
 | 
						|
      this.printService.destroy();
 | 
						|
      this.printService = null;
 | 
						|
 | 
						|
      this.pdfDocument?.annotationStorage.resetModified();
 | 
						|
    }
 | 
						|
    this.forceRendering();
 | 
						|
    // Re-enable the editor-indicator after printing (fixes bug 1790552).
 | 
						|
    this.setTitle();
 | 
						|
  },
 | 
						|
 | 
						|
  rotatePages(delta) {
 | 
						|
    this.pdfViewer.pagesRotation += delta;
 | 
						|
    // Note that the thumbnail viewer is updated, and rendering is triggered,
 | 
						|
    // in the 'rotationchanging' event handler.
 | 
						|
  },
 | 
						|
 | 
						|
  requestPresentationMode() {
 | 
						|
    this.pdfPresentationMode?.request();
 | 
						|
  },
 | 
						|
 | 
						|
  async triggerPrinting() {
 | 
						|
    if (this.supportsPrinting && (await this._printPermissionPromise)) {
 | 
						|
      window.print();
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  bindEvents() {
 | 
						|
    if (this._eventBusAbortController) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const ac = (this._eventBusAbortController = new AbortController());
 | 
						|
    const opts = { signal: ac.signal };
 | 
						|
 | 
						|
    const {
 | 
						|
      eventBus,
 | 
						|
      externalServices,
 | 
						|
      pdfDocumentProperties,
 | 
						|
      pdfViewer,
 | 
						|
      preferences,
 | 
						|
    } = this;
 | 
						|
 | 
						|
    eventBus._on("resize", onResize.bind(this), opts);
 | 
						|
    eventBus._on("hashchange", onHashchange.bind(this), opts);
 | 
						|
    eventBus._on("beforeprint", this.beforePrint.bind(this), opts);
 | 
						|
    eventBus._on("afterprint", this.afterPrint.bind(this), opts);
 | 
						|
    eventBus._on("pagerender", onPageRender.bind(this), opts);
 | 
						|
    eventBus._on("pagerendered", onPageRendered.bind(this), opts);
 | 
						|
    eventBus._on("updateviewarea", onUpdateViewarea.bind(this), opts);
 | 
						|
    eventBus._on("pagechanging", onPageChanging.bind(this), opts);
 | 
						|
    eventBus._on("scalechanging", onScaleChanging.bind(this), opts);
 | 
						|
    eventBus._on("rotationchanging", onRotationChanging.bind(this), opts);
 | 
						|
    eventBus._on("sidebarviewchanged", onSidebarViewChanged.bind(this), opts);
 | 
						|
    eventBus._on("pagemode", onPageMode.bind(this), opts);
 | 
						|
    eventBus._on("namedaction", onNamedAction.bind(this), opts);
 | 
						|
    eventBus._on(
 | 
						|
      "presentationmodechanged",
 | 
						|
      evt => (pdfViewer.presentationModeState = evt.state),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "presentationmode",
 | 
						|
      this.requestPresentationMode.bind(this),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "switchannotationeditormode",
 | 
						|
      evt => (pdfViewer.annotationEditorMode = evt),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on("print", this.triggerPrinting.bind(this), opts);
 | 
						|
    eventBus._on("download", this.downloadOrSave.bind(this), opts);
 | 
						|
    eventBus._on("firstpage", () => (this.page = 1), opts);
 | 
						|
    eventBus._on("lastpage", () => (this.page = this.pagesCount), opts);
 | 
						|
    eventBus._on("nextpage", () => pdfViewer.nextPage(), opts);
 | 
						|
    eventBus._on("previouspage", () => pdfViewer.previousPage(), opts);
 | 
						|
    eventBus._on("zoomin", this.zoomIn.bind(this), opts);
 | 
						|
    eventBus._on("zoomout", this.zoomOut.bind(this), opts);
 | 
						|
    eventBus._on("zoomreset", this.zoomReset.bind(this), opts);
 | 
						|
    eventBus._on("pagenumberchanged", onPageNumberChanged.bind(this), opts);
 | 
						|
    eventBus._on(
 | 
						|
      "scalechanged",
 | 
						|
      evt => (pdfViewer.currentScaleValue = evt.value),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on("rotatecw", this.rotatePages.bind(this, 90), opts);
 | 
						|
    eventBus._on("rotateccw", this.rotatePages.bind(this, -90), opts);
 | 
						|
    eventBus._on(
 | 
						|
      "optionalcontentconfig",
 | 
						|
      evt => (pdfViewer.optionalContentConfigPromise = evt.promise),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "switchscrollmode",
 | 
						|
      evt => (pdfViewer.scrollMode = evt.mode),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "scrollmodechanged",
 | 
						|
      onViewerModesChanged.bind(this, "scrollMode"),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "switchspreadmode",
 | 
						|
      evt => (pdfViewer.spreadMode = evt.mode),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "spreadmodechanged",
 | 
						|
      onViewerModesChanged.bind(this, "spreadMode"),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "imagealttextsettings",
 | 
						|
      onImageAltTextSettings.bind(this),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "documentproperties",
 | 
						|
      () => pdfDocumentProperties?.open(),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on("findfromurlhash", onFindFromUrlHash.bind(this), opts);
 | 
						|
    eventBus._on(
 | 
						|
      "updatefindmatchescount",
 | 
						|
      onUpdateFindMatchesCount.bind(this),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
    eventBus._on(
 | 
						|
      "updatefindcontrolstate",
 | 
						|
      onUpdateFindControlState.bind(this),
 | 
						|
      opts
 | 
						|
    );
 | 
						|
 | 
						|
    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
      eventBus._on("fileinputchange", onFileInputChange.bind(this), opts);
 | 
						|
      eventBus._on("openfile", onOpenFile.bind(this), opts);
 | 
						|
    }
 | 
						|
    if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
      eventBus._on(
 | 
						|
        "annotationeditorstateschanged",
 | 
						|
        evt => externalServices.updateEditorStates(evt),
 | 
						|
        opts
 | 
						|
      );
 | 
						|
      eventBus._on(
 | 
						|
        "reporttelemetry",
 | 
						|
        evt => externalServices.reportTelemetry(evt.details),
 | 
						|
        opts
 | 
						|
      );
 | 
						|
    }
 | 
						|
    if (
 | 
						|
      typeof PDFJSDev === "undefined" ||
 | 
						|
      PDFJSDev.test("TESTING || MOZCENTRAL")
 | 
						|
    ) {
 | 
						|
      eventBus._on(
 | 
						|
        "setpreference",
 | 
						|
        evt => preferences.set(evt.name, evt.value),
 | 
						|
        opts
 | 
						|
      );
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  bindWindowEvents() {
 | 
						|
    if (this._windowAbortController) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    this._windowAbortController = new AbortController();
 | 
						|
 | 
						|
    const {
 | 
						|
      eventBus,
 | 
						|
      appConfig: { mainContainer },
 | 
						|
      pdfViewer,
 | 
						|
      _windowAbortController: { signal },
 | 
						|
    } = this;
 | 
						|
 | 
						|
    this._touchManager = new TouchManager({
 | 
						|
      container: window,
 | 
						|
      isPinchingDisabled: () => pdfViewer.isInPresentationMode,
 | 
						|
      isPinchingStopped: () => this.overlayManager?.active,
 | 
						|
      onPinching: this.touchPinchCallback.bind(this),
 | 
						|
      onPinchEnd: this.touchPinchEndCallback.bind(this),
 | 
						|
      signal,
 | 
						|
    });
 | 
						|
 | 
						|
    function addWindowResolutionChange(evt = null) {
 | 
						|
      if (evt) {
 | 
						|
        pdfViewer.refresh();
 | 
						|
      }
 | 
						|
      const mediaQueryList = window.matchMedia(
 | 
						|
        `(resolution: ${OutputScale.pixelRatio}dppx)`
 | 
						|
      );
 | 
						|
      mediaQueryList.addEventListener("change", addWindowResolutionChange, {
 | 
						|
        once: true,
 | 
						|
        signal,
 | 
						|
      });
 | 
						|
    }
 | 
						|
    addWindowResolutionChange();
 | 
						|
 | 
						|
    window.addEventListener("wheel", onWheel.bind(this), {
 | 
						|
      passive: false,
 | 
						|
      signal,
 | 
						|
    });
 | 
						|
    window.addEventListener("click", onClick.bind(this), { signal });
 | 
						|
    window.addEventListener("keydown", onKeyDown.bind(this), { signal });
 | 
						|
    window.addEventListener("keyup", onKeyUp.bind(this), { signal });
 | 
						|
    window.addEventListener(
 | 
						|
      "resize",
 | 
						|
      () => eventBus.dispatch("resize", { source: window }),
 | 
						|
      { signal }
 | 
						|
    );
 | 
						|
    window.addEventListener(
 | 
						|
      "hashchange",
 | 
						|
      () => {
 | 
						|
        eventBus.dispatch("hashchange", {
 | 
						|
          source: window,
 | 
						|
          hash: document.location.hash.substring(1),
 | 
						|
        });
 | 
						|
      },
 | 
						|
      { signal }
 | 
						|
    );
 | 
						|
    window.addEventListener(
 | 
						|
      "beforeprint",
 | 
						|
      () => eventBus.dispatch("beforeprint", { source: window }),
 | 
						|
      { signal }
 | 
						|
    );
 | 
						|
    window.addEventListener(
 | 
						|
      "afterprint",
 | 
						|
      () => eventBus.dispatch("afterprint", { source: window }),
 | 
						|
      { signal }
 | 
						|
    );
 | 
						|
    window.addEventListener(
 | 
						|
      "updatefromsandbox",
 | 
						|
      evt => {
 | 
						|
        eventBus.dispatch("updatefromsandbox", {
 | 
						|
          source: window,
 | 
						|
          detail: evt.detail,
 | 
						|
        });
 | 
						|
      },
 | 
						|
      { signal }
 | 
						|
    );
 | 
						|
 | 
						|
    if (
 | 
						|
      (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) &&
 | 
						|
      !("onscrollend" in document.documentElement)
 | 
						|
    ) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
      // Using the values lastScrollTop and lastScrollLeft is a workaround to
 | 
						|
      // https://bugzilla.mozilla.org/show_bug.cgi?id=1881974.
 | 
						|
      // TODO: remove them once the bug is fixed.
 | 
						|
      ({ scrollTop: this._lastScrollTop, scrollLeft: this._lastScrollLeft } =
 | 
						|
        mainContainer);
 | 
						|
    }
 | 
						|
 | 
						|
    let scrollendTimeoutID, scrollAbortController;
 | 
						|
    const scrollend = () => {
 | 
						|
      if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
        ({ scrollTop: this._lastScrollTop, scrollLeft: this._lastScrollLeft } =
 | 
						|
          mainContainer);
 | 
						|
      }
 | 
						|
      clearTimeout(scrollendTimeoutID);
 | 
						|
      if (this._isScrolling) {
 | 
						|
        scrollAbortController.abort();
 | 
						|
        scrollAbortController = null;
 | 
						|
        this._isScrolling = false;
 | 
						|
      }
 | 
						|
    };
 | 
						|
    const scroll = () => {
 | 
						|
      if (this._isCtrlKeyDown) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      if (
 | 
						|
        (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) &&
 | 
						|
        this._lastScrollTop === mainContainer.scrollTop &&
 | 
						|
        this._lastScrollLeft === mainContainer.scrollLeft
 | 
						|
      ) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      if (!this._isScrolling) {
 | 
						|
        scrollAbortController = new AbortController();
 | 
						|
        const abortSignal = AbortSignal.any([
 | 
						|
          scrollAbortController.signal,
 | 
						|
          signal,
 | 
						|
        ]);
 | 
						|
 | 
						|
        mainContainer.addEventListener("scrollend", scrollend, {
 | 
						|
          signal: abortSignal,
 | 
						|
        });
 | 
						|
        mainContainer.addEventListener("blur", scrollend, {
 | 
						|
          signal: abortSignal,
 | 
						|
        });
 | 
						|
        this._isScrolling = true;
 | 
						|
      }
 | 
						|
      clearTimeout(scrollendTimeoutID);
 | 
						|
      // Why 100 ? Because of:
 | 
						|
      // https://developer.chrome.com/blog/scrollend-a-new-javascript-event
 | 
						|
      // Maybe we could find a better value... ideally the `scrollend` event
 | 
						|
      // should be correctly fired.
 | 
						|
      scrollendTimeoutID = setTimeout(scrollend, 100);
 | 
						|
    };
 | 
						|
    mainContainer.addEventListener("scroll", scroll, {
 | 
						|
      passive: true,
 | 
						|
      signal,
 | 
						|
    });
 | 
						|
  },
 | 
						|
 | 
						|
  unbindEvents() {
 | 
						|
    this._eventBusAbortController?.abort();
 | 
						|
    this._eventBusAbortController = null;
 | 
						|
  },
 | 
						|
 | 
						|
  unbindWindowEvents() {
 | 
						|
    this._windowAbortController?.abort();
 | 
						|
    this._windowAbortController = null;
 | 
						|
    this._touchManager = null;
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * @ignore
 | 
						|
   */
 | 
						|
  async testingClose() {
 | 
						|
    this.unbindEvents();
 | 
						|
    this.unbindWindowEvents();
 | 
						|
 | 
						|
    this._globalAbortController?.abort();
 | 
						|
    this._globalAbortController = null;
 | 
						|
 | 
						|
    this.findBar?.close();
 | 
						|
 | 
						|
    await Promise.all([this.l10n?.destroy(), this.close()]);
 | 
						|
  },
 | 
						|
 | 
						|
  _accumulateTicks(ticks, prop) {
 | 
						|
    // If the direction changed, reset the accumulated ticks.
 | 
						|
    if ((this[prop] > 0 && ticks < 0) || (this[prop] < 0 && ticks > 0)) {
 | 
						|
      this[prop] = 0;
 | 
						|
    }
 | 
						|
    this[prop] += ticks;
 | 
						|
    const wholeTicks = Math.trunc(this[prop]);
 | 
						|
    this[prop] -= wholeTicks;
 | 
						|
    return wholeTicks;
 | 
						|
  },
 | 
						|
 | 
						|
  _accumulateFactor(previousScale, factor, prop) {
 | 
						|
    if (factor === 1) {
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
    // If the direction changed, reset the accumulated factor.
 | 
						|
    if ((this[prop] > 1 && factor < 1) || (this[prop] < 1 && factor > 1)) {
 | 
						|
      this[prop] = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    const newFactor =
 | 
						|
      Math.floor(previousScale * factor * this[prop] * 100) /
 | 
						|
      (100 * previousScale);
 | 
						|
    this[prop] = factor / newFactor;
 | 
						|
 | 
						|
    return newFactor;
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Should be called *after* all pages have loaded, or if an error occurred,
 | 
						|
   * to unblock the "load" event; see https://bugzilla.mozilla.org/show_bug.cgi?id=1618553
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
  _unblockDocumentLoadEvent() {
 | 
						|
    document.blockUnblockOnload?.(false);
 | 
						|
 | 
						|
    // Ensure that this method is only ever run once.
 | 
						|
    this._unblockDocumentLoadEvent = () => {};
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Used together with the integration-tests, to enable awaiting full
 | 
						|
   * initialization of the scripting/sandbox.
 | 
						|
   */
 | 
						|
  get scriptingReady() {
 | 
						|
    return this.pdfScriptingManager.ready;
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
initCom(PDFViewerApplication);
 | 
						|
 | 
						|
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
 | 
						|
  PDFPrintServiceFactory.initGlobals(PDFViewerApplication);
 | 
						|
}
 | 
						|
 | 
						|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
  const HOSTED_VIEWER_ORIGINS = new Set([
 | 
						|
    "null",
 | 
						|
    "http://mozilla.github.io",
 | 
						|
    "https://mozilla.github.io",
 | 
						|
  ]);
 | 
						|
  // eslint-disable-next-line no-var
 | 
						|
  var validateFileURL = function (file) {
 | 
						|
    if (!file) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const viewerOrigin = URL.parse(window.location)?.origin || "null";
 | 
						|
    if (HOSTED_VIEWER_ORIGINS.has(viewerOrigin)) {
 | 
						|
      // Hosted or local viewer, allow for any file locations
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const fileOrigin = URL.parse(file, window.location)?.origin;
 | 
						|
    if (fileOrigin === viewerOrigin) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    const ex = new Error("file origin does not match viewer's");
 | 
						|
 | 
						|
    PDFViewerApplication._documentError("pdfjs-loading-error", {
 | 
						|
      message: ex.message,
 | 
						|
    });
 | 
						|
    // Removing of the following line will not guarantee that the viewer will
 | 
						|
    // start accepting URLs from foreign origin -- CORS headers on the remote
 | 
						|
    // server must be properly configured.
 | 
						|
    throw ex;
 | 
						|
  };
 | 
						|
 | 
						|
  // eslint-disable-next-line no-var
 | 
						|
  var onFileInputChange = function (evt) {
 | 
						|
    if (this.pdfViewer?.isInPresentationMode) {
 | 
						|
      return; // Opening a new PDF file isn't supported in Presentation Mode.
 | 
						|
    }
 | 
						|
    const file = evt.fileInput.files[0];
 | 
						|
 | 
						|
    this.open({
 | 
						|
      url: URL.createObjectURL(file),
 | 
						|
      originalUrl: encodeURIComponent(file.name),
 | 
						|
    });
 | 
						|
  };
 | 
						|
 | 
						|
  // eslint-disable-next-line no-var
 | 
						|
  var onOpenFile = function (evt) {
 | 
						|
    this._openFileInput?.click();
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
function onPageRender({ pageNumber }) {
 | 
						|
  // If the page is (the most) visible when it starts rendering,
 | 
						|
  // ensure that the page number input loading indicator is displayed.
 | 
						|
  if (pageNumber === this.page) {
 | 
						|
    this.toolbar?.updateLoadingIndicatorState(true);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onPageRendered({ pageNumber, isDetailView, error }) {
 | 
						|
  // If the page is still visible when it has finished rendering,
 | 
						|
  // ensure that the page number input loading indicator is hidden.
 | 
						|
  if (pageNumber === this.page) {
 | 
						|
    this.toolbar?.updateLoadingIndicatorState(false);
 | 
						|
  }
 | 
						|
 | 
						|
  // Use the rendered page to set the corresponding thumbnail image.
 | 
						|
  if (!isDetailView && this.pdfSidebar?.visibleView === SidebarView.THUMBS) {
 | 
						|
    const pageView = this.pdfViewer.getPageView(/* index = */ pageNumber - 1);
 | 
						|
    const thumbnailView = this.pdfThumbnailViewer?.getThumbnail(
 | 
						|
      /* index = */ pageNumber - 1
 | 
						|
    );
 | 
						|
    if (pageView) {
 | 
						|
      thumbnailView?.setImage(pageView);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (error) {
 | 
						|
    this._otherError("pdfjs-rendering-error", error);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onPageMode({ mode }) {
 | 
						|
  // Handle the 'pagemode' hash parameter, see also `PDFLinkService_setHash`.
 | 
						|
  let view;
 | 
						|
  switch (mode) {
 | 
						|
    case "thumbs":
 | 
						|
      view = SidebarView.THUMBS;
 | 
						|
      break;
 | 
						|
    case "bookmarks":
 | 
						|
    case "outline": // non-standard
 | 
						|
      view = SidebarView.OUTLINE;
 | 
						|
      break;
 | 
						|
    case "attachments": // non-standard
 | 
						|
      view = SidebarView.ATTACHMENTS;
 | 
						|
      break;
 | 
						|
    case "layers": // non-standard
 | 
						|
      view = SidebarView.LAYERS;
 | 
						|
      break;
 | 
						|
    case "none":
 | 
						|
      view = SidebarView.NONE;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      console.error('Invalid "pagemode" hash parameter: ' + mode);
 | 
						|
      return;
 | 
						|
  }
 | 
						|
  this.pdfSidebar?.switchView(view, /* forceOpen = */ true);
 | 
						|
}
 | 
						|
 | 
						|
function onNamedAction(evt) {
 | 
						|
  // Processing a couple of named actions that might be useful, see also
 | 
						|
  // `PDFLinkService.executeNamedAction`.
 | 
						|
  switch (evt.action) {
 | 
						|
    case "GoToPage":
 | 
						|
      this.appConfig.toolbar?.pageNumber.select();
 | 
						|
      break;
 | 
						|
 | 
						|
    case "Find":
 | 
						|
      if (!this.supportsIntegratedFind) {
 | 
						|
        this.findBar?.toggle();
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case "Print":
 | 
						|
      this.triggerPrinting();
 | 
						|
      break;
 | 
						|
 | 
						|
    case "SaveAs":
 | 
						|
      this.downloadOrSave();
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onSidebarViewChanged({ view }) {
 | 
						|
  this.pdfRenderingQueue.isThumbnailViewEnabled = view === SidebarView.THUMBS;
 | 
						|
 | 
						|
  if (this.isInitialViewSet) {
 | 
						|
    // Only update the storage when the document has been loaded *and* rendered.
 | 
						|
    this.store?.set("sidebarView", view).catch(() => {
 | 
						|
      // Unable to write to storage.
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onUpdateViewarea({ location }) {
 | 
						|
  if (this.isInitialViewSet) {
 | 
						|
    // Only update the storage when the document has been loaded *and* rendered.
 | 
						|
    this.store
 | 
						|
      ?.setMultiple({
 | 
						|
        page: location.pageNumber,
 | 
						|
        zoom: location.scale,
 | 
						|
        scrollLeft: location.left,
 | 
						|
        scrollTop: location.top,
 | 
						|
        rotation: location.rotation,
 | 
						|
      })
 | 
						|
      .catch(() => {
 | 
						|
        // Unable to write to storage.
 | 
						|
      });
 | 
						|
  }
 | 
						|
  if (this.appConfig.secondaryToolbar) {
 | 
						|
    this.appConfig.secondaryToolbar.viewBookmarkButton.href =
 | 
						|
      this.pdfLinkService.getAnchorUrl(location.pdfOpenParams);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onViewerModesChanged(name, evt) {
 | 
						|
  if (this.isInitialViewSet && !this.pdfViewer.isInPresentationMode) {
 | 
						|
    // Only update the storage when the document has been loaded *and* rendered.
 | 
						|
    this.store?.set(name, evt.mode).catch(() => {
 | 
						|
      // Unable to write to storage.
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onResize() {
 | 
						|
  const { pdfDocument, pdfViewer, pdfRenderingQueue } = this;
 | 
						|
 | 
						|
  if (pdfRenderingQueue.printing && window.matchMedia("print").matches) {
 | 
						|
    // Work-around issue 15324 by ignoring "resize" events during printing.
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!pdfDocument) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  const currentScaleValue = pdfViewer.currentScaleValue;
 | 
						|
  if (
 | 
						|
    currentScaleValue === "auto" ||
 | 
						|
    currentScaleValue === "page-fit" ||
 | 
						|
    currentScaleValue === "page-width"
 | 
						|
  ) {
 | 
						|
    // Note: the scale is constant for 'page-actual'.
 | 
						|
    pdfViewer.currentScaleValue = currentScaleValue;
 | 
						|
  }
 | 
						|
  pdfViewer.update();
 | 
						|
}
 | 
						|
 | 
						|
function onHashchange(evt) {
 | 
						|
  const hash = evt.hash;
 | 
						|
  if (!hash) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  if (!this.isInitialViewSet) {
 | 
						|
    this.initialBookmark = hash;
 | 
						|
  } else if (!this.pdfHistory?.popStateInProgress) {
 | 
						|
    this.pdfLinkService.setHash(hash);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onPageNumberChanged(evt) {
 | 
						|
  const { pdfViewer } = this;
 | 
						|
  // Note that for `<input type="number">` HTML elements, an empty string will
 | 
						|
  // be returned for non-number inputs; hence we simply do nothing in that case.
 | 
						|
  if (evt.value !== "") {
 | 
						|
    this.pdfLinkService.goToPage(evt.value);
 | 
						|
  }
 | 
						|
 | 
						|
  // Ensure that the page number input displays the correct value, even if the
 | 
						|
  // value entered by the user was invalid (e.g. a floating point number).
 | 
						|
  if (
 | 
						|
    evt.value !== pdfViewer.currentPageNumber.toString() &&
 | 
						|
    evt.value !== pdfViewer.currentPageLabel
 | 
						|
  ) {
 | 
						|
    this.toolbar?.setPageNumber(
 | 
						|
      pdfViewer.currentPageNumber,
 | 
						|
      pdfViewer.currentPageLabel
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onImageAltTextSettings() {
 | 
						|
  this.imageAltTextSettings?.open({
 | 
						|
    enableGuessAltText: AppOptions.get("enableGuessAltText"),
 | 
						|
    enableNewAltTextWhenAddingImage: AppOptions.get(
 | 
						|
      "enableNewAltTextWhenAddingImage"
 | 
						|
    ),
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
function onFindFromUrlHash(evt) {
 | 
						|
  this.eventBus.dispatch("find", {
 | 
						|
    source: evt.source,
 | 
						|
    type: "",
 | 
						|
    query: evt.query,
 | 
						|
    caseSensitive: false,
 | 
						|
    entireWord: false,
 | 
						|
    highlightAll: true,
 | 
						|
    findPrevious: false,
 | 
						|
    matchDiacritics: true,
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
function onUpdateFindMatchesCount({ matchesCount }) {
 | 
						|
  if (this.supportsIntegratedFind) {
 | 
						|
    this.externalServices.updateFindMatchesCount(matchesCount);
 | 
						|
  } else {
 | 
						|
    this.findBar?.updateResultsCount(matchesCount);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onUpdateFindControlState({
 | 
						|
  state,
 | 
						|
  previous,
 | 
						|
  entireWord,
 | 
						|
  matchesCount,
 | 
						|
  rawQuery,
 | 
						|
}) {
 | 
						|
  if (this.supportsIntegratedFind) {
 | 
						|
    this.externalServices.updateFindControlState({
 | 
						|
      result: state,
 | 
						|
      findPrevious: previous,
 | 
						|
      entireWord,
 | 
						|
      matchesCount,
 | 
						|
      rawQuery,
 | 
						|
    });
 | 
						|
  } else {
 | 
						|
    this.findBar?.updateUIState(state, previous, matchesCount);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onScaleChanging(evt) {
 | 
						|
  this.toolbar?.setPageScale(evt.presetValue, evt.scale);
 | 
						|
 | 
						|
  this.pdfViewer.update();
 | 
						|
}
 | 
						|
 | 
						|
function onRotationChanging(evt) {
 | 
						|
  if (this.pdfThumbnailViewer) {
 | 
						|
    this.pdfThumbnailViewer.pagesRotation = evt.pagesRotation;
 | 
						|
  }
 | 
						|
 | 
						|
  this.forceRendering();
 | 
						|
  // Ensure that the active page doesn't change during rotation.
 | 
						|
  this.pdfViewer.currentPageNumber = evt.pageNumber;
 | 
						|
}
 | 
						|
 | 
						|
function onPageChanging({ pageNumber, pageLabel }) {
 | 
						|
  this.toolbar?.setPageNumber(pageNumber, pageLabel);
 | 
						|
  this.secondaryToolbar?.setPageNumber(pageNumber);
 | 
						|
 | 
						|
  if (this.pdfSidebar?.visibleView === SidebarView.THUMBS) {
 | 
						|
    this.pdfThumbnailViewer?.scrollThumbnailIntoView(pageNumber);
 | 
						|
  }
 | 
						|
 | 
						|
  // Show/hide the loading indicator in the page number input element.
 | 
						|
  const currentPage = this.pdfViewer.getPageView(/* index = */ pageNumber - 1);
 | 
						|
  this.toolbar?.updateLoadingIndicatorState(
 | 
						|
    currentPage?.renderingState === RenderingStates.RUNNING
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
function onWheel(evt) {
 | 
						|
  const {
 | 
						|
    pdfViewer,
 | 
						|
    supportsMouseWheelZoomCtrlKey,
 | 
						|
    supportsMouseWheelZoomMetaKey,
 | 
						|
    supportsPinchToZoom,
 | 
						|
  } = this;
 | 
						|
 | 
						|
  if (pdfViewer.isInPresentationMode) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // Pinch-to-zoom on a trackpad maps to a wheel event with ctrlKey set to true
 | 
						|
  // https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent#browser_compatibility
 | 
						|
  // Hence if ctrlKey is true but ctrl key hasn't been pressed then we can
 | 
						|
  // infer that we have a pinch-to-zoom.
 | 
						|
  // But the ctrlKey could have been pressed outside of the browser window,
 | 
						|
  // hence we try to do some magic to guess if the scaleFactor is likely coming
 | 
						|
  // from a pinch-to-zoom or not.
 | 
						|
 | 
						|
  // It is important that we query deltaMode before delta{X,Y}, so that
 | 
						|
  // Firefox doesn't switch to DOM_DELTA_PIXEL mode for compat with other
 | 
						|
  // browsers, see https://bugzilla.mozilla.org/show_bug.cgi?id=1392460.
 | 
						|
  const deltaMode = evt.deltaMode;
 | 
						|
 | 
						|
  // The following formula is a bit strange but it comes from:
 | 
						|
  // https://searchfox.org/mozilla-central/rev/d62c4c4d5547064487006a1506287da394b64724/widget/InputData.cpp#618-626
 | 
						|
  let scaleFactor = Math.exp(-evt.deltaY / 100);
 | 
						|
 | 
						|
  const isBuiltInMac =
 | 
						|
    typeof PDFJSDev !== "undefined" &&
 | 
						|
    PDFJSDev.test("MOZCENTRAL") &&
 | 
						|
    FeatureTest.platform.isMac;
 | 
						|
  const isPinchToZoom =
 | 
						|
    evt.ctrlKey &&
 | 
						|
    !this._isCtrlKeyDown &&
 | 
						|
    deltaMode === WheelEvent.DOM_DELTA_PIXEL &&
 | 
						|
    evt.deltaX === 0 &&
 | 
						|
    (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) &&
 | 
						|
    evt.deltaZ === 0;
 | 
						|
  const origin = [evt.clientX, evt.clientY];
 | 
						|
 | 
						|
  if (
 | 
						|
    isPinchToZoom ||
 | 
						|
    (evt.ctrlKey && supportsMouseWheelZoomCtrlKey) ||
 | 
						|
    (evt.metaKey && supportsMouseWheelZoomMetaKey)
 | 
						|
  ) {
 | 
						|
    // Only zoom the pages, not the entire viewer.
 | 
						|
    evt.preventDefault();
 | 
						|
    // NOTE: this check must be placed *after* preventDefault.
 | 
						|
    if (
 | 
						|
      this._isScrolling ||
 | 
						|
      document.visibilityState === "hidden" ||
 | 
						|
      this.overlayManager.active
 | 
						|
    ) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (isPinchToZoom && supportsPinchToZoom) {
 | 
						|
      scaleFactor = this._accumulateFactor(
 | 
						|
        pdfViewer.currentScale,
 | 
						|
        scaleFactor,
 | 
						|
        "_wheelUnusedFactor"
 | 
						|
      );
 | 
						|
      this.updateZoom(null, scaleFactor, origin);
 | 
						|
    } else {
 | 
						|
      const delta = normalizeWheelEventDirection(evt);
 | 
						|
 | 
						|
      let ticks = 0;
 | 
						|
      if (
 | 
						|
        deltaMode === WheelEvent.DOM_DELTA_LINE ||
 | 
						|
        deltaMode === WheelEvent.DOM_DELTA_PAGE
 | 
						|
      ) {
 | 
						|
        // For line-based devices, use one tick per event, because different
 | 
						|
        // OSs have different defaults for the number lines. But we generally
 | 
						|
        // want one "clicky" roll of the wheel (which produces one event) to
 | 
						|
        // adjust the zoom by one step.
 | 
						|
        //
 | 
						|
        // If we're getting fractional lines (I can't think of a scenario
 | 
						|
        // this might actually happen), be safe and use the accumulator.
 | 
						|
        ticks =
 | 
						|
          Math.abs(delta) >= 1
 | 
						|
            ? Math.sign(delta)
 | 
						|
            : this._accumulateTicks(delta, "_wheelUnusedTicks");
 | 
						|
      } else {
 | 
						|
        // pixel-based devices
 | 
						|
        const PIXELS_PER_LINE_SCALE = 30;
 | 
						|
        ticks = this._accumulateTicks(
 | 
						|
          delta / PIXELS_PER_LINE_SCALE,
 | 
						|
          "_wheelUnusedTicks"
 | 
						|
        );
 | 
						|
      }
 | 
						|
 | 
						|
      this.updateZoom(ticks, null, origin);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function closeSecondaryToolbar({ target }) {
 | 
						|
  if (!this.secondaryToolbar?.isOpen) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  const { toolbar, secondaryToolbar } = this.appConfig;
 | 
						|
  if (
 | 
						|
    this.pdfViewer.containsElement(target) ||
 | 
						|
    (toolbar?.container.contains(target) &&
 | 
						|
      !secondaryToolbar?.toolbar.contains(target) &&
 | 
						|
      // TODO: change the `contains` for an equality check when the bug:
 | 
						|
      //  https://bugzilla.mozilla.org/show_bug.cgi?id=1921984
 | 
						|
      // is fixed.
 | 
						|
      !secondaryToolbar?.toggleButton.contains(target))
 | 
						|
  ) {
 | 
						|
    this.secondaryToolbar.close();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function closeEditorUndoBar(evt) {
 | 
						|
  if (!this.editorUndoBar?.isOpen) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  if (this.appConfig.secondaryToolbar?.toolbar.contains(evt.target)) {
 | 
						|
    this.editorUndoBar.hide();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onClick(evt) {
 | 
						|
  closeSecondaryToolbar.call(this, evt);
 | 
						|
  closeEditorUndoBar.call(this, evt);
 | 
						|
}
 | 
						|
 | 
						|
function onKeyUp(evt) {
 | 
						|
  // evt.ctrlKey is false hence we use evt.key.
 | 
						|
  if (evt.key === "Control") {
 | 
						|
    this._isCtrlKeyDown = false;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function onKeyDown(evt) {
 | 
						|
  this._isCtrlKeyDown = evt.key === "Control";
 | 
						|
 | 
						|
  if (
 | 
						|
    this.editorUndoBar?.isOpen &&
 | 
						|
    evt.keyCode !== 9 &&
 | 
						|
    evt.keyCode !== 16 &&
 | 
						|
    !(
 | 
						|
      (evt.keyCode === 13 || evt.keyCode === 32) &&
 | 
						|
      getActiveOrFocusedElement() === this.appConfig.editorUndoBar.undoButton
 | 
						|
    )
 | 
						|
  ) {
 | 
						|
    // Hide undo bar on keypress except for Shift, Tab, Shift+Tab.
 | 
						|
    // Also avoid hiding if the undo button is triggered.
 | 
						|
    this.editorUndoBar.hide();
 | 
						|
  }
 | 
						|
 | 
						|
  if (this.overlayManager.active) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  const { eventBus, pdfViewer } = this;
 | 
						|
  const isViewerInPresentationMode = pdfViewer.isInPresentationMode;
 | 
						|
 | 
						|
  let handled = false,
 | 
						|
    ensureViewerFocused = false;
 | 
						|
  const cmd =
 | 
						|
    (evt.ctrlKey ? 1 : 0) |
 | 
						|
    (evt.altKey ? 2 : 0) |
 | 
						|
    (evt.shiftKey ? 4 : 0) |
 | 
						|
    (evt.metaKey ? 8 : 0);
 | 
						|
 | 
						|
  // First, handle the key bindings that are independent whether an input
 | 
						|
  // control is selected or not.
 | 
						|
  if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
 | 
						|
    // either CTRL or META key with optional SHIFT.
 | 
						|
    switch (evt.keyCode) {
 | 
						|
      case 70: // f
 | 
						|
        if (!this.supportsIntegratedFind && !evt.shiftKey) {
 | 
						|
          this.findBar?.open();
 | 
						|
          handled = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 71: // g
 | 
						|
        if (!this.supportsIntegratedFind) {
 | 
						|
          const { state } = this.findController;
 | 
						|
          if (state) {
 | 
						|
            const newState = {
 | 
						|
              source: window,
 | 
						|
              type: "again",
 | 
						|
              findPrevious: cmd === 5 || cmd === 12,
 | 
						|
            };
 | 
						|
            eventBus.dispatch("find", { ...state, ...newState });
 | 
						|
          }
 | 
						|
          handled = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 61: // FF/Mac '='
 | 
						|
      case 107: // FF '+' and '='
 | 
						|
      case 187: // Chrome '+'
 | 
						|
      case 171: // FF with German keyboard
 | 
						|
        this.zoomIn();
 | 
						|
        handled = true;
 | 
						|
        break;
 | 
						|
      case 173: // FF/Mac '-'
 | 
						|
      case 109: // FF '-'
 | 
						|
      case 189: // Chrome '-'
 | 
						|
        this.zoomOut();
 | 
						|
        handled = true;
 | 
						|
        break;
 | 
						|
      case 48: // '0'
 | 
						|
      case 96: // '0' on Numpad of Swedish keyboard
 | 
						|
        if (!isViewerInPresentationMode) {
 | 
						|
          // keeping it unhandled (to restore page zoom to 100%)
 | 
						|
          setTimeout(() => {
 | 
						|
            // ... and resetting the scale after browser adjusts its scale
 | 
						|
            this.zoomReset();
 | 
						|
          });
 | 
						|
          handled = false;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      case 38: // up arrow
 | 
						|
        if (isViewerInPresentationMode || this.page > 1) {
 | 
						|
          this.page = 1;
 | 
						|
          handled = true;
 | 
						|
          ensureViewerFocused = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 40: // down arrow
 | 
						|
        if (isViewerInPresentationMode || this.page < this.pagesCount) {
 | 
						|
          this.page = this.pagesCount;
 | 
						|
          handled = true;
 | 
						|
          ensureViewerFocused = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC || CHROME")) {
 | 
						|
    // CTRL or META without shift
 | 
						|
    if (cmd === 1 || cmd === 8) {
 | 
						|
      switch (evt.keyCode) {
 | 
						|
        case 83: // s
 | 
						|
          eventBus.dispatch("download", { source: window });
 | 
						|
          handled = true;
 | 
						|
          break;
 | 
						|
 | 
						|
        case 79: // o
 | 
						|
          if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
 | 
						|
            eventBus.dispatch("openfile", { source: window });
 | 
						|
            handled = true;
 | 
						|
          }
 | 
						|
          break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // CTRL+ALT or Option+Command
 | 
						|
  if (cmd === 3 || cmd === 10) {
 | 
						|
    switch (evt.keyCode) {
 | 
						|
      case 80: // p
 | 
						|
        this.requestPresentationMode();
 | 
						|
        handled = true;
 | 
						|
        this.externalServices.reportTelemetry({
 | 
						|
          type: "buttons",
 | 
						|
          data: { id: "presentationModeKeyboard" },
 | 
						|
        });
 | 
						|
        break;
 | 
						|
      case 71: // g
 | 
						|
        // focuses input#pageNumber field
 | 
						|
        if (this.appConfig.toolbar) {
 | 
						|
          this.appConfig.toolbar.pageNumber.select();
 | 
						|
          handled = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (handled) {
 | 
						|
    if (ensureViewerFocused && !isViewerInPresentationMode) {
 | 
						|
      pdfViewer.focus();
 | 
						|
    }
 | 
						|
    evt.preventDefault();
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  // Some shortcuts should not get handled if a control/input element
 | 
						|
  // is selected.
 | 
						|
  const curElement = getActiveOrFocusedElement();
 | 
						|
  const curElementTagName = curElement?.tagName.toUpperCase();
 | 
						|
  if (
 | 
						|
    curElementTagName === "INPUT" ||
 | 
						|
    curElementTagName === "TEXTAREA" ||
 | 
						|
    curElementTagName === "SELECT" ||
 | 
						|
    (curElementTagName === "BUTTON" && evt.keyCode === /* Space = */ 32) ||
 | 
						|
    curElement?.isContentEditable
 | 
						|
  ) {
 | 
						|
    // Make sure that the secondary toolbar is closed when Escape is pressed.
 | 
						|
    if (evt.keyCode !== /* Esc = */ 27) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // No control key pressed at all.
 | 
						|
  if (cmd === 0) {
 | 
						|
    let turnPage = 0,
 | 
						|
      turnOnlyIfPageFit = false;
 | 
						|
    switch (evt.keyCode) {
 | 
						|
      case 38: // up arrow
 | 
						|
        if (this.supportsCaretBrowsingMode) {
 | 
						|
          this.moveCaret(/* isUp = */ true, /* select = */ false);
 | 
						|
          handled = true;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      /* falls through */
 | 
						|
      case 33: // pg up
 | 
						|
        // vertical scrolling using arrow/pg keys
 | 
						|
        if (pdfViewer.isVerticalScrollbarEnabled) {
 | 
						|
          turnOnlyIfPageFit = true;
 | 
						|
        }
 | 
						|
        turnPage = -1;
 | 
						|
        break;
 | 
						|
      case 8: // backspace
 | 
						|
        if (!isViewerInPresentationMode) {
 | 
						|
          turnOnlyIfPageFit = true;
 | 
						|
        }
 | 
						|
        turnPage = -1;
 | 
						|
        break;
 | 
						|
      case 37: // left arrow
 | 
						|
        if (this.supportsCaretBrowsingMode) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
        // horizontal scrolling using arrow keys
 | 
						|
        if (pdfViewer.isHorizontalScrollbarEnabled) {
 | 
						|
          turnOnlyIfPageFit = true;
 | 
						|
        }
 | 
						|
      /* falls through */
 | 
						|
      case 75: // 'k'
 | 
						|
      case 80: // 'p'
 | 
						|
        turnPage = -1;
 | 
						|
        break;
 | 
						|
      case 27: // esc key
 | 
						|
        if (this.secondaryToolbar?.isOpen) {
 | 
						|
          this.secondaryToolbar.close();
 | 
						|
          handled = true;
 | 
						|
        }
 | 
						|
        if (!this.supportsIntegratedFind && this.findBar?.opened) {
 | 
						|
          this.findBar.close();
 | 
						|
          handled = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 40: // down arrow
 | 
						|
        if (this.supportsCaretBrowsingMode) {
 | 
						|
          this.moveCaret(/* isUp = */ false, /* select = */ false);
 | 
						|
          handled = true;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      /* falls through */
 | 
						|
      case 34: // pg down
 | 
						|
        // vertical scrolling using arrow/pg keys
 | 
						|
        if (pdfViewer.isVerticalScrollbarEnabled) {
 | 
						|
          turnOnlyIfPageFit = true;
 | 
						|
        }
 | 
						|
        turnPage = 1;
 | 
						|
        break;
 | 
						|
      case 32: // spacebar
 | 
						|
        if (!isViewerInPresentationMode) {
 | 
						|
          turnOnlyIfPageFit = true;
 | 
						|
        }
 | 
						|
        turnPage = 1;
 | 
						|
        break;
 | 
						|
      case 39: // right arrow
 | 
						|
        if (this.supportsCaretBrowsingMode) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
        // horizontal scrolling using arrow keys
 | 
						|
        if (pdfViewer.isHorizontalScrollbarEnabled) {
 | 
						|
          turnOnlyIfPageFit = true;
 | 
						|
        }
 | 
						|
      /* falls through */
 | 
						|
      case 74: // 'j'
 | 
						|
      case 78: // 'n'
 | 
						|
        turnPage = 1;
 | 
						|
        break;
 | 
						|
 | 
						|
      case 36: // home
 | 
						|
        if (isViewerInPresentationMode || this.page > 1) {
 | 
						|
          this.page = 1;
 | 
						|
          handled = true;
 | 
						|
          ensureViewerFocused = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case 35: // end
 | 
						|
        if (isViewerInPresentationMode || this.page < this.pagesCount) {
 | 
						|
          this.page = this.pagesCount;
 | 
						|
          handled = true;
 | 
						|
          ensureViewerFocused = true;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      case 83: // 's'
 | 
						|
        this.pdfCursorTools?.switchTool(CursorTool.SELECT);
 | 
						|
        break;
 | 
						|
      case 72: // 'h'
 | 
						|
        this.pdfCursorTools?.switchTool(CursorTool.HAND);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 82: // 'r'
 | 
						|
        this.rotatePages(90);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 115: // F4
 | 
						|
        this.pdfSidebar?.toggle();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (
 | 
						|
      turnPage !== 0 &&
 | 
						|
      (!turnOnlyIfPageFit || pdfViewer.currentScaleValue === "page-fit")
 | 
						|
    ) {
 | 
						|
      if (turnPage > 0) {
 | 
						|
        pdfViewer.nextPage();
 | 
						|
      } else {
 | 
						|
        pdfViewer.previousPage();
 | 
						|
      }
 | 
						|
      handled = true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // shift-key
 | 
						|
  if (cmd === 4) {
 | 
						|
    switch (evt.keyCode) {
 | 
						|
      case 32: // spacebar
 | 
						|
        if (
 | 
						|
          !isViewerInPresentationMode &&
 | 
						|
          pdfViewer.currentScaleValue !== "page-fit"
 | 
						|
        ) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        pdfViewer.previousPage();
 | 
						|
 | 
						|
        handled = true;
 | 
						|
        break;
 | 
						|
 | 
						|
      case 38: // up arrow
 | 
						|
        this.moveCaret(/* isUp = */ true, /* select = */ true);
 | 
						|
        handled = true;
 | 
						|
        break;
 | 
						|
      case 40: // down arrow
 | 
						|
        this.moveCaret(/* isUp = */ false, /* select = */ true);
 | 
						|
        handled = true;
 | 
						|
        break;
 | 
						|
      case 82: // 'r'
 | 
						|
        this.rotatePages(-90);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!handled && !isViewerInPresentationMode) {
 | 
						|
    // 33=Page Up  34=Page Down  35=End    36=Home
 | 
						|
    // 37=Left     38=Up         39=Right  40=Down
 | 
						|
    // 32=Spacebar
 | 
						|
    if (
 | 
						|
      (evt.keyCode >= 33 && evt.keyCode <= 40) ||
 | 
						|
      (evt.keyCode === 32 && curElementTagName !== "BUTTON")
 | 
						|
    ) {
 | 
						|
      ensureViewerFocused = true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) {
 | 
						|
    // The page container is not focused, but a page navigation key has been
 | 
						|
    // pressed. Change the focus to the viewer container to make sure that
 | 
						|
    // navigation by keyboard works as expected.
 | 
						|
    pdfViewer.focus();
 | 
						|
  }
 | 
						|
 | 
						|
  if (handled) {
 | 
						|
    evt.preventDefault();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function beforeUnload(evt) {
 | 
						|
  evt.preventDefault();
 | 
						|
  evt.returnValue = "";
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
export { PDFViewerApplication };
 |