| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041 | /* 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. */import {  animationStarted,  apiPageLayoutToViewerModes,  apiPageModeToSidebarView,  AutoPrintRegExp,  DEFAULT_SCALE_VALUE,  getActiveOrFocusedElement,  isValidRotation,  isValidScrollMode,  isValidSpreadMode,  normalizeWheelEventDirection,  parseQueryString,  ProgressBar,  RendererType,  RenderingStates,  ScrollMode,  SidebarView,  SpreadMode,  TextLayerMode,} from "./ui_utils.js";import {  AnnotationEditorType,  build,  createPromiseCapability,  getDocument,  getFilenameFromUrl,  getPdfFilenameFromUrl,  GlobalWorkerOptions,  InvalidPDFException,  isDataScheme,  isPdfFile,  loadScript,  MissingPDFException,  OPS,  PDFWorker,  shadow,  UnexpectedResponseException,  version,} from "pdfjs-lib";import { AppOptions, OptionKind } from "./app_options.js";import { AutomationEventBus, EventBus } from "./event_utils.js";import { CursorTool, PDFCursorTools } from "./pdf_cursor_tools.js";import { LinkTarget, PDFLinkService } from "./pdf_link_service.js";import { AnnotationEditorParams } from "./annotation_editor_params.js";import { OverlayManager } from "./overlay_manager.js";import { PasswordPrompt } from "./password_prompt.js";import { PDFAttachmentViewer } from "./pdf_attachment_viewer.js";import { PDFDocumentProperties } from "./pdf_document_properties.js";import { PDFFindBar } from "./pdf_find_bar.js";import { PDFFindController } from "./pdf_find_controller.js";import { PDFHistory } from "./pdf_history.js";import { PDFLayerViewer } from "./pdf_layer_viewer.js";import { PDFOutlineViewer } from "./pdf_outline_viewer.js";import { PDFPresentationMode } from "./pdf_presentation_mode.js";import { PDFRenderingQueue } from "./pdf_rendering_queue.js";import { PDFScriptingManager } from "./pdf_scripting_manager.js";import { PDFSidebar } from "./pdf_sidebar.js";import { PDFSidebarResizer } from "./pdf_sidebar_resizer.js";import { PDFThumbnailViewer } from "./pdf_thumbnail_viewer.js";import { PDFViewer } from "./pdf_viewer.js";import { SecondaryToolbar } from "./secondary_toolbar.js";import { Toolbar } from "./toolbar.js";import { ViewHistory } from "./view_history.js";const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; // msconst FORCE_PAGES_LOADED_TIMEOUT = 10000; // msconst WHEEL_ZOOM_DISABLED_TIMEOUT = 1000; // msconst ViewOnLoad = {  UNKNOWN: -1,  PREVIOUS: 0, // Default value.  INITIAL: 1,};const ViewerCssTheme = {  AUTOMATIC: 0, // Default value.  LIGHT: 1,  DARK: 2,};class DefaultExternalServices {  constructor() {    throw new Error("Cannot initialize DefaultExternalServices.");  }  static updateFindControlState(data) {}  static updateFindMatchesCount(data) {}  static initPassiveLoading(callbacks) {}  static reportTelemetry(data) {}  static createDownloadManager() {    throw new Error("Not implemented: createDownloadManager");  }  static createPreferences() {    throw new Error("Not implemented: createPreferences");  }  static createL10n(options) {    throw new Error("Not implemented: createL10n");  }  static createScripting(options) {    throw new Error("Not implemented: createScripting");  }  static get supportsIntegratedFind() {    return shadow(this, "supportsIntegratedFind", false);  }  static get supportsDocumentFonts() {    return shadow(this, "supportsDocumentFonts", true);  }  static get supportedMouseWheelZoomModifierKeys() {    return shadow(this, "supportedMouseWheelZoomModifierKeys", {      ctrlKey: true,      metaKey: true,    });  }  static get isInAutomation() {    return shadow(this, "isInAutomation", false);  }  static updateEditorStates(data) {    throw new Error("Not implemented: updateEditorStates");  }}const PDFViewerApplication = {  initialBookmark: document.location.hash.substring(1),  _initializedCapability: createPromiseCapability(),  appConfig: null,  pdfDocument: null,  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 {PDFSidebarResizer} */  pdfSidebarResizer: 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: null,  /** @type {Toolbar} */  toolbar: null,  /** @type {SecondaryToolbar} */  secondaryToolbar: null,  /** @type {EventBus} */  eventBus: null,  /** @type {IL10n} */  l10n: null,  /** @type {AnnotationEditorParams} */  annotationEditorParams: null,  isInitialViewSet: false,  downloadComplete: false,  isViewerEmbedded: window.parent !== window,  url: "",  baseUrl: "",  _downloadUrl: "",  externalServices: DefaultExternalServices,  _boundEvents: Object.create(null),  documentInfo: null,  metadata: null,  _contentDispositionFilename: null,  _contentLength: null,  _saveInProgress: false,  _wheelUnusedTicks: 0,  _PDFBug: null,  _hasAnnotationEditors: false,  _title: document.title,  _printAnnotationStoragePromise: null,  // Called once when the document is loaded.  async initialize(appConfig) {    this.preferences = this.externalServices.createPreferences();    this.appConfig = appConfig;    await this._readPreferences();    await this._parseHashParameters();    this._forceCssTheme();    await this._initializeL10n();    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();    // We can start UI localization now.    const appContainer = appConfig.appContainer || document.documentElement;    this.l10n.translate(appContainer).then(() => {      // Dispatch the 'localized' event on the `eventBus` once the viewer      // has been fully initialized and translated.      this.eventBus.dispatch("localized", { source: this });    });    this._initializedCapability.resolve();  },  /**   * @private   */  async _readPreferences() {    if (      typeof PDFJSDev === "undefined" ||      PDFJSDev.test("!PRODUCTION || GENERIC")    ) {      if (AppOptions.get("disablePreferences")) {        // Give custom implementations of the default viewer a simpler way to        // opt-out of having the `Preferences` override existing `AppOptions`.        return;      }      if (AppOptions._hasUserOptions()) {        console.warn(          "_readPreferences: The Preferences may override manually set AppOptions; " +            'please use the "disablePreferences"-option in order to prevent that.'        );      }    }    try {      AppOptions.setAll(await this.preferences.getAll());    } catch (reason) {      console.error(`_readPreferences: "${reason?.message}".`);    }  },  /**   * Potentially parse special debugging flags in the hash section of the URL.   * @private   */  async _parseHashParameters() {    if (!AppOptions.get("pdfBugEnabled")) {      return;    }    const hash = document.location.hash.substring(1);    if (!hash) {      return;    }    const { mainContainer, viewerContainer } = this.appConfig,      params = parseQueryString(hash);    if (params.get("disableworker") === "true") {      try {        await loadFakeWorker();      } catch (ex) {        console.error(`_parseHashParameters: "${ex.message}".`);      }    }    if (params.has("disablerange")) {      AppOptions.set("disableRange", params.get("disablerange") === "true");    }    if (params.has("disablestream")) {      AppOptions.set("disableStream", params.get("disablestream") === "true");    }    if (params.has("disableautofetch")) {      AppOptions.set(        "disableAutoFetch",        params.get("disableautofetch") === "true"      );    }    if (params.has("disablefontface")) {      AppOptions.set(        "disableFontFace",        params.get("disablefontface") === "true"      );    }    if (params.has("disablehistory")) {      AppOptions.set("disableHistory", params.get("disablehistory") === "true");    }    if (params.has("verbosity")) {      AppOptions.set("verbosity", params.get("verbosity") | 0);    }    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);            this._PDFBug.loadCSS();          } catch (ex) {            console.error(`_parseHashParameters: "${ex.message}".`);          }          break;      }    }    if (params.has("pdfbug")) {      AppOptions.set("pdfBug", true);      AppOptions.set("fontExtraProperties", true);      const enabled = params.get("pdfbug").split(",");      try {        await loadPDFBug(this);        this._PDFBug.init({ OPS }, mainContainer, enabled);      } catch (ex) {        console.error(`_parseHashParameters: "${ex.message}".`);      }    }    // It is not possible to change locale for the (various) extension builds.    if (      (typeof PDFJSDev === "undefined" ||        PDFJSDev.test("!PRODUCTION || GENERIC")) &&      params.has("locale")    ) {      AppOptions.set("locale", params.get("locale"));    }  },  /**   * @private   */  async _initializeL10n() {    this.l10n = this.externalServices.createL10n(      typeof PDFJSDev === "undefined" || PDFJSDev.test("!PRODUCTION || GENERIC")        ? { locale: AppOptions.get("locale") }        : null    );    const dir = await this.l10n.getDirection();    document.getElementsByTagName("html")[0].dir = dir;  },  /**   * @private   */  _forceCssTheme() {    const cssTheme = AppOptions.get("viewerCssTheme");    if (      cssTheme === ViewerCssTheme.AUTOMATIC ||      !Object.values(ViewerCssTheme).includes(cssTheme)    ) {      return;    }    try {      const styleSheet = document.styleSheets[0];      const cssRules = styleSheet?.cssRules || [];      for (let i = 0, ii = cssRules.length; i < ii; i++) {        const rule = cssRules[i];        if (          rule instanceof CSSMediaRule &&          rule.media?.[0] === "(prefers-color-scheme: dark)"        ) {          if (cssTheme === ViewerCssTheme.LIGHT) {            styleSheet.deleteRule(i);            return;          }          // cssTheme === ViewerCssTheme.DARK          const darkRules =            /^@media \(prefers-color-scheme: dark\) {\n\s*([\w\s-.,:;/\\{}()]+)\n}$/.exec(              rule.cssText            );          if (darkRules?.[1]) {            styleSheet.deleteRule(i);            styleSheet.insertRule(darkRules[1], i);          }          return;        }      }    } catch (reason) {      console.error(`_forceCssTheme: "${reason?.message}".`);    }  },  /**   * @private   */  async _initializeViewerComponents() {    const { appConfig, externalServices } = this;    const eventBus = externalServices.isInAutomation      ? new AutomationEventBus()      : new EventBus();    this.eventBus = eventBus;    this.overlayManager = new OverlayManager();    const pdfRenderingQueue = new PDFRenderingQueue();    pdfRenderingQueue.onIdle = this._cleanup.bind(this);    this.pdfRenderingQueue = pdfRenderingQueue;    const pdfLinkService = new PDFLinkService({      eventBus,      externalLinkTarget: AppOptions.get("externalLinkTarget"),      externalLinkRel: AppOptions.get("externalLinkRel"),      ignoreDestinationZoom: AppOptions.get("ignoreDestinationZoom"),    });    this.pdfLinkService = pdfLinkService;    const downloadManager = externalServices.createDownloadManager();    this.downloadManager = downloadManager;    const findController = new PDFFindController({      linkService: pdfLinkService,      eventBus,    });    this.findController = findController;    const pdfScriptingManager = new PDFScriptingManager({      eventBus,      sandboxBundleSrc:        typeof PDFJSDev === "undefined" ||        PDFJSDev.test("!PRODUCTION || GENERIC || CHROME")          ? AppOptions.get("sandboxBundleSrc")          : null,      scriptingFactory: externalServices,      docPropertiesLookup: this._scriptingDocProperties.bind(this),    });    this.pdfScriptingManager = pdfScriptingManager;    const container = appConfig.mainContainer,      viewer = appConfig.viewerContainer;    const annotationEditorMode = AppOptions.get("annotationEditorMode");    const pageColors =      AppOptions.get("forcePageColors") ||      window.matchMedia("(forced-colors: active)").matches        ? {            background: AppOptions.get("pageColorsBackground"),            foreground: AppOptions.get("pageColorsForeground"),          }        : null;    this.pdfViewer = new PDFViewer({      container,      viewer,      eventBus,      renderingQueue: pdfRenderingQueue,      linkService: pdfLinkService,      downloadManager,      findController,      scriptingManager:        AppOptions.get("enableScripting") && pdfScriptingManager,      renderer:        typeof PDFJSDev === "undefined" ||        PDFJSDev.test("!PRODUCTION || GENERIC")          ? AppOptions.get("renderer")          : null,      l10n: this.l10n,      textLayerMode: AppOptions.get("textLayerMode"),      annotationMode: AppOptions.get("annotationMode"),      annotationEditorMode,      imageResourcesPath: AppOptions.get("imageResourcesPath"),      enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),      useOnlyCssZoom: AppOptions.get("useOnlyCssZoom"),      isOffscreenCanvasSupported: AppOptions.get("isOffscreenCanvasSupported"),      maxCanvasPixels: AppOptions.get("maxCanvasPixels"),      enablePermissions: AppOptions.get("enablePermissions"),      pageColors,    });    pdfRenderingQueue.setViewer(this.pdfViewer);    pdfLinkService.setViewer(this.pdfViewer);    pdfScriptingManager.setViewer(this.pdfViewer);    if (appConfig.sidebar?.thumbnailView) {      this.pdfThumbnailViewer = new PDFThumbnailViewer({        container: appConfig.sidebar.thumbnailView,        eventBus,        renderingQueue: pdfRenderingQueue,        linkService: pdfLinkService,        l10n: this.l10n,        pageColors,      });      pdfRenderingQueue.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: pdfLinkService,        eventBus,      });      pdfLinkService.setHistory(this.pdfHistory);    }    if (!this.supportsIntegratedFind && appConfig.findBar) {      this.findBar = new PDFFindBar(appConfig.findBar, eventBus, this.l10n);    }    if (appConfig.annotationEditorParams) {      if (annotationEditorMode !== AnnotationEditorType.DISABLE) {        this.annotationEditorParams = new AnnotationEditorParams(          appConfig.annotationEditorParams,          eventBus        );      } else {        for (const id of ["editorModeButtons", "editorModeSeparator"]) {          document.getElementById(id)?.classList.add("hidden");        }      }    }    if (appConfig.documentProperties) {      this.pdfDocumentProperties = new PDFDocumentProperties(        appConfig.documentProperties,        this.overlayManager,        eventBus,        this.l10n,        /* fileNameLookup = */ () => {          return this._docFilename;        }      );    }    this.pdfCursorTools = new PDFCursorTools({      container,      eventBus,      cursorToolOnLoad: AppOptions.get("cursorToolOnLoad"),    });    if (appConfig.toolbar) {      this.toolbar = new Toolbar(appConfig.toolbar, eventBus, this.l10n);    }    if (appConfig.secondaryToolbar) {      this.secondaryToolbar = new SecondaryToolbar(        appConfig.secondaryToolbar,        eventBus,        this.externalServices      );    }    if (this.supportsFullscreen) {      this.pdfPresentationMode = new PDFPresentationMode({        container,        pdfViewer: this.pdfViewer,        eventBus,      });    }    if (appConfig.passwordOverlay) {      this.passwordPrompt = new PasswordPrompt(        appConfig.passwordOverlay,        this.overlayManager,        this.l10n,        this.isViewerEmbedded      );    }    if (appConfig.sidebar?.outlineView) {      this.pdfOutlineViewer = new PDFOutlineViewer({        container: appConfig.sidebar.outlineView,        eventBus,        linkService: pdfLinkService,        downloadManager,      });    }    if (appConfig.sidebar?.attachmentsView) {      this.pdfAttachmentViewer = new PDFAttachmentViewer({        container: appConfig.sidebar.attachmentsView,        eventBus,        downloadManager,      });    }    if (appConfig.sidebar?.layersView) {      this.pdfLayerViewer = new PDFLayerViewer({        container: appConfig.sidebar.layersView,        eventBus,        l10n: this.l10n,      });    }    if (appConfig.sidebar) {      this.pdfSidebar = new PDFSidebar({        elements: appConfig.sidebar,        pdfViewer: this.pdfViewer,        pdfThumbnailViewer: this.pdfThumbnailViewer,        eventBus,        l10n: this.l10n,      });      this.pdfSidebar.onToggled = this.forceRendering.bind(this);      this.pdfSidebarResizer = new PDFSidebarResizer(        appConfig.sidebarResizer,        eventBus,        this.l10n      );    }  },  run(config) {    this.initialize(config).then(webViewerInitialized);  },  get initialized() {    return this._initializedCapability.settled;  },  get initializedPromise() {    return this._initializedCapability.promise;  },  zoomIn(steps) {    if (this.pdfViewer.isInPresentationMode) {      return;    }    this.pdfViewer.increaseScale(steps, {      delay: AppOptions.get("defaultZoomDelay"),    });  },  zoomOut(steps) {    if (this.pdfViewer.isInPresentationMode) {      return;    }    this.pdfViewer.decreaseScale(steps, {      delay: AppOptions.get("defaultZoomDelay"),    });  },  zoomReset() {    if (this.pdfViewer.isInPresentationMode) {      return;    }    this.pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;  },  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 PDFPrintServiceFactory.instance.supportsPrinting;  },  get supportsFullscreen() {    return shadow(this, "supportsFullscreen", document.fullscreenEnabled);  },  get supportsIntegratedFind() {    return this.externalServices.supportsIntegratedFind;  },  get supportsDocumentFonts() {    return this.externalServices.supportsDocumentFonts;  },  get loadingBar() {    const barElement = document.getElementById("loadingBar");    const bar = barElement ? new ProgressBar(barElement) : null;    return shadow(this, "loadingBar", bar);  },  get supportedMouseWheelZoomModifierKeys() {    return this.externalServices.supportedMouseWheelZoomModifierKeys;  },  initPassiveLoading() {    if (      typeof PDFJSDev === "undefined" ||      !PDFJSDev.test("MOZCENTRAL || CHROME")    ) {      throw new Error("Not implemented: initPassiveLoading");    }    this.externalServices.initPassiveLoading({      onOpenWithTransport: (url, length, transport) => {        this.open(url, { length, range: transport });      },      onOpenWithData: (data, contentDispositionFilename) => {        if (isPdfFile(contentDispositionFilename)) {          this._contentDispositionFilename = contentDispositionFilename;        }        this.open(data);      },      onOpenWithURL: (url, length, originalUrl) => {        const file = originalUrl !== undefined ? { url, originalUrl } : url;        const args = length !== undefined ? { length } : null;        this.open(file, args);      },      onError: err => {        this.l10n.get("loading_error").then(msg => {          this._documentError(msg, err);        });      },      onProgress: (loaded, total) => {        this.progress(loaded / total);      },    });  },  setTitleUsingUrl(url = "", downloadUrl = null) {    this.url = url;    this.baseUrl = url.split("#")[0];    if (downloadUrl) {      this._downloadUrl =        downloadUrl === url ? this.baseUrl : downloadUrl.split("#")[0];    }    if (isDataScheme(url)) {      this._hideViewBookmark();    }    let title = getPdfFilenameFromUrl(url, "");    if (!title) {      try {        title = decodeURIComponent(getFilenameFromUrl(url)) || url;      } catch (ex) {        // decodeURIComponent may throw URIError,        // fall back to using the unprocessed url in that case        title = url;      }    }    this.setTitle(title);  },  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}`;  },  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);  },  /**   * @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")) &&      this.pdfDocument?.annotationStorage.size > 0 &&      this._annotationStorageModified    ) {      try {        // Trigger saving, to prevent data loss in forms; see issue 12257.        await this.save();      } catch (reason) {        // 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.downloadComplete = 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.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 PDF document specified by URL or array with additional arguments.   * @param {string|TypedArray|ArrayBuffer} file - PDF location or binary data.   * @param {Object} [args] - Additional arguments for the getDocument call,   *                          e.g. HTTP headers ('httpHeaders') or alternative   *                          data transport ('range').   * @returns {Promise} - Returns the promise, which is resolved when document   *                      is opened.   */  async open(file, 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 workerParameters = AppOptions.getAll(OptionKind.WORKER);    for (const key in workerParameters) {      GlobalWorkerOptions[key] = workerParameters[key];    }    const parameters = Object.create(null);    if (typeof file === "string") {      // URL      this.setTitleUsingUrl(file, /* downloadUrl = */ file);      parameters.url = file;    } else if (file && "byteLength" in file) {      // ArrayBuffer      parameters.data = file;    } else if (file.url && file.originalUrl) {      this.setTitleUsingUrl(file.originalUrl, /* downloadUrl = */ file.url);      parameters.url = file.url;    }    // Set the necessary API parameters, using the available options.    const apiParameters = AppOptions.getAll(OptionKind.API);    for (const key in apiParameters) {      let value = apiParameters[key];      if (key === "docBaseUrl" && !value) {        if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) {          value = document.URL.split("#")[0];        } else if (PDFJSDev.test("MOZCENTRAL || CHROME")) {          value = this.baseUrl;        }      }      parameters[key] = value;    }    // Finally, update the API parameters with the arguments (if they exist).    if (args) {      for (const key in args) {        parameters[key] = args[key];      }    }    const loadingTask = getDocument(parameters);    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 = "loading_error";        if (reason instanceof InvalidPDFException) {          key = "invalid_file_error";        } else if (reason instanceof MissingPDFException) {          key = "missing_file_error";        } else if (reason instanceof UnexpectedResponseException) {          key = "unexpected_response_error";        }        return this.l10n.get(key).then(msg => {          this._documentError(msg, { message: reason?.message });          throw reason;        });      }    );  },  /**   * @private   */  _ensureDownloadComplete() {    if (this.pdfDocument && this.downloadComplete) {      return;    }    throw new Error("PDF document not downloaded.");  },  async download() {    const url = this._downloadUrl,      filename = this._docFilename;    try {      this._ensureDownloadComplete();      const data = await this.pdfDocument.getData();      const blob = new Blob([data], { type: "application/pdf" });      await this.downloadManager.download(blob, url, filename);    } catch (reason) {      // When the PDF document isn't ready, or the PDF file is still      // downloading, simply download using the URL.      await this.downloadManager.downloadUrl(url, filename);    }  },  async save() {    if (this._saveInProgress) {      return;    }    this._saveInProgress = true;    await this.pdfScriptingManager.dispatchWillSave();    const url = this._downloadUrl,      filename = this._docFilename;    try {      this._ensureDownloadComplete();      const data = await this.pdfDocument.saveDocument();      const blob = new Blob([data], { type: "application/pdf" });      await this.downloadManager.download(blob, url, filename);    } catch (reason) {      // When the PDF document isn't ready, or the PDF file is still      // downloading, simply fallback to a "regular" download.      console.error(`Error when saving the document: ${reason.message}`);      await this.download();    } finally {      await this.pdfScriptingManager.dispatchDidSave();      this._saveInProgress = false;    }    if (this._hasAnnotationEditors) {      this.externalServices.reportTelemetry({        type: "editing",        data: { type: "save" },      });    }  },  downloadOrSave() {    if (this.pdfDocument?.annotationStorage.size > 0) {      this.save();    } else {      this.download();    }  },  /**   * Report the error; used for errors affecting loading and/or parsing of   * the entire PDF document.   */  _documentError(message, moreInfo = null) {    this._unblockDocumentLoadEvent();    this._otherError(message, 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} message - A message that is human readable.   * @param {Object} [moreInfo] - Further information about the error that is   *                              more technical. Should have a 'message' and   *                              optionally a 'stack' property.   */  _otherError(message, moreInfo = null) {    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")}`);  },  progress(level) {    if (!this.loadingBar || this.downloadComplete) {      // Don't accidentally show the loading bar again when the entire file has      // already been fetched (only an issue when disableAutoFetch is enabled).      return;    }    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 (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.    const disableAutoFetch =      this.pdfDocument?.loadingParams.disableAutoFetch ??      AppOptions.get("disableAutoFetch");    if (!disableAutoFetch || isNaN(percent)) {      return;    }    if (this.disableAutoFetchLoadingBarTimeout) {      clearTimeout(this.disableAutoFetchLoadingBarTimeout);      this.disableAutoFetchLoadingBarTimeout = null;    }    this.loadingBar.show();    this.disableAutoFetchLoadingBarTimeout = setTimeout(() => {      this.loadingBar.hide();      this.disableAutoFetchLoadingBarTimeout = null;    }, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT);  },  load(pdfDocument) {    this.pdfDocument = pdfDocument;    pdfDocument.getDownloadInfo().then(({ length }) => {      this._contentLength = length; // Ensure that the correct length is used.      this.downloadComplete = true;      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(function () {      /* Avoid breaking initial rendering; ignoring errors. */    });    const pageModePromise = pdfDocument.getPageMode().catch(function () {      /* Avoid breaking initial rendering; ignoring errors. */    });    const openActionPromise = pdfDocument.getOpenAction().catch(function () {      /* Avoid breaking initial rendering; ignoring errors. */    });    this.toolbar?.setPagesCount(pdfDocument.numPages, false);    this.secondaryToolbar?.setPagesCount(pdfDocument.numPages);    let baseDocumentUrl;    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {      baseDocumentUrl = null;    } else if (PDFJSDev.test("MOZCENTRAL")) {      baseDocumentUrl = this.baseUrl;    } else if (PDFJSDev.test("CHROME")) {      baseDocumentUrl = location.href.split("#")[0];    }    if (baseDocumentUrl && isDataScheme(baseDocumentUrl)) {      // Ignore "data:"-URLs for performance reasons, even though it may cause      // internal links to not work perfectly in all cases (see bug 1803050).      baseDocumentUrl = null;    }    this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);    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. */        return Object.create(null);      });    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);          }          // NOTE: Always ignore the pageLayout in GeckoView since there's          // no UI available to change Scroll/Spread modes for the user.          if (            (typeof PDFJSDev === "undefined" || !PDFJSDev.test("GECKOVIEW")) &&            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 });          // Make all navigation keys work on document load,          // unless the viewer is embedded in a web page.          if (!this.isViewerEmbedded) {            pdfViewer.focus();          }          // 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.l10n.get("loading_error").then(msg => {          this._documentError(msg, { message: reason?.message });        });      }    );    onePageRendered.then(data => {      this.externalServices.reportTelemetry({        type: "pageInfo",        timestamp: data.timestamp,      });      pdfDocument.getOutline().then(outline => {        if (pdfDocument !== this.pdfDocument) {          return; // The document was closed while the outline resolved.        }        this.pdfOutlineViewer?.render({ outline, pdfDocument });      });      pdfDocument.getAttachments().then(attachments => {        if (pdfDocument !== this.pdfDocument) {          return; // The document was closed while the attachments resolved.        }        this.pdfAttachmentViewer?.render({ attachments });      });      // 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, javaScript] = await Promise.all([      openActionPromise,      !this.pdfViewer.enableScripting ? pdfDocument.getJavaScript() : null,    ]);    if (pdfDocument !== this.pdfDocument) {      return; // The document was closed while the auto print data resolved.    }    let triggerAutoPrint = false;    if (openAction?.action === "Print") {      triggerAutoPrint = true;    }    if (javaScript) {      javaScript.some(js => {        if (!js) {          // Don't warn/fallback for empty JavaScript actions.          return false;        }        console.warn("Warning: JavaScript support is not enabled");        return true;      });      if (!triggerAutoPrint) {        // Hack to support auto printing.        for (const js of javaScript) {          if (js && AutoPrintRegExp.test(js)) {            triggerAutoPrint = true;            break;          }        }      }    }    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.    }    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} ` +        `${(info.Producer || "-").trim()} / ${(info.Creator || "-").trim()}] ` +        `(PDF.js: ${version || "?"} [${build || "?"}])`    );    let pdfTitle = info.Title;    const metadataTitle = metadata?.get("dc:title");    if (metadataTitle) {      // 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 (        metadataTitle !== "Untitled" &&        !/[\uFFF0-\uFFFF]/g.test(metadataTitle)      ) {        pdfTitle = metadataTitle;      }    }    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) {    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();      if (typeStr) {        this.externalServices.reportTelemetry({          type: "editing",          data: { type: typeStr },        });      }    };  },  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();    if (      typeof PDFJSDev === "undefined" ||      PDFJSDev.test("!PRODUCTION || GENERIC")    ) {      // We don't want to remove fonts used by active page SVGs.      this.pdfDocument.cleanup(        /* keepLoadedFonts = */ this.pdfViewer.renderer === RendererType.SVG      );    } else {      this.pdfDocument.cleanup();    }  },  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(() => {        return 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.l10n.get("printing_not_supported").then(msg => {        this._otherError(msg);      });      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("printing_not_ready").then(msg => {        // eslint-disable-next-line no-alert        window.alert(msg);      });      return;    }    const pagesOverview = this.pdfViewer.getPagesOverview();    const printContainer = this.appConfig.printContainer;    const printResolution = AppOptions.get("printResolution");    const optionalContentConfigPromise =      this.pdfViewer.optionalContentConfigPromise;    const printService = PDFPrintServiceFactory.instance.createPrintService(      this.pdfDocument,      pagesOverview,      printContainer,      printResolution,      optionalContentConfigPromise,      this._printAnnotationStoragePromise,      this.l10n    );    this.printService = printService;    this.forceRendering();    // Disable the editor-indicator during printing (fixes bug 1790552).    this.setTitle();    printService.layout();    if (this._hasAnnotationEditors) {      this.externalServices.reportTelemetry({        type: "editing",        data: { type: "print" },      });    }  },  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();  },  triggerPrinting() {    if (!this.supportsPrinting) {      return;    }    window.print();  },  bindEvents() {    const { eventBus, _boundEvents } = this;    _boundEvents.beforePrint = this.beforePrint.bind(this);    _boundEvents.afterPrint = this.afterPrint.bind(this);    eventBus._on("resize", webViewerResize);    eventBus._on("hashchange", webViewerHashchange);    eventBus._on("beforeprint", _boundEvents.beforePrint);    eventBus._on("afterprint", _boundEvents.afterPrint);    eventBus._on("pagerender", webViewerPageRender);    eventBus._on("pagerendered", webViewerPageRendered);    eventBus._on("updateviewarea", webViewerUpdateViewarea);    eventBus._on("pagechanging", webViewerPageChanging);    eventBus._on("scalechanging", webViewerScaleChanging);    eventBus._on("rotationchanging", webViewerRotationChanging);    eventBus._on("sidebarviewchanged", webViewerSidebarViewChanged);    eventBus._on("pagemode", webViewerPageMode);    eventBus._on("namedaction", webViewerNamedAction);    eventBus._on("presentationmodechanged", webViewerPresentationModeChanged);    eventBus._on("presentationmode", webViewerPresentationMode);    eventBus._on(      "switchannotationeditormode",      webViewerSwitchAnnotationEditorMode    );    eventBus._on(      "switchannotationeditorparams",      webViewerSwitchAnnotationEditorParams    );    eventBus._on("print", webViewerPrint);    eventBus._on("download", webViewerDownload);    eventBus._on("firstpage", webViewerFirstPage);    eventBus._on("lastpage", webViewerLastPage);    eventBus._on("nextpage", webViewerNextPage);    eventBus._on("previouspage", webViewerPreviousPage);    eventBus._on("zoomin", webViewerZoomIn);    eventBus._on("zoomout", webViewerZoomOut);    eventBus._on("zoomreset", webViewerZoomReset);    eventBus._on("pagenumberchanged", webViewerPageNumberChanged);    eventBus._on("scalechanged", webViewerScaleChanged);    eventBus._on("rotatecw", webViewerRotateCw);    eventBus._on("rotateccw", webViewerRotateCcw);    eventBus._on("optionalcontentconfig", webViewerOptionalContentConfig);    eventBus._on("switchscrollmode", webViewerSwitchScrollMode);    eventBus._on("scrollmodechanged", webViewerScrollModeChanged);    eventBus._on("switchspreadmode", webViewerSwitchSpreadMode);    eventBus._on("spreadmodechanged", webViewerSpreadModeChanged);    eventBus._on("documentproperties", webViewerDocumentProperties);    eventBus._on("findfromurlhash", webViewerFindFromUrlHash);    eventBus._on("updatefindmatchescount", webViewerUpdateFindMatchesCount);    eventBus._on("updatefindcontrolstate", webViewerUpdateFindControlState);    if (AppOptions.get("pdfBug")) {      _boundEvents.reportPageStatsPDFBug = reportPageStatsPDFBug;      eventBus._on("pagerendered", _boundEvents.reportPageStatsPDFBug);      eventBus._on("pagechanging", _boundEvents.reportPageStatsPDFBug);    }    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {      eventBus._on("fileinputchange", webViewerFileInputChange);      eventBus._on("openfile", webViewerOpenFile);    }    if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {      eventBus._on(        "annotationeditorstateschanged",        webViewerAnnotationEditorStatesChanged      );    }  },  bindWindowEvents() {    const { eventBus, _boundEvents } = this;    function addWindowResolutionChange(evt = null) {      if (evt) {        webViewerResolutionChange(evt);      }      const mediaQueryList = window.matchMedia(        `(resolution: ${window.devicePixelRatio || 1}dppx)`      );      mediaQueryList.addEventListener("change", addWindowResolutionChange, {        once: true,      });      if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {        return;      }      _boundEvents.removeWindowResolutionChange ||= function () {        mediaQueryList.removeEventListener("change", addWindowResolutionChange);        _boundEvents.removeWindowResolutionChange = null;      };    }    addWindowResolutionChange();    _boundEvents.windowResize = () => {      eventBus.dispatch("resize", { source: window });    };    _boundEvents.windowHashChange = () => {      eventBus.dispatch("hashchange", {        source: window,        hash: document.location.hash.substring(1),      });    };    _boundEvents.windowBeforePrint = () => {      eventBus.dispatch("beforeprint", { source: window });    };    _boundEvents.windowAfterPrint = () => {      eventBus.dispatch("afterprint", { source: window });    };    _boundEvents.windowUpdateFromSandbox = event => {      eventBus.dispatch("updatefromsandbox", {        source: window,        detail: event.detail,      });    };    window.addEventListener("visibilitychange", webViewerVisibilityChange);    window.addEventListener("wheel", webViewerWheel, { passive: false });    window.addEventListener("touchstart", webViewerTouchStart, {      passive: false,    });    window.addEventListener("click", webViewerClick);    window.addEventListener("keydown", webViewerKeyDown);    window.addEventListener("resize", _boundEvents.windowResize);    window.addEventListener("hashchange", _boundEvents.windowHashChange);    window.addEventListener("beforeprint", _boundEvents.windowBeforePrint);    window.addEventListener("afterprint", _boundEvents.windowAfterPrint);    window.addEventListener(      "updatefromsandbox",      _boundEvents.windowUpdateFromSandbox    );  },  unbindEvents() {    if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {      throw new Error("Not implemented: unbindEvents");    }    const { eventBus, _boundEvents } = this;    eventBus._off("resize", webViewerResize);    eventBus._off("hashchange", webViewerHashchange);    eventBus._off("beforeprint", _boundEvents.beforePrint);    eventBus._off("afterprint", _boundEvents.afterPrint);    eventBus._off("pagerender", webViewerPageRender);    eventBus._off("pagerendered", webViewerPageRendered);    eventBus._off("updateviewarea", webViewerUpdateViewarea);    eventBus._off("pagechanging", webViewerPageChanging);    eventBus._off("scalechanging", webViewerScaleChanging);    eventBus._off("rotationchanging", webViewerRotationChanging);    eventBus._off("sidebarviewchanged", webViewerSidebarViewChanged);    eventBus._off("pagemode", webViewerPageMode);    eventBus._off("namedaction", webViewerNamedAction);    eventBus._off("presentationmodechanged", webViewerPresentationModeChanged);    eventBus._off("presentationmode", webViewerPresentationMode);    eventBus._off("print", webViewerPrint);    eventBus._off("download", webViewerDownload);    eventBus._off("firstpage", webViewerFirstPage);    eventBus._off("lastpage", webViewerLastPage);    eventBus._off("nextpage", webViewerNextPage);    eventBus._off("previouspage", webViewerPreviousPage);    eventBus._off("zoomin", webViewerZoomIn);    eventBus._off("zoomout", webViewerZoomOut);    eventBus._off("zoomreset", webViewerZoomReset);    eventBus._off("pagenumberchanged", webViewerPageNumberChanged);    eventBus._off("scalechanged", webViewerScaleChanged);    eventBus._off("rotatecw", webViewerRotateCw);    eventBus._off("rotateccw", webViewerRotateCcw);    eventBus._off("optionalcontentconfig", webViewerOptionalContentConfig);    eventBus._off("switchscrollmode", webViewerSwitchScrollMode);    eventBus._off("scrollmodechanged", webViewerScrollModeChanged);    eventBus._off("switchspreadmode", webViewerSwitchSpreadMode);    eventBus._off("spreadmodechanged", webViewerSpreadModeChanged);    eventBus._off("documentproperties", webViewerDocumentProperties);    eventBus._off("findfromurlhash", webViewerFindFromUrlHash);    eventBus._off("updatefindmatchescount", webViewerUpdateFindMatchesCount);    eventBus._off("updatefindcontrolstate", webViewerUpdateFindControlState);    if (_boundEvents.reportPageStatsPDFBug) {      eventBus._off("pagerendered", _boundEvents.reportPageStatsPDFBug);      eventBus._off("pagechanging", _boundEvents.reportPageStatsPDFBug);      _boundEvents.reportPageStatsPDFBug = null;    }    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {      eventBus._off("fileinputchange", webViewerFileInputChange);      eventBus._off("openfile", webViewerOpenFile);    }    _boundEvents.beforePrint = null;    _boundEvents.afterPrint = null;  },  unbindWindowEvents() {    if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {      throw new Error("Not implemented: unbindWindowEvents");    }    const { _boundEvents } = this;    window.removeEventListener("visibilitychange", webViewerVisibilityChange);    window.removeEventListener("wheel", webViewerWheel, { passive: false });    window.removeEventListener("touchstart", webViewerTouchStart, {      passive: false,    });    window.removeEventListener("click", webViewerClick);    window.removeEventListener("keydown", webViewerKeyDown);    window.removeEventListener("resize", _boundEvents.windowResize);    window.removeEventListener("hashchange", _boundEvents.windowHashChange);    window.removeEventListener("beforeprint", _boundEvents.windowBeforePrint);    window.removeEventListener("afterprint", _boundEvents.windowAfterPrint);    window.removeEventListener(      "updatefromsandbox",      _boundEvents.windowUpdateFromSandbox    );    _boundEvents.removeWindowResolutionChange?.();    _boundEvents.windowResize = null;    _boundEvents.windowHashChange = null;    _boundEvents.windowBeforePrint = null;    _boundEvents.windowAfterPrint = null;    _boundEvents.windowUpdateFromSandbox = null;  },  accumulateWheelTicks(ticks) {    // If the scroll direction changed, reset the accumulated wheel ticks.    if (      (this._wheelUnusedTicks > 0 && ticks < 0) ||      (this._wheelUnusedTicks < 0 && ticks > 0)    ) {      this._wheelUnusedTicks = 0;    }    this._wheelUnusedTicks += ticks;    const wholeTicks = Math.trunc(this._wheelUnusedTicks);    this._wheelUnusedTicks -= wholeTicks;    return wholeTicks;  },  /**   * 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;  },};if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {  const HOSTED_VIEWER_ORIGINS = [    "null",    "http://mozilla.github.io",    "https://mozilla.github.io",  ];  // eslint-disable-next-line no-var  var validateFileURL = function (file) {    if (!file) {      return;    }    try {      const viewerOrigin = new URL(window.location.href).origin || "null";      if (HOSTED_VIEWER_ORIGINS.includes(viewerOrigin)) {        // Hosted or local viewer, allow for any file locations        return;      }      const fileOrigin = new URL(file, window.location.href).origin;      // 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.      // if (fileOrigin !== viewerOrigin) {      //   throw new Error("file origin does not match viewer's");      // }    } catch (ex) {      PDFViewerApplication.l10n.get("loading_error").then(msg => {        PDFViewerApplication._documentError(msg, { message: ex?.message });      });      throw ex;    }  };}async function loadFakeWorker() {  GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc");  if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) {    window.pdfjsWorker = await import("pdfjs/core/worker.js");    return;  }  await loadScript(PDFWorker.workerSrc);}async function loadPDFBug(self) {  const { debuggerScriptPath } = self.appConfig;  const { PDFBug } =    typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")      ? await import(debuggerScriptPath) // eslint-disable-line no-unsanitized/method      : await __non_webpack_import__(debuggerScriptPath); // eslint-disable-line no-undef  self._PDFBug = PDFBug;}function reportPageStatsPDFBug({ pageNumber }) {  if (!globalThis.Stats?.enabled) {    return;  }  const pageView = PDFViewerApplication.pdfViewer.getPageView(    /* index = */ pageNumber - 1  );  globalThis.Stats.add(pageNumber, pageView?.pdfPage?.stats);}function webViewerInitialized() {  const { appConfig, eventBus } = PDFViewerApplication;  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");    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 = appConfig.openFileInput;    fileInput.value = null;    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) {      evt.preventDefault();      evt.dataTransfer.dropEffect =        evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move";    });    appConfig.mainContainer.addEventListener("drop", function (evt) {      evt.preventDefault();      const { files } = evt.dataTransfer;      if (!files || files.length === 0) {        return;      }      eventBus.dispatch("fileinputchange", {        source: this,        fileInput: evt.dataTransfer,      });    });  }  if (!PDFViewerApplication.supportsDocumentFonts) {    AppOptions.set("disableFontFace", true);    PDFViewerApplication.l10n.get("web_fonts_disabled").then(msg => {      console.warn(msg);    });  }  if (!PDFViewerApplication.supportsPrinting) {    appConfig.toolbar?.print.classList.add("hidden");    appConfig.secondaryToolbar?.printButton.classList.add("hidden");  }  if (!PDFViewerApplication.supportsFullscreen) {    appConfig.secondaryToolbar?.presentationModeButton.classList.add("hidden");  }  if (PDFViewerApplication.supportsIntegratedFind) {    appConfig.toolbar?.viewFind.classList.add("hidden");  }  appConfig.mainContainer.addEventListener(    "transitionend",    function (evt) {      if (evt.target === /* mainContainer */ this) {        eventBus.dispatch("resize", { source: this });      }    },    true  );  try {    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {      if (file) {        PDFViewerApplication.open(file);      } else {        PDFViewerApplication._hideViewBookmark();      }    } else if (PDFJSDev.test("MOZCENTRAL || CHROME")) {      PDFViewerApplication.setTitleUsingUrl(file, /* downloadUrl = */ file);      PDFViewerApplication.initPassiveLoading();    } else {      throw new Error("Not implemented: webViewerInitialized");    }  } catch (reason) {    PDFViewerApplication.l10n.get("loading_error").then(msg => {      PDFViewerApplication._documentError(msg, reason);    });  }}function webViewerPageRender({ pageNumber }) {  // If the page is (the most) visible when it starts rendering,  // ensure that the page number input loading indicator is displayed.  if (pageNumber === PDFViewerApplication.page) {    PDFViewerApplication.toolbar?.updateLoadingIndicatorState(true);  }}function webViewerPageRendered({ pageNumber, error }) {  // If the page is still visible when it has finished rendering,  // ensure that the page number input loading indicator is hidden.  if (pageNumber === PDFViewerApplication.page) {    PDFViewerApplication.toolbar?.updateLoadingIndicatorState(false);  }  // Use the rendered page to set the corresponding thumbnail image.  if (PDFViewerApplication.pdfSidebar?.visibleView === SidebarView.THUMBS) {    const pageView = PDFViewerApplication.pdfViewer.getPageView(      /* index = */ pageNumber - 1    );    const thumbnailView = PDFViewerApplication.pdfThumbnailViewer?.getThumbnail(      /* index = */ pageNumber - 1    );    if (pageView && thumbnailView) {      thumbnailView.setImage(pageView);    }  }  if (error) {    PDFViewerApplication.l10n.get("rendering_error").then(msg => {      PDFViewerApplication._otherError(msg, error);    });  }}function webViewerPageMode({ 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;  }  PDFViewerApplication.pdfSidebar?.switchView(view, /* forceOpen = */ true);}function webViewerNamedAction(evt) {  // Processing a couple of named actions that might be useful, see also  // `PDFLinkService.executeNamedAction`.  switch (evt.action) {    case "GoToPage":      PDFViewerApplication.appConfig.toolbar?.pageNumber.select();      break;    case "Find":      if (!PDFViewerApplication.supportsIntegratedFind) {        PDFViewerApplication?.findBar.toggle();      }      break;    case "Print":      PDFViewerApplication.triggerPrinting();      break;    case "SaveAs":      PDFViewerApplication.downloadOrSave();      break;  }}function webViewerPresentationModeChanged(evt) {  PDFViewerApplication.pdfViewer.presentationModeState = evt.state;}function webViewerSidebarViewChanged({ view }) {  PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled =    view === SidebarView.THUMBS;  if (PDFViewerApplication.isInitialViewSet) {    // Only update the storage when the document has been loaded *and* rendered.    PDFViewerApplication.store?.set("sidebarView", view).catch(() => {      // Unable to write to storage.    });  }}function webViewerUpdateViewarea({ location }) {  if (PDFViewerApplication.isInitialViewSet) {    // Only update the storage when the document has been loaded *and* rendered.    PDFViewerApplication.store      ?.setMultiple({        page: location.pageNumber,        zoom: location.scale,        scrollLeft: location.left,        scrollTop: location.top,        rotation: location.rotation,      })      .catch(() => {        // Unable to write to storage.      });  }  if (PDFViewerApplication.appConfig.secondaryToolbar) {    const href = PDFViewerApplication.pdfLinkService.getAnchorUrl(      location.pdfOpenParams    );    PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href =      href;  }}function webViewerScrollModeChanged(evt) {  if (    PDFViewerApplication.isInitialViewSet &&    !PDFViewerApplication.pdfViewer.isInPresentationMode  ) {    // Only update the storage when the document has been loaded *and* rendered.    PDFViewerApplication.store?.set("scrollMode", evt.mode).catch(() => {      // Unable to write to storage.    });  }}function webViewerSpreadModeChanged(evt) {  if (    PDFViewerApplication.isInitialViewSet &&    !PDFViewerApplication.pdfViewer.isInPresentationMode  ) {    // Only update the storage when the document has been loaded *and* rendered.    PDFViewerApplication.store?.set("spreadMode", evt.mode).catch(() => {      // Unable to write to storage.    });  }}function webViewerResize() {  const { pdfDocument, pdfViewer, pdfRenderingQueue } = PDFViewerApplication;  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 webViewerHashchange(evt) {  const hash = evt.hash;  if (!hash) {    return;  }  if (!PDFViewerApplication.isInitialViewSet) {    PDFViewerApplication.initialBookmark = hash;  } else if (!PDFViewerApplication.pdfHistory?.popStateInProgress) {    PDFViewerApplication.pdfLinkService.setHash(hash);  }}if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {  // eslint-disable-next-line no-var  var webViewerFileInputChange = function (evt) {    if (PDFViewerApplication.pdfViewer?.isInPresentationMode) {      return; // Opening a new PDF file isn't supported in Presentation Mode.    }    const file = evt.fileInput.files[0];    let url = URL.createObjectURL(file);    if (file.name) {      url = { url, originalUrl: file.name };    }    PDFViewerApplication.open(url);  };  // eslint-disable-next-line no-var  var webViewerOpenFile = function (evt) {    const fileInput = PDFViewerApplication.appConfig.openFileInput;    fileInput.click();  };}function webViewerPresentationMode() {  PDFViewerApplication.requestPresentationMode();}function webViewerSwitchAnnotationEditorMode(evt) {  PDFViewerApplication.pdfViewer.annotationEditorMode = evt.mode;}function webViewerSwitchAnnotationEditorParams(evt) {  PDFViewerApplication.pdfViewer.annotationEditorParams = evt;}function webViewerPrint() {  PDFViewerApplication.triggerPrinting();}function webViewerDownload() {  PDFViewerApplication.downloadOrSave();}function webViewerFirstPage() {  if (PDFViewerApplication.pdfDocument) {    PDFViewerApplication.page = 1;  }}function webViewerLastPage() {  if (PDFViewerApplication.pdfDocument) {    PDFViewerApplication.page = PDFViewerApplication.pagesCount;  }}function webViewerNextPage() {  PDFViewerApplication.pdfViewer.nextPage();}function webViewerPreviousPage() {  PDFViewerApplication.pdfViewer.previousPage();}function webViewerZoomIn() {  PDFViewerApplication.zoomIn();}function webViewerZoomOut() {  PDFViewerApplication.zoomOut();}function webViewerZoomReset() {  PDFViewerApplication.zoomReset();}function webViewerPageNumberChanged(evt) {  const pdfViewer = PDFViewerApplication.pdfViewer;  // 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 !== "") {    PDFViewerApplication.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  ) {    PDFViewerApplication.toolbar?.setPageNumber(      pdfViewer.currentPageNumber,      pdfViewer.currentPageLabel    );  }}function webViewerScaleChanged(evt) {  PDFViewerApplication.pdfViewer.currentScaleValue = evt.value;}function webViewerRotateCw() {  PDFViewerApplication.rotatePages(90);}function webViewerRotateCcw() {  PDFViewerApplication.rotatePages(-90);}function webViewerOptionalContentConfig(evt) {  PDFViewerApplication.pdfViewer.optionalContentConfigPromise = evt.promise;}function webViewerSwitchScrollMode(evt) {  PDFViewerApplication.pdfViewer.scrollMode = evt.mode;}function webViewerSwitchSpreadMode(evt) {  PDFViewerApplication.pdfViewer.spreadMode = evt.mode;}function webViewerDocumentProperties() {  PDFViewerApplication.pdfDocumentProperties?.open();}function webViewerFindFromUrlHash(evt) {  PDFViewerApplication.eventBus.dispatch("find", {    source: evt.source,    type: "",    query: evt.query,    phraseSearch: evt.phraseSearch,    caseSensitive: false,    entireWord: false,    highlightAll: true,    findPrevious: false,    matchDiacritics: true,  });}function webViewerUpdateFindMatchesCount({ matchesCount }) {  if (PDFViewerApplication.supportsIntegratedFind) {    PDFViewerApplication.externalServices.updateFindMatchesCount(matchesCount);  } else {    PDFViewerApplication.findBar.updateResultsCount(matchesCount);  }}function webViewerUpdateFindControlState({  state,  previous,  matchesCount,  rawQuery,}) {  if (PDFViewerApplication.supportsIntegratedFind) {    PDFViewerApplication.externalServices.updateFindControlState({      result: state,      findPrevious: previous,      matchesCount,      rawQuery,    });  } else {    PDFViewerApplication.findBar?.updateUIState(state, previous, matchesCount);  }}function webViewerScaleChanging(evt) {  PDFViewerApplication.toolbar?.setPageScale(evt.presetValue, evt.scale);  PDFViewerApplication.pdfViewer.update();}function webViewerRotationChanging(evt) {  if (PDFViewerApplication.pdfThumbnailViewer) {    PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation;  }  PDFViewerApplication.forceRendering();  // Ensure that the active page doesn't change during rotation.  PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber;}function webViewerPageChanging({ pageNumber, pageLabel }) {  PDFViewerApplication.toolbar?.setPageNumber(pageNumber, pageLabel);  PDFViewerApplication.secondaryToolbar?.setPageNumber(pageNumber);  if (PDFViewerApplication.pdfSidebar?.visibleView === SidebarView.THUMBS) {    PDFViewerApplication.pdfThumbnailViewer?.scrollThumbnailIntoView(      pageNumber    );  }  // Show/hide the loading indicator in the page number input element.  const currentPage = PDFViewerApplication.pdfViewer.getPageView(    /* index = */ pageNumber - 1  );  PDFViewerApplication.toolbar?.updateLoadingIndicatorState(    currentPage?.renderingState === RenderingStates.RUNNING  );}function webViewerResolutionChange(evt) {  PDFViewerApplication.pdfViewer.refresh();}function webViewerVisibilityChange(evt) {  if (document.visibilityState === "visible") {    // Ignore mouse wheel zooming during tab switches (bug 1503412).    setZoomDisabledTimeout();  }}let zoomDisabledTimeout = null;function setZoomDisabledTimeout() {  if (zoomDisabledTimeout) {    clearTimeout(zoomDisabledTimeout);  }  zoomDisabledTimeout = setTimeout(function () {    zoomDisabledTimeout = null;  }, WHEEL_ZOOM_DISABLED_TIMEOUT);}function webViewerWheel(evt) {  const { pdfViewer, supportedMouseWheelZoomModifierKeys } =    PDFViewerApplication;  if (pdfViewer.isInPresentationMode) {    return;  }  if (    (evt.ctrlKey && supportedMouseWheelZoomModifierKeys.ctrlKey) ||    (evt.metaKey && supportedMouseWheelZoomModifierKeys.metaKey)  ) {    // Only zoom the pages, not the entire viewer.    evt.preventDefault();    // NOTE: this check must be placed *after* preventDefault.    if (zoomDisabledTimeout || document.visibilityState === "hidden") {      return;    }    // 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;    const delta = normalizeWheelEventDirection(evt);    const previousScale = pdfViewer.currentScale;    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 (Math.abs(delta) >= 1) {        ticks = Math.sign(delta);      } else {        // If we're getting fractional lines (I can't think of a scenario        // this might actually happen), be safe and use the accumulator.        ticks = PDFViewerApplication.accumulateWheelTicks(delta);      }    } else {      // pixel-based devices      const PIXELS_PER_LINE_SCALE = 30;      ticks = PDFViewerApplication.accumulateWheelTicks(        delta / PIXELS_PER_LINE_SCALE      );    }    if (ticks < 0) {      PDFViewerApplication.zoomOut(-ticks);    } else if (ticks > 0) {      PDFViewerApplication.zoomIn(ticks);    }    const currentScale = pdfViewer.currentScale;    if (previousScale !== currentScale) {      // After scaling the page via zoomIn/zoomOut, the position of the upper-      // left corner is restored. When the mouse wheel is used, the position      // under the cursor should be restored instead.      const scaleCorrectionFactor = currentScale / previousScale - 1;      const [top, left] = pdfViewer.containerTopLeft;      const dx = evt.clientX - left;      const dy = evt.clientY - top;      pdfViewer.container.scrollLeft += dx * scaleCorrectionFactor;      pdfViewer.container.scrollTop += dy * scaleCorrectionFactor;    }  } else {    setZoomDisabledTimeout();  }}function webViewerTouchStart(evt) {  if (evt.touches.length > 1) {    // Disable touch-based zooming, because the entire UI bits gets zoomed and    // that doesn't look great. If we do want to have a good touch-based    // zooming experience, we need to implement smooth zoom capability (probably    // using a CSS transform for faster visual response, followed by async    // re-rendering at the final zoom level) and do gesture detection on the    // touchmove events to drive it. Or if we want to settle for a less good    // experience we can make the touchmove events drive the existing step-zoom    // behaviour that the ctrl+mousewheel path takes.    evt.preventDefault();  }}function webViewerClick(evt) {  if (!PDFViewerApplication.secondaryToolbar?.isOpen) {    return;  }  const appConfig = PDFViewerApplication.appConfig;  if (    PDFViewerApplication.pdfViewer.containsElement(evt.target) ||    (appConfig.toolbar?.container.contains(evt.target) &&      evt.target !== appConfig.secondaryToolbar?.toggleButton)  ) {    PDFViewerApplication.secondaryToolbar.close();  }}function webViewerKeyDown(evt) {  if (PDFViewerApplication.overlayManager.active) {    return;  }  const { eventBus, pdfViewer } = PDFViewerApplication;  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 (!PDFViewerApplication.supportsIntegratedFind && !evt.shiftKey) {          PDFViewerApplication.findBar?.open();          handled = true;        }        break;      case 71: // g        if (!PDFViewerApplication.supportsIntegratedFind) {          const { state } = PDFViewerApplication.findController;          if (state) {            const eventState = Object.assign(Object.create(null), state, {              source: window,              type: "again",              findPrevious: cmd === 5 || cmd === 12,            });            eventBus.dispatch("find", eventState);          }          handled = true;        }        break;      case 61: // FF/Mac '='      case 107: // FF '+' and '='      case 187: // Chrome '+'      case 171: // FF with German keyboard        if (!isViewerInPresentationMode) {          PDFViewerApplication.zoomIn();        }        handled = true;        break;      case 173: // FF/Mac '-'      case 109: // FF '-'      case 189: // Chrome '-'        if (!isViewerInPresentationMode) {          PDFViewerApplication.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(function () {            // ... and resetting the scale after browser adjusts its scale            PDFViewerApplication.zoomReset();          });          handled = false;        }        break;      case 38: // up arrow        if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {          PDFViewerApplication.page = 1;          handled = true;          ensureViewerFocused = true;        }        break;      case 40: // down arrow        if (          isViewerInPresentationMode ||          PDFViewerApplication.page < PDFViewerApplication.pagesCount        ) {          PDFViewerApplication.page = PDFViewerApplication.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        PDFViewerApplication.requestPresentationMode();        handled = true;        PDFViewerApplication.externalServices.reportTelemetry({          type: "buttons",          data: { id: "presentationModeKeyboard" },        });        break;      case 71: // g        // focuses input#pageNumber field        if (PDFViewerApplication.appConfig.toolbar) {          PDFViewerApplication.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" ||    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      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        // 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 (PDFViewerApplication.secondaryToolbar?.isOpen) {          PDFViewerApplication.secondaryToolbar.close();          handled = true;        }        if (          !PDFViewerApplication.supportsIntegratedFind &&          PDFViewerApplication.findBar?.opened        ) {          PDFViewerApplication.findBar.close();          handled = true;        }        break;      case 40: // down arrow      case 34: // pg down        // vertical scrolling using arrow/pg keys        if (pdfViewer.isVerticalScrollbarEnabled) {          turnOnlyIfPageFit = true;        }        turnPage = 1;        break;      case 13: // enter key      case 32: // spacebar        if (!isViewerInPresentationMode) {          turnOnlyIfPageFit = true;        }        turnPage = 1;        break;      case 39: // right arrow        // 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 || PDFViewerApplication.page > 1) {          PDFViewerApplication.page = 1;          handled = true;          ensureViewerFocused = true;        }        break;      case 35: // end        if (          isViewerInPresentationMode ||          PDFViewerApplication.page < PDFViewerApplication.pagesCount        ) {          PDFViewerApplication.page = PDFViewerApplication.pagesCount;          handled = true;          ensureViewerFocused = true;        }        break;      case 83: // 's'        PDFViewerApplication.pdfCursorTools?.switchTool(CursorTool.SELECT);        break;      case 72: // 'h'        PDFViewerApplication.pdfCursorTools?.switchTool(CursorTool.HAND);        break;      case 82: // 'r'        PDFViewerApplication.rotatePages(90);        break;      case 115: // F4        PDFViewerApplication.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 13: // enter key      case 32: // spacebar        if (          !isViewerInPresentationMode &&          pdfViewer.currentScaleValue !== "page-fit"        ) {          break;        }        pdfViewer.previousPage();        handled = true;        break;      case 82: // 'r'        PDFViewerApplication.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;}function webViewerAnnotationEditorStatesChanged(data) {  PDFViewerApplication.externalServices.updateEditorStates(data);}/* Abstract factory for the print service. */const PDFPrintServiceFactory = {  instance: {    supportsPrinting: false,    createPrintService() {      throw new Error("Not implemented: createPrintService");    },  },};export {  DefaultExternalServices,  PDFPrintServiceFactory,  PDFViewerApplication,};
 |