Bug 1489996 - Update pdf.js to version 2.0.843. r=bdahl
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 10 Sep 2018 20:02:01 -0400
changeset 483893 caa65bf34838ab7861dcfed3ae59f9f6ed89fc0b
parent 483892 5097db630d1fb51f7f3fcd5523a924fa823e77ce
child 483894 a0d64a94fb662523c9e55669251b27153b8fe65c
push id241
push userfmarier@mozilla.com
push dateMon, 24 Sep 2018 21:48:02 +0000
reviewersbdahl
bugs1489996
milestone64.0a1
Bug 1489996 - Update pdf.js to version 2.0.843. r=bdahl
browser/extensions/pdfjs/README.mozilla
browser/extensions/pdfjs/content/build/pdf.js
browser/extensions/pdfjs/content/build/pdf.worker.js
browser/extensions/pdfjs/content/web/viewer.html
browser/extensions/pdfjs/content/web/viewer.js
browser/extensions/pdfjs/moz.yaml
browser/locales/en-US/pdfviewer/viewer.properties
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.0.815
+Current extension version is: 2.0.843
 
-Taken from upstream commit: d6927376
+Taken from upstream commit: bf368f3a
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.815';
-var pdfjsBuild = 'd6927376';
+var pdfjsVersion = '2.0.843';
+var pdfjsBuild = 'bf368f3a';
 var pdfjsSharedUtil = __w_pdfjs_require__(1);
 var pdfjsDisplayAPI = __w_pdfjs_require__(7);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(19);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(20);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(8);
 var pdfjsDisplaySVG = __w_pdfjs_require__(21);
 let pdfjsDisplayWorkerOptions = __w_pdfjs_require__(13);
 let pdfjsDisplayAPICompatibility = __w_pdfjs_require__(10);
@@ -4221,17 +4221,17 @@ function _fetchDocument(worker, source, 
     return Promise.reject(new Error('Worker was destroyed'));
   }
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
     docId,
-    apiVersion: '2.0.815',
+    apiVersion: '2.0.843',
     source: {
       data: source.data,
       url: source.url,
       password: source.password,
       disableAutoFetch: source.disableAutoFetch,
       rangeChunkSize: source.rangeChunkSize,
       length: source.length
     },
@@ -5548,18 +5548,18 @@ var InternalRenderTask = function Intern
         }
       });
     }
   };
   return InternalRenderTask;
 }();
 var version, build;
 {
-  exports.version = version = '2.0.815';
-  exports.build = build = 'd6927376';
+  exports.version = version = '2.0.843';
+  exports.build = build = 'bf368f3a';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;
@@ -6349,17 +6349,17 @@ var CanvasGraphics = function CanvasGrap
     this.groupLevel = 0;
     this.smaskStack = [];
     this.smaskCounter = 0;
     this.tempSMask = null;
     this.cachedCanvases = new CachedCanvases(this.canvasFactory);
     if (canvasCtx) {
       addContextCurrentTransform(canvasCtx);
     }
-    this.cachedGetSinglePixelWidth = null;
+    this._cachedGetSinglePixelWidth = null;
   }
   function putBinaryImageData(ctx, imgData) {
     if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) {
       ctx.putImageData(imgData, 0, 0);
       return;
     }
     var height = imgData.height,
         width = imgData.width;
@@ -6824,22 +6824,22 @@ var CanvasGraphics = function CanvasGrap
       }
       if (this.current.activeSMask !== null && (this.stateStack.length === 0 || this.stateStack[this.stateStack.length - 1].activeSMask !== this.current.activeSMask)) {
         this.endSMaskGroup();
       }
       if (this.stateStack.length !== 0) {
         this.current = this.stateStack.pop();
         this.ctx.restore();
         this.pendingClip = null;
-        this.cachedGetSinglePixelWidth = null;
+        this._cachedGetSinglePixelWidth = null;
       }
     },
     transform: function CanvasGraphics_transform(a, b, c, d, e, f) {
       this.ctx.transform(a, b, c, d, e, f);
-      this.cachedGetSinglePixelWidth = null;
+      this._cachedGetSinglePixelWidth = null;
     },
     constructPath: function CanvasGraphics_constructPath(ops, args) {
       var ctx = this.ctx;
       var current = this.current;
       var x = current.x,
           y = current.y;
       for (var i = 0, j = 0, ii = ops.length; i < ii; i++) {
         switch (ops[i] | 0) {
@@ -7172,17 +7172,17 @@ var CanvasGraphics = function CanvasGrap
       } else {
         ctx.scale(textHScale, 1);
       }
       var lineWidth = current.lineWidth;
       var scale = current.textMatrixScale;
       if (scale === 0 || lineWidth === 0) {
         var fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK;
         if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {
-          this.cachedGetSinglePixelWidth = null;
+          this._cachedGetSinglePixelWidth = null;
           lineWidth = this.getSinglePixelWidth() * MIN_WIDTH_FACTOR;
         }
       } else {
         lineWidth /= scale;
       }
       if (fontSizeScale !== 1.0) {
         ctx.scale(fontSizeScale, fontSizeScale);
         lineWidth /= fontSizeScale;
@@ -7264,17 +7264,17 @@ var CanvasGraphics = function CanvasGrap
       var textHScale = current.textHScale * fontDirection;
       var fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX;
       var glyphsLength = glyphs.length;
       var isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE;
       var i, glyph, width, spacingLength;
       if (isTextInvisible || fontSize === 0) {
         return;
       }
-      this.cachedGetSinglePixelWidth = null;
+      this._cachedGetSinglePixelWidth = null;
       ctx.save();
       ctx.transform.apply(ctx, current.textMatrix);
       ctx.translate(current.x, current.y);
       ctx.scale(textHScale, fontDirection);
       for (i = 0; i < glyphsLength; ++i) {
         glyph = glyphs[i];
         if ((0, _util.isNum)(glyph)) {
           spacingLength = spacingDir * glyph * fontSize / 1000;
@@ -7732,24 +7732,22 @@ var CanvasGraphics = function CanvasGrap
           ctx.clip('evenodd');
         } else {
           ctx.clip();
         }
         this.pendingClip = null;
       }
       ctx.beginPath();
     },
-    getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) {
-      if (this.cachedGetSinglePixelWidth === null) {
-        this.ctx.save();
-        var inverse = this.ctx.mozCurrentTransformInverse;
-        this.ctx.restore();
-        this.cachedGetSinglePixelWidth = Math.sqrt(Math.max(inverse[0] * inverse[0] + inverse[1] * inverse[1], inverse[2] * inverse[2] + inverse[3] * inverse[3]));
-      }
-      return this.cachedGetSinglePixelWidth;
+    getSinglePixelWidth(scale) {
+      if (this._cachedGetSinglePixelWidth === null) {
+        const inverse = this.ctx.mozCurrentTransformInverse;
+        this._cachedGetSinglePixelWidth = Math.sqrt(Math.max(inverse[0] * inverse[0] + inverse[1] * inverse[1], inverse[2] * inverse[2] + inverse[3] * inverse[3]));
+      }
+      return this._cachedGetSinglePixelWidth;
     },
     getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) {
       var transform = this.ctx.mozCurrentTransform;
       return [transform[0] * x + transform[2] * y + transform[4], transform[1] * x + transform[3] * y + transform[5]];
     }
   };
   for (var op in _util.OPS) {
     CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op];
@@ -10010,18 +10008,18 @@ var renderTextLayer = function renderTex
       let textDivProperties = this._textDivProperties.get(textDiv);
       if (textDivProperties.isWhitespace) {
         return;
       }
       let fontSize = textDiv.style.fontSize;
       let fontFamily = textDiv.style.fontFamily;
       if (fontSize !== this._layoutTextLastFontSize || fontFamily !== this._layoutTextLastFontFamily) {
         this._layoutTextCtx.font = fontSize + ' ' + fontFamily;
-        this._lastFontSize = fontSize;
-        this._lastFontFamily = fontFamily;
+        this._layoutTextLastFontSize = fontSize;
+        this._layoutTextLastFontFamily = fontFamily;
       }
       let width = this._layoutTextCtx.measureText(textDiv.textContent).width;
       let transform = '';
       if (textDivProperties.canvasWidth !== 0 && width > 0) {
         textDivProperties.scale = textDivProperties.canvasWidth / width;
         transform = 'scaleX(' + textDivProperties.scale + ')';
       }
       if (textDivProperties.angle !== 0) {
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.815';
-var pdfjsBuild = 'd6927376';
+var pdfjsVersion = '2.0.843';
+var pdfjsBuild = 'bf368f3a';
 var pdfjsCoreWorker = __w_pdfjs_require__(1);
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -322,17 +322,17 @@ var WorkerMessageHandler = {
     });
   },
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.0.815';
+    let workerVersion = '2.0.843';
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
     var handler = new _message_handler.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
@@ -22280,17 +22280,17 @@ exports.CMapFactory = CMapFactory;
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getFontType = exports.ProblematicCharRanges = exports.IdentityToUnicodeMap = exports.ToUnicodeMap = exports.FontFlags = exports.Font = exports.ErrorFont = exports.PRIVATE_USE_OFFSET_END = exports.PRIVATE_USE_OFFSET_START = exports.SEAC_ANALYSIS_ENABLED = undefined;
+exports.getFontType = exports.IdentityToUnicodeMap = exports.ToUnicodeMap = exports.FontFlags = exports.Font = exports.ErrorFont = exports.SEAC_ANALYSIS_ENABLED = undefined;
 
 var _util = __w_pdfjs_require__(2);
 
 var _cff_parser = __w_pdfjs_require__(31);
 
 var _glyphlist = __w_pdfjs_require__(34);
 
 var _encodings = __w_pdfjs_require__(33);
@@ -22302,21 +22302,19 @@ var _unicode = __w_pdfjs_require__(36);
 var _font_renderer = __w_pdfjs_require__(37);
 
 var _cmap = __w_pdfjs_require__(29);
 
 var _stream = __w_pdfjs_require__(14);
 
 var _type1_parser = __w_pdfjs_require__(38);
 
-var PRIVATE_USE_OFFSET_START = 0xE000;
-var PRIVATE_USE_OFFSET_END = 0xF8FF;
-var SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = false;
+const PRIVATE_USE_AREAS = [[0xE000, 0xF8FF], [0x100000, 0x10FFFD]];
 var PDF_GLYPH_SPACE_UNITS = 1000;
-var SEAC_ANALYSIS_ENABLED = false;
+var SEAC_ANALYSIS_ENABLED = true;
 var FontFlags = {
   FixedPitch: 1,
   Serif: 2,
   Symbolic: 4,
   Script: 8,
   Nonsymbolic: 32,
   Italic: 64,
   AllCap: 65536,
@@ -22585,17 +22583,16 @@ var OpenTypeFileBuilder = function OpenT
       if (tag in this.tables) {
         throw new Error('Table ' + tag + ' already exists');
       }
       this.tables[tag] = data;
     }
   };
   return OpenTypeFileBuilder;
 }();
-var ProblematicCharRanges = new Int32Array([0x0000, 0x0020, 0x007F, 0x00A1, 0x00AD, 0x00AE, 0x0600, 0x0780, 0x08A0, 0x10A0, 0x1780, 0x1800, 0x1C00, 0x1C50, 0x2000, 0x2010, 0x2011, 0x2012, 0x2028, 0x2030, 0x205F, 0x2070, 0x25CC, 0x25CD, 0x3000, 0x3001, 0x3164, 0x3165, 0xAA60, 0xAA80, 0xD800, 0xE000, 0xFFF0, 0x10000]);
 var Font = function FontClosure() {
   function Font(name, file, properties) {
     var charCode;
     this.name = name;
     this.loadedName = properties.loadedName;
     this.isType3Font = properties.isType3Font;
     this.sizes = [];
     this.missingFile = false;
@@ -22789,68 +22786,43 @@ var Font = function FontClosure() {
     for (var charCode in differences) {
       unicode = (0, _unicode.getUnicodeForGlyph)(differences[charCode], glyphsUnicodeMap);
       if (unicode !== -1) {
         toFontChar[+charCode] = unicode;
       }
     }
     return toFontChar;
   }
-  function isProblematicUnicodeLocation(code) {
-    var i = 0,
-        j = ProblematicCharRanges.length - 1;
-    while (i < j) {
-      var c = i + j + 1 >> 1;
-      if (code < ProblematicCharRanges[c]) {
-        j = c - 1;
-      } else {
-        i = c;
-      }
-    }
-    return !(i & 1);
-  }
-  function adjustMapping(charCodeToGlyphId, properties, missingGlyphs) {
-    var toUnicode = properties.toUnicode;
-    var isSymbolic = !!(properties.flags & FontFlags.Symbolic);
-    var isIdentityUnicode = properties.toUnicode instanceof IdentityToUnicodeMap;
+  function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) {
     var newMap = Object.create(null);
     var toFontChar = [];
-    var usedFontCharCodes = [];
-    var nextAvailableFontCharCode = PRIVATE_USE_OFFSET_START;
+    var privateUseAreaIndex = 0;
+    var nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
+    var privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
     for (var originalCharCode in charCodeToGlyphId) {
       originalCharCode |= 0;
       var glyphId = charCodeToGlyphId[originalCharCode];
-      if (missingGlyphs[glyphId]) {
+      if (!hasGlyph(glyphId)) {
         continue;
       }
-      var fontCharCode = originalCharCode;
-      var hasUnicodeValue = false;
-      if (!isIdentityUnicode && toUnicode.has(originalCharCode)) {
-        hasUnicodeValue = true;
-        var unicode = toUnicode.get(fontCharCode);
-        if (unicode.length === 1) {
-          fontCharCode = unicode.charCodeAt(0);
-        }
-      }
-      if (usedFontCharCodes[fontCharCode] !== undefined || isProblematicUnicodeLocation(fontCharCode) || isSymbolic && !hasUnicodeValue) {
-        do {
-          if (nextAvailableFontCharCode > PRIVATE_USE_OFFSET_END) {
-            (0, _util.warn)('Ran out of space in font private use area.');
-            break;
-          }
-          fontCharCode = nextAvailableFontCharCode++;
-          if (SKIP_PRIVATE_USE_RANGE_F000_TO_F01F && fontCharCode === 0xF000) {
-            fontCharCode = 0xF020;
-            nextAvailableFontCharCode = fontCharCode + 1;
-          }
-        } while (usedFontCharCodes[fontCharCode] !== undefined);
+      if (nextAvailableFontCharCode > privateUseOffetEnd) {
+        privateUseAreaIndex++;
+        if (privateUseAreaIndex >= PRIVATE_USE_AREAS.length) {
+          (0, _util.warn)('Ran out of space in font private use area.');
+          break;
+        }
+        nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
+        privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
+      }
+      var fontCharCode = nextAvailableFontCharCode++;
+      if (glyphId === 0) {
+        glyphId = newGlyphZeroId;
       }
       newMap[fontCharCode] = glyphId;
       toFontChar[originalCharCode] = fontCharCode;
-      usedFontCharCodes[fontCharCode] = true;
     }
     return {
       toFontChar,
       charCodeToGlyphId: newMap,
       nextAvailableFontCharCode
     };
   }
   function getRanges(glyphs, numGlyphs) {
@@ -23027,16 +22999,19 @@ var Font = function FontClosure() {
         } else if (position < 96) {
           ulUnicodeRange3 |= 1 << position - 64;
         } else if (position < 123) {
           ulUnicodeRange4 |= 1 << position - 96;
         } else {
           throw new _util.FormatError('Unicode ranges Bits > 123 are reserved for internal usage');
         }
       }
+      if (lastCharIndex > 0xFFFF) {
+        lastCharIndex = 0xFFFF;
+      }
     } else {
       firstCharIndex = 0;
       lastCharIndex = 255;
     }
     var bbox = properties.bbox || [0, 0, 0, 0];
     var unitsPerEm = override.unitsPerEm || 1 / (properties.fontMatrix || _util.FONT_IDENTITY_MATRIX)[0];
     var scale = properties.ascentScaled ? 1.0 : unitsPerEm / PDF_GLYPH_SPACE_UNITS;
     var typoAscent = override.ascent || Math.round(scale * (properties.ascent || bbox[3]));
@@ -23580,33 +23555,31 @@ var Font = function FontClosure() {
           itemDecode = function fontItemDecode(data, offset) {
             return data[offset] << 9 | data[offset + 1] << 1;
           };
           itemEncode = function fontItemEncode(data, offset, value) {
             data[offset] = value >> 9 & 0xFF;
             data[offset + 1] = value >> 1 & 0xFF;
           };
         }
+        var numGlyphsOut = dupFirstEntry ? numGlyphs + 1 : numGlyphs;
         var locaData = loca.data;
-        var locaDataSize = itemSize * (1 + numGlyphs);
-        if (locaData.length !== locaDataSize) {
-          locaData = new Uint8Array(locaDataSize);
-          locaData.set(loca.data.subarray(0, locaDataSize));
-          loca.data = locaData;
-        }
+        var locaDataSize = itemSize * (1 + numGlyphsOut);
+        locaData = new Uint8Array(locaDataSize);
+        locaData.set(loca.data.subarray(0, locaDataSize));
+        loca.data = locaData;
         var oldGlyfData = glyf.data;
         var oldGlyfDataLength = oldGlyfData.length;
         var newGlyfData = new Uint8Array(oldGlyfDataLength);
         var startOffset = itemDecode(locaData, 0);
         var writeOffset = 0;
         var missingGlyphs = Object.create(null);
         itemEncode(locaData, 0, writeOffset);
         var i, j;
-        var locaCount = dupFirstEntry ? numGlyphs - 1 : numGlyphs;
-        for (i = 0, j = itemSize; i < locaCount; i++, j += itemSize) {
+        for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
           var endOffset = itemDecode(locaData, j);
           if (endOffset === 0) {
             endOffset = startOffset;
           }
           if (endOffset > oldGlyfDataLength && (oldGlyfDataLength + 3 & ~3) === endOffset) {
             endOffset = oldGlyfDataLength;
           }
           if (endOffset > oldGlyfDataLength) {
@@ -23621,17 +23594,17 @@ var Font = function FontClosure() {
             maxSizeOfInstructions = glyphProfile.sizeOfInstructions;
           }
           writeOffset += newLength;
           itemEncode(locaData, j, writeOffset);
           startOffset = endOffset;
         }
         if (writeOffset === 0) {
           var simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]);
-          for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
+          for (i = 0, j = itemSize; i < numGlyphsOut; i++, j += itemSize) {
             itemEncode(locaData, j, simpleGlyph.length);
           }
           glyf.data = simpleGlyph;
         } else if (dupFirstEntry) {
           var firstEntryLength = itemDecode(locaData, itemSize);
           if (newGlyfData.length > firstEntryLength + writeOffset) {
             glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset);
           } else {
@@ -24040,45 +24013,47 @@ var Font = function FontClosure() {
         }
         this.isOpenType = false;
       }
       if (!tables['maxp']) {
         throw new _util.FormatError('Required "maxp" table is not found');
       }
       font.pos = (font.start || 0) + tables['maxp'].offset;
       var version = font.getInt32();
-      var numGlyphs = font.getUint16();
+      const numGlyphs = font.getUint16();
+      let numGlyphsOut = numGlyphs + 1;
+      let dupFirstEntry = true;
+      if (numGlyphsOut > 0xFFFF) {
+        dupFirstEntry = false;
+        numGlyphsOut = numGlyphs;
+        (0, _util.warn)('Not enough space in glyfs to duplicate first glyph.');
+      }
       var maxFunctionDefs = 0;
       var maxSizeOfInstructions = 0;
       if (version >= 0x00010000 && tables['maxp'].length >= 22) {
         font.pos += 8;
         var maxZones = font.getUint16();
         if (maxZones > 2) {
           tables['maxp'].data[14] = 0;
           tables['maxp'].data[15] = 2;
         }
         font.pos += 4;
         maxFunctionDefs = font.getUint16();
         font.pos += 4;
         maxSizeOfInstructions = font.getUint16();
       }
-      var dupFirstEntry = false;
-      if (properties.type === 'CIDFontType2' && properties.toUnicode && properties.toUnicode.get(0) > '\u0000') {
-        dupFirstEntry = true;
-        numGlyphs++;
-        tables['maxp'].data[4] = numGlyphs >> 8;
-        tables['maxp'].data[5] = numGlyphs & 255;
-      }
+      tables['maxp'].data[4] = numGlyphsOut >> 8;
+      tables['maxp'].data[5] = numGlyphsOut & 255;
       var hintsValid = sanitizeTTPrograms(tables['fpgm'], tables['prep'], tables['cvt '], maxFunctionDefs);
       if (!hintsValid) {
         delete tables['fpgm'];
         delete tables['prep'];
         delete tables['cvt '];
       }
-      sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphs);
+      sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphsOut);
       if (!tables['head']) {
         throw new _util.FormatError('Required "head" table is not found');
       }
       sanitizeHead(tables['head'], numGlyphs, isTrueType ? tables['loca'].length : 0);
       var missingGlyphs = Object.create(null);
       if (isTrueType) {
         var isGlyphLocationsLong = int16(tables['head'].data[50], tables['head'].data[51]);
         var glyphsInfo = sanitizeGlyphLocations(tables['loca'], tables['glyf'], numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions);
@@ -24100,21 +24075,22 @@ var Font = function FontClosure() {
         yMax: int16(tables['head'].data[42], tables['head'].data[43]),
         yMin: signedInt16(tables['head'].data[38], tables['head'].data[39]),
         ascent: int16(tables['hhea'].data[4], tables['hhea'].data[5]),
         descent: signedInt16(tables['hhea'].data[6], tables['hhea'].data[7])
       };
       this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm;
       this.descent = metricsOverride.descent / metricsOverride.unitsPerEm;
       if (tables['post']) {
-        var valid = readPostScriptTable(tables['post'], properties, numGlyphs);
-        if (!valid) {
-          tables['post'] = null;
-        }
-      }
+        readPostScriptTable(tables['post'], properties, numGlyphs);
+      }
+      tables['post'] = {
+        tag: 'post',
+        data: createPostTable(properties)
+      };
       var charCodeToGlyphId = [],
           charCode;
       function hasGlyph(glyphId) {
         return !missingGlyphs[glyphId];
       }
       if (properties.composite) {
         var cidToGidMap = properties.cidToGidMap || [];
         var isCidToGidMapEmpty = cidToGidMap.length === 0;
@@ -24127,19 +24103,16 @@ var Font = function FontClosure() {
             glyphId = cid;
           } else if (cidToGidMap[cid] !== undefined) {
             glyphId = cidToGidMap[cid];
           }
           if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) {
             charCodeToGlyphId[charCode] = glyphId;
           }
         });
-        if (dupFirstEntry && (isCidToGidMapEmpty || !charCodeToGlyphId[0])) {
-          charCodeToGlyphId[0] = numGlyphs - 1;
-        }
       } else {
         var cmapTable = readCmapTable(tables['cmap'], font, this.isSymbolicFont, properties.hasEncoding);
         var cmapPlatformId = cmapTable.platformId;
         var cmapEncodingId = cmapTable.encodingId;
         var cmapMappings = cmapTable.mappings;
         var cmapMappingsLength = cmapMappings.length;
         if (properties.hasEncoding && (cmapPlatformId === 3 && cmapEncodingId === 1 || cmapPlatformId === 1 && cmapEncodingId === 0) || cmapPlatformId === -1 && cmapEncodingId === -1 && !!(0, _encodings.getEncoding)(properties.baseEncodingName)) {
           var baseEncoding = [];
@@ -24197,39 +24170,38 @@ var Font = function FontClosure() {
             }
             charCodeToGlyphId[charCode] = cmapMappings[i].glyphId;
           }
         }
       }
       if (charCodeToGlyphId.length === 0) {
         charCodeToGlyphId[0] = 0;
       }
-      var newMapping = adjustMapping(charCodeToGlyphId, properties, missingGlyphs);
+      let glyphZeroId = numGlyphsOut - 1;
+      if (!dupFirstEntry) {
+        glyphZeroId = 0;
+      }
+      var newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId);
       this.toFontChar = newMapping.toFontChar;
       tables['cmap'] = {
         tag: 'cmap',
-        data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphs)
+        data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphsOut)
       };
       if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) {
         tables['OS/2'] = {
           tag: 'OS/2',
           data: createOS2Table(properties, newMapping.charCodeToGlyphId, metricsOverride)
         };
       }
-      if (!tables['post']) {
-        tables['post'] = {
-          tag: 'post',
-          data: createPostTable(properties)
-        };
-      }
       if (!isTrueType) {
         try {
           cffFile = new _stream.Stream(tables['CFF '].data);
           var parser = new _cff_parser.CFFParser(cffFile, properties, SEAC_ANALYSIS_ENABLED);
           cff = parser.parse();
+          cff.duplicateFirstGlyph();
           var compiler = new _cff_parser.CFFCompiler(cff);
           tables['CFF '].data = compiler.compile();
         } catch (e) {
           (0, _util.warn)('Failed to compile font ' + properties.loadedName);
         }
       }
       if (!tables['name']) {
         tables['name'] = {
@@ -24246,18 +24218,22 @@ var Font = function FontClosure() {
       }
       return builder.toArray();
     },
     convert: function Font_convert(fontName, font, properties) {
       properties.fixedPitch = false;
       if (properties.builtInEncoding) {
         adjustToUnicode(properties, properties.builtInEncoding);
       }
+      let glyphZeroId = 1;
+      if (font instanceof CFFFont) {
+        glyphZeroId = font.numGlyphs - 1;
+      }
       var mapping = font.getGlyphMapping(properties);
-      var newMapping = adjustMapping(mapping, properties, Object.create(null));
+      var newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId);
       this.toFontChar = newMapping.toFontChar;
       var numGlyphs = font.numGlyphs;
       function getCharCodes(charCodeToGlyphId, glyphId) {
         var charCodes = null;
         for (var charCode in charCodeToGlyphId) {
           if (glyphId === charCodeToGlyphId[charCode]) {
             if (!charCodes) {
               charCodes = [];
@@ -24398,21 +24374,21 @@ var Font = function FontClosure() {
         operatorListId = fontCharCode;
       }
       var accent = null;
       if (this.seacMap && this.seacMap[charcode]) {
         isInFont = true;
         var seac = this.seacMap[charcode];
         fontCharCode = seac.baseFontCharCode;
         accent = {
-          fontChar: String.fromCharCode(seac.accentFontCharCode),
+          fontChar: String.fromCodePoint(seac.accentFontCharCode),
           offset: seac.accentOffset
         };
       }
-      var fontChar = String.fromCharCode(fontCharCode);
+      var fontChar = typeof fontCharCode === 'number' ? String.fromCodePoint(fontCharCode) : '';
       var glyph = this.glyphCache[charcode];
       if (!glyph || !glyph.matchesForCache(fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont)) {
         glyph = new Glyph(fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont);
         this.glyphCache[charcode] = glyph;
       }
       return glyph;
     },
     charsToGlyphs: function Font_charsToGlyphs(chars) {
@@ -24664,16 +24640,26 @@ var Type1Font = function Type1FontClosur
           glyphId = glyphNames.indexOf(encoding[charCode]);
           if (glyphId >= 0) {
             builtInEncoding[charCode] = glyphId;
           }
         }
       }
       return type1FontGlyphMapping(properties, builtInEncoding, glyphNames);
     },
+    hasGlyphId: function Type1Font_hasGlyphID(id) {
+      if (id < 0 || id >= this.numGlyphs) {
+        return false;
+      }
+      if (id === 0) {
+        return true;
+      }
+      var glyph = this.charstrings[id - 1];
+      return glyph.charstring.length > 0;
+    },
     getSeacs: function Type1Font_getSeacs(charstrings) {
       var i, ii;
       var seacMap = [];
       for (i = 0, ii = charstrings.length; i < ii; i++) {
         var charstring = charstrings[i];
         if (charstring.seac) {
           seacMap[i + 1] = charstring.seac;
         }
@@ -24741,22 +24727,17 @@ var Type1Font = function Type1FontClosur
           index = 0;
         }
         charsetArray.push(index >> 8 & 0xff, index & 0xff);
       }
       cff.charset = new _cff_parser.CFFCharset(false, 0, [], charsetArray);
       var charStringsIndex = new _cff_parser.CFFIndex();
       charStringsIndex.add([0x8B, 0x0E]);
       for (i = 0; i < count; i++) {
-        var glyph = glyphs[i];
-        if (glyph.length === 0) {
-          charStringsIndex.add([0x8B, 0x0E]);
-          continue;
-        }
-        charStringsIndex.add(glyph);
+        charStringsIndex.add(glyphs[i]);
       }
       cff.charStrings = charStringsIndex;
       var privateDict = new _cff_parser.CFFPrivateDict();
       privateDict.setByName('Subrs', null);
       var fields = ['BlueValues', 'OtherBlues', 'FamilyBlues', 'FamilyOtherBlues', 'StemSnapH', 'StemSnapV', 'BlueShift', 'BlueFuzz', 'BlueScale', 'LanguageGroup', 'ExpansionFactor', 'ForceBold', 'StdHW', 'StdVW'];
       for (i = 0, ii = fields.length; i < ii; i++) {
         var field = fields[i];
         if (!(field in properties.privateData)) {
@@ -24782,16 +24763,17 @@ var Type1Font = function Type1FontClosur
   };
   return Type1Font;
 }();
 var CFFFont = function CFFFontClosure() {
   function CFFFont(file, properties) {
     this.properties = properties;
     var parser = new _cff_parser.CFFParser(file, properties, SEAC_ANALYSIS_ENABLED);
     this.cff = parser.parse();
+    this.cff.duplicateFirstGlyph();
     var compiler = new _cff_parser.CFFCompiler(this.cff);
     this.seacs = this.cff.seacs;
     try {
       this.data = compiler.compile();
     } catch (e) {
       (0, _util.warn)('Failed to compile font ' + properties.loadedName);
       this.data = file;
     }
@@ -24822,52 +24804,42 @@ var CFFFont = function CFFFontClosure() 
             charCodeToGlyphId[glyphId] = glyphId;
           }
         }
         return charCodeToGlyphId;
       }
       var encoding = cff.encoding ? cff.encoding.encoding : null;
       charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets);
       return charCodeToGlyphId;
+    },
+    hasGlyphId: function CFFFont_hasGlyphID(id) {
+      return this.cff.hasGlyphId(id);
     }
   };
   return CFFFont;
 }();
-(function checkSeacSupport() {
-  if (typeof navigator !== 'undefined' && /Windows/.test(navigator.userAgent)) {
-    exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED = true;
-  }
-})();
-(function checkChromeWindows() {
-  if (typeof navigator !== 'undefined' && /Windows.*Chrome/.test(navigator.userAgent)) {
-    SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = true;
-  }
-})();
 exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED;
-exports.PRIVATE_USE_OFFSET_START = PRIVATE_USE_OFFSET_START;
-exports.PRIVATE_USE_OFFSET_END = PRIVATE_USE_OFFSET_END;
 exports.ErrorFont = ErrorFont;
 exports.Font = Font;
 exports.FontFlags = FontFlags;
 exports.ToUnicodeMap = ToUnicodeMap;
 exports.IdentityToUnicodeMap = IdentityToUnicodeMap;
-exports.ProblematicCharRanges = ProblematicCharRanges;
 exports.getFontType = getFontType;
 
 /***/ }),
 /* 31 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.CFFCompiler = exports.CFFPrivateDict = exports.CFFTopDict = exports.CFFCharset = exports.CFFIndex = exports.CFFStrings = exports.CFFHeader = exports.CFF = exports.CFFParser = exports.CFFStandardStrings = undefined;
+exports.CFFFDSelect = exports.CFFCompiler = exports.CFFPrivateDict = exports.CFFTopDict = exports.CFFCharset = exports.CFFIndex = exports.CFFStrings = exports.CFFHeader = exports.CFF = exports.CFFParser = exports.CFFStandardStrings = undefined;
 
 var _util = __w_pdfjs_require__(2);
 
 var _charsets = __w_pdfjs_require__(32);
 
 var _encodings = __w_pdfjs_require__(33);
 
 var MAX_SUBR_NESTING = 10;
@@ -25621,59 +25593,50 @@ var CFFParser = function CFFParserClosur
           readSupplement();
         }
         raw = bytes.subarray(dataStart, dataEnd);
       }
       format = format & 0x7f;
       return new CFFEncoding(predefined, format, encoding, raw);
     },
     parseFDSelect: function CFFParser_parseFDSelect(pos, length) {
-      var start = pos;
       var bytes = this.bytes;
       var format = bytes[pos++];
-      var fdSelect = [],
-          rawBytes;
-      var i,
-          invalidFirstGID = false;
+      var fdSelect = [];
+      var i;
       switch (format) {
         case 0:
           for (i = 0; i < length; ++i) {
             var id = bytes[pos++];
             fdSelect.push(id);
           }
-          rawBytes = bytes.subarray(start, pos);
           break;
         case 3:
           var rangesCount = bytes[pos++] << 8 | bytes[pos++];
           for (i = 0; i < rangesCount; ++i) {
             var first = bytes[pos++] << 8 | bytes[pos++];
             if (i === 0 && first !== 0) {
               (0, _util.warn)('parseFDSelect: The first range must have a first GID of 0' + ' -- trying to recover.');
-              invalidFirstGID = true;
               first = 0;
             }
             var fdIndex = bytes[pos++];
             var next = bytes[pos] << 8 | bytes[pos + 1];
             for (var j = first; j < next; ++j) {
               fdSelect.push(fdIndex);
             }
           }
           pos += 2;
-          rawBytes = bytes.subarray(start, pos);
-          if (invalidFirstGID) {
-            rawBytes[3] = rawBytes[4] = 0;
-          }
           break;
         default:
           throw new _util.FormatError(`parseFDSelect: Unknown format "${format}".`);
       }
       if (fdSelect.length !== length) {
         throw new _util.FormatError('parseFDSelect: Invalid font data.');
       }
-      return new CFFFDSelect(fdSelect, rawBytes);
+      return new CFFFDSelect(format, fdSelect);
     }
   };
   return CFFParser;
 }();
 var CFF = function CFFClosure() {
   function CFF() {
     this.header = null;
     this.names = [];
@@ -25682,16 +25645,36 @@ var CFF = function CFFClosure() {
     this.globalSubrIndex = null;
     this.encoding = null;
     this.charset = null;
     this.charStrings = null;
     this.fdArray = [];
     this.fdSelect = null;
     this.isCIDFont = false;
   }
+  CFF.prototype = {
+    duplicateFirstGlyph: function CFF_duplicateFirstGlyph() {
+      if (this.charStrings.count >= 65535) {
+        (0, _util.warn)('Not enough space in charstrings to duplicate first glyph.');
+        return;
+      }
+      var glyphZero = this.charStrings.get(0);
+      this.charStrings.add(glyphZero);
+      if (this.isCIDFont) {
+        this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0]);
+      }
+    },
+    hasGlyphId: function CFF_hasGlyphID(id) {
+      if (id < 0 || id >= this.charStrings.count) {
+        return false;
+      }
+      var glyph = this.charStrings.get(id);
+      return glyph.length > 0;
+    }
+  };
   return CFF;
 }();
 var CFFHeader = function CFFHeaderClosure() {
   function CFFHeader(major, minor, hdrSize, offSize) {
     this.major = major;
     this.minor = minor;
     this.hdrSize = hdrSize;
     this.offSize = offSize;
@@ -25868,19 +25851,19 @@ var CFFEncoding = function CFFEncodingCl
     this.predefined = predefined;
     this.format = format;
     this.encoding = encoding;
     this.raw = raw;
   }
   return CFFEncoding;
 }();
 var CFFFDSelect = function CFFFDSelectClosure() {
-  function CFFFDSelect(fdSelect, raw) {
+  function CFFFDSelect(format, fdSelect) {
+    this.format = format;
     this.fdSelect = fdSelect;
-    this.raw = raw;
   }
   CFFFDSelect.prototype = {
     getFDIndex: function CFFFDSelect_get(glyphIndex) {
       if (glyphIndex < 0 || glyphIndex >= this.fdSelect.length) {
         return -1;
       }
       return this.fdSelect[glyphIndex];
     }
@@ -25961,47 +25944,42 @@ var CFFCompiler = function CFFCompilerCl
             var matrix = base.slice(0);
             if (subDict.hasName('FontMatrix')) {
               matrix = _util.Util.transform(matrix, subDict.getByName('FontMatrix'));
             }
             subDict.setByName('FontMatrix', matrix);
           }
         }
       }
+      cff.topDict.setByName('charset', 0);
       var compiled = this.compileTopDicts([cff.topDict], output.length, cff.isCIDFont);
       output.add(compiled.output);
       var topDictTracker = compiled.trackers[0];
       var stringIndex = this.compileStringIndex(cff.strings.strings);
       output.add(stringIndex);
       var globalSubrIndex = this.compileIndex(cff.globalSubrIndex);
       output.add(globalSubrIndex);
       if (cff.encoding && cff.topDict.hasName('Encoding')) {
         if (cff.encoding.predefined) {
           topDictTracker.setEntryLocation('Encoding', [cff.encoding.format], output);
         } else {
           var encoding = this.compileEncoding(cff.encoding);
           topDictTracker.setEntryLocation('Encoding', [output.length], output);
           output.add(encoding);
         }
       }
-      if (cff.charset && cff.topDict.hasName('charset')) {
-        if (cff.charset.predefined) {
-          topDictTracker.setEntryLocation('charset', [cff.charset.format], output);
-        } else {
-          var charset = this.compileCharset(cff.charset);
-          topDictTracker.setEntryLocation('charset', [output.length], output);
-          output.add(charset);
-        }
-      }
+      var charset = this.compileCharset(cff.charset);
+      topDictTracker.setEntryLocation('charset', [output.length], output);
+      output.add(charset);
       var charStrings = this.compileCharStrings(cff.charStrings);
       topDictTracker.setEntryLocation('CharStrings', [output.length], output);
       output.add(charStrings);
       if (cff.isCIDFont) {
         topDictTracker.setEntryLocation('FDSelect', [output.length], output);
-        var fdSelect = this.compileFDSelect(cff.fdSelect.raw);
+        var fdSelect = this.compileFDSelect(cff.fdSelect);
         output.add(fdSelect);
         compiled = this.compileTopDicts(cff.fdArray, output.length, true);
         topDictTracker.setEntryLocation('FDArray', [output.length], output);
         output.add(compiled.output);
         var fontDictTrackers = compiled.trackers;
         this.compilePrivateDicts(cff.fdArray, fontDictTrackers, output);
       }
       this.compilePrivateDicts([cff.topDict], [topDictTracker], output);
@@ -26186,26 +26164,65 @@ var CFFCompiler = function CFFCompilerCl
       }
       return this.compileIndex(stringIndex);
     },
     compileGlobalSubrIndex: function CFFCompiler_compileGlobalSubrIndex() {
       var globalSubrIndex = this.cff.globalSubrIndex;
       this.out.writeByteArray(this.compileIndex(globalSubrIndex));
     },
     compileCharStrings: function CFFCompiler_compileCharStrings(charStrings) {
-      return this.compileIndex(charStrings);
+      var charStringsIndex = new CFFIndex();
+      for (var i = 0; i < charStrings.count; i++) {
+        var glyph = charStrings.get(i);
+        if (glyph.length === 0) {
+          charStringsIndex.add(new Uint8Array([0x8B, 0x0E]));
+          continue;
+        }
+        charStringsIndex.add(glyph);
+      }
+      return this.compileIndex(charStringsIndex);
     },
     compileCharset: function CFFCompiler_compileCharset(charset) {
-      return this.compileTypedArray(charset.raw);
+      let length = 1 + (this.cff.charStrings.count - 1) * 2;
+      let out = new Uint8Array(length);
+      return this.compileTypedArray(out);
     },
     compileEncoding: function CFFCompiler_compileEncoding(encoding) {
       return this.compileTypedArray(encoding.raw);
     },
     compileFDSelect: function CFFCompiler_compileFDSelect(fdSelect) {
-      return this.compileTypedArray(fdSelect);
+      let format = fdSelect.format;
+      let out, i;
+      switch (format) {
+        case 0:
+          out = new Uint8Array(1 + fdSelect.fdSelect.length);
+          out[0] = format;
+          for (i = 0; i < fdSelect.fdSelect.length; i++) {
+            out[i + 1] = fdSelect.fdSelect[i];
+          }
+          break;
+        case 3:
+          let start = 0;
+          let lastFD = fdSelect.fdSelect[0];
+          let ranges = [format, 0, 0, start >> 8 & 0xFF, start & 0xFF, lastFD];
+          for (i = 1; i < fdSelect.fdSelect.length; i++) {
+            let currentFD = fdSelect.fdSelect[i];
+            if (currentFD !== lastFD) {
+              ranges.push(i >> 8 & 0xFF, i & 0xFF, currentFD);
+              lastFD = currentFD;
+            }
+          }
+          let numRanges = (ranges.length - 3) / 3;
+          ranges[1] = numRanges >> 8 & 0xFF;
+          ranges[2] = numRanges & 0xFF;
+          ranges.push(i >> 8 & 0xFF, i & 0xFF);
+          out = new Uint8Array(ranges);
+          break;
+      }
+      return this.compileTypedArray(out);
     },
     compileTypedArray: function CFFCompiler_compileTypedArray(data) {
       var out = [];
       for (var i = 0, ii = data.length; i < ii; ++i) {
         out[i] = data[i];
       }
       return out;
     },
@@ -26266,16 +26283,17 @@ exports.CFFParser = CFFParser;
 exports.CFF = CFF;
 exports.CFFHeader = CFFHeader;
 exports.CFFStrings = CFFStrings;
 exports.CFFIndex = CFFIndex;
 exports.CFFCharset = CFFCharset;
 exports.CFFTopDict = CFFTopDict;
 exports.CFFPrivateDict = CFFPrivateDict;
 exports.CFFCompiler = CFFCompiler;
+exports.CFFFDSelect = CFFFDSelect;
 
 /***/ }),
 /* 32 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
@@ -33698,17 +33716,17 @@ var FontRendererFactory = function FontR
     for (var j = itemSize; j < loca.length; j += itemSize) {
       var endOffset = itemDecode(loca, j);
       glyphs.push(glyf.subarray(startOffset, endOffset));
       startOffset = endOffset;
     }
     return glyphs;
   }
   function lookupCmap(ranges, unicode) {
-    var code = unicode.charCodeAt(0),
+    var code = unicode.codePointAt(0),
         gid = 0;
     var l = 0,
         r = ranges.length - 1;
     while (l < r) {
       var c = l + r + 1 >> 1;
       if (code < ranges[c].start) {
         r = c - 1;
       } else {
--- a/browser/extensions/pdfjs/content/web/viewer.html
+++ b/browser/extensions/pdfjs/content/web/viewer.html
@@ -77,21 +77,25 @@ See https://github.com/adobe-type-tools/
               </button>
               <div class="splitToolbarButtonSeparator"></div>
               <button id="findNext" class="toolbarButton findNext" title="Find the next occurrence of the phrase" tabindex="93" data-l10n-id="find_next">
                 <span data-l10n-id="find_next_label">Next</span>
               </button>
             </div>
           </div>
 
-          <div id="findbarOptionsContainer">
+          <div id="findbarOptionsOneContainer">
             <input type="checkbox" id="findHighlightAll" class="toolbarField" tabindex="94">
             <label for="findHighlightAll" class="toolbarLabel" data-l10n-id="find_highlight">Highlight all</label>
             <input type="checkbox" id="findMatchCase" class="toolbarField" tabindex="95">
             <label for="findMatchCase" class="toolbarLabel" data-l10n-id="find_match_case_label">Match case</label>
+          </div>
+          <div id="findbarOptionsTwoContainer">
+            <input type="checkbox" id="findEntireWord" class="toolbarField" tabindex="96">
+            <label for="findEntireWord" class="toolbarLabel" data-l10n-id="find_entire_word_label">Whole words</label>
             <span id="findResultsCount" class="toolbarLabel hidden"></span>
           </div>
 
           <div id="findbarMessageContainer">
             <span id="findMsg" class="toolbarLabel"></span>
           </div>
         </div>  <!-- findbar -->
 
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -115,18 +115,18 @@
 
 ;
 let pdfjsWebApp, pdfjsWebAppOptions;
 {
   pdfjsWebApp = __webpack_require__(1);
   pdfjsWebAppOptions = __webpack_require__(8);
 }
 {
-  __webpack_require__(33);
-  __webpack_require__(36);
+  __webpack_require__(34);
+  __webpack_require__(37);
 }
 ;
 ;
 ;
 function getViewerConfiguration() {
   return {
     appContainer: document.body,
     mainContainer: document.getElementById('viewerContainer'),
@@ -195,19 +195,19 @@ function getViewerConfiguration() {
       resizer: document.getElementById('sidebarResizer')
     },
     findBar: {
       bar: document.getElementById('findbar'),
       toggleButton: document.getElementById('viewFind'),
       findField: document.getElementById('findInput'),
       highlightAllCheckbox: document.getElementById('findHighlightAll'),
       caseSensitiveCheckbox: document.getElementById('findMatchCase'),
+      entireWordCheckbox: document.getElementById('findEntireWord'),
       findMsg: document.getElementById('findMsg'),
       findResultsCount: document.getElementById('findResultsCount'),
-      findStatusIcon: document.getElementById('findStatusIcon'),
       findPreviousButton: document.getElementById('findPrevious'),
       findNextButton: document.getElementById('findNext')
     },
     passwordOverlay: {
       overlayName: 'passwordOverlay',
       container: document.getElementById('passwordOverlay'),
       label: document.getElementById('passwordText'),
       input: document.getElementById('password'),
@@ -293,41 +293,42 @@ var _password_prompt = __webpack_require
 var _pdf_attachment_viewer = __webpack_require__(13);
 
 var _pdf_document_properties = __webpack_require__(14);
 
 var _pdf_find_bar = __webpack_require__(15);
 
 var _pdf_find_controller = __webpack_require__(16);
 
-var _pdf_history = __webpack_require__(17);
-
-var _pdf_link_service = __webpack_require__(18);
-
-var _pdf_outline_viewer = __webpack_require__(19);
-
-var _pdf_presentation_mode = __webpack_require__(20);
-
-var _pdf_sidebar_resizer = __webpack_require__(21);
-
-var _pdf_thumbnail_viewer = __webpack_require__(22);
-
-var _pdf_viewer = __webpack_require__(24);
-
-var _secondary_toolbar = __webpack_require__(29);
-
-var _toolbar = __webpack_require__(31);
-
-var _view_history = __webpack_require__(32);
+var _pdf_history = __webpack_require__(18);
+
+var _pdf_link_service = __webpack_require__(19);
+
+var _pdf_outline_viewer = __webpack_require__(20);
+
+var _pdf_presentation_mode = __webpack_require__(21);
+
+var _pdf_sidebar_resizer = __webpack_require__(22);
+
+var _pdf_thumbnail_viewer = __webpack_require__(23);
+
+var _pdf_viewer = __webpack_require__(25);
+
+var _secondary_toolbar = __webpack_require__(30);
+
+var _toolbar = __webpack_require__(32);
+
+var _view_history = __webpack_require__(33);
 
 const DEFAULT_SCALE_DELTA = 1.1;
 const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
 const FORCE_PAGES_LOADED_TIMEOUT = 10000;
 const DefaultExternalServices = {
   updateFindControlState(data) {},
+  updateFindMatchesCount(data) {},
   initPassiveLoading(callbacks) {},
   fallback(data, callback) {},
   reportTelemetry(data) {},
   createDownloadManager(options) {
     throw new Error('Not implemented: createDownloadManager');
   },
   createPreferences() {
     throw new Error('Not implemented: createPreferences');
@@ -374,228 +375,224 @@ let PDFViewerApplication = {
   isInitialViewSet: false,
   downloadComplete: false,
   isViewerEmbedded: window.parent !== window,
   url: '',
   baseUrl: '',
   externalServices: DefaultExternalServices,
   _boundEvents: {},
   contentDispositionFilename: null,
-  initialize(appConfig) {
+  async initialize(appConfig) {
     this.preferences = this.externalServices.createPreferences();
     this.appConfig = appConfig;
-    return this._readPreferences().then(() => {
-      return this._parseHashParameters();
-    }).then(() => {
-      return this._initializeL10n();
-    }).then(() => {
-      if (this.isViewerEmbedded && _app_options.AppOptions.get('externalLinkTarget') === _pdfjsLib.LinkTarget.NONE) {
-        _app_options.AppOptions.set('externalLinkTarget', _pdfjsLib.LinkTarget.TOP);
-      }
-      return this._initializeViewerComponents();
-    }).then(() => {
-      this.bindEvents();
-      this.bindWindowEvents();
-      let appContainer = appConfig.appContainer || document.documentElement;
-      this.l10n.translate(appContainer).then(() => {
-        this.eventBus.dispatch('localized', { source: this });
-      });
-      this.initialized = true;
-    });
+    await this._readPreferences();
+    await this._parseHashParameters();
+    await this._initializeL10n();
+    if (this.isViewerEmbedded && _app_options.AppOptions.get('externalLinkTarget') === _pdfjsLib.LinkTarget.NONE) {
+      _app_options.AppOptions.set('externalLinkTarget', _pdfjsLib.LinkTarget.TOP);
+    }
+    await this._initializeViewerComponents();
+    this.bindEvents();
+    this.bindWindowEvents();
+    let appContainer = appConfig.appContainer || document.documentElement;
+    this.l10n.translate(appContainer).then(() => {
+      this.eventBus.dispatch('localized', { source: this });
+    });
+    this.initialized = true;
   },
-  _readPreferences() {
+  async _readPreferences() {
     const OVERRIDES = {
       disableFontFace: true,
       disableRange: true,
       disableStream: true,
       textLayerMode: _ui_utils.TextLayerMode.DISABLE
     };
-    return this.preferences.getAll().then(function (prefs) {
+    try {
+      const prefs = await this.preferences.getAll();
       for (let name in prefs) {
         if (name in OVERRIDES && _app_options.AppOptions.get(name) === OVERRIDES[name]) {
           continue;
         }
         _app_options.AppOptions.set(name, prefs[name]);
       }
-    }, function (reason) {});
+    } catch (reason) {}
   },
-  _parseHashParameters() {
+  async _parseHashParameters() {
+    if (!_app_options.AppOptions.get('pdfBugEnabled')) {
+      return;
+    }
     const waitOn = [];
-    if (_app_options.AppOptions.get('pdfBugEnabled')) {
-      let hash = document.location.hash.substring(1);
-      let hashParams = (0, _ui_utils.parseQueryString)(hash);
-      if ('disableworker' in hashParams && hashParams['disableworker'] === 'true') {
-        waitOn.push(loadFakeWorker());
-      }
-      if ('disablerange' in hashParams) {
-        _app_options.AppOptions.set('disableRange', hashParams['disablerange'] === 'true');
-      }
-      if ('disablestream' in hashParams) {
-        _app_options.AppOptions.set('disableStream', hashParams['disablestream'] === 'true');
-      }
-      if ('disableautofetch' in hashParams) {
-        _app_options.AppOptions.set('disableAutoFetch', hashParams['disableautofetch'] === 'true');
-      }
-      if ('disablefontface' in hashParams) {
-        _app_options.AppOptions.set('disableFontFace', hashParams['disablefontface'] === 'true');
-      }
-      if ('disablehistory' in hashParams) {
-        _app_options.AppOptions.set('disableHistory', hashParams['disablehistory'] === 'true');
-      }
-      if ('webgl' in hashParams) {
-        _app_options.AppOptions.set('enableWebGL', hashParams['webgl'] === 'true');
-      }
-      if ('useonlycsszoom' in hashParams) {
-        _app_options.AppOptions.set('useOnlyCssZoom', hashParams['useonlycsszoom'] === 'true');
-      }
-      if ('verbosity' in hashParams) {
-        _app_options.AppOptions.set('verbosity', hashParams['verbosity'] | 0);
-      }
-      if ('textlayer' in hashParams) {
-        switch (hashParams['textlayer']) {
-          case 'off':
-            _app_options.AppOptions.set('textLayerMode', _ui_utils.TextLayerMode.DISABLE);
-            break;
-          case 'visible':
-          case 'shadow':
-          case 'hover':
-            let viewer = this.appConfig.viewerContainer;
-            viewer.classList.add('textLayer-' + hashParams['textlayer']);
-            break;
-        }
-      }
-      if ('pdfbug' in hashParams) {
-        _app_options.AppOptions.set('pdfBug', true);
-        let enabled = hashParams['pdfbug'].split(',');
-        waitOn.push(loadAndEnablePDFBug(enabled));
-      }
+    let hash = document.location.hash.substring(1);
+    let hashParams = (0, _ui_utils.parseQueryString)(hash);
+    if ('disableworker' in hashParams && hashParams['disableworker'] === 'true') {
+      waitOn.push(loadFakeWorker());
+    }
+    if ('disablerange' in hashParams) {
+      _app_options.AppOptions.set('disableRange', hashParams['disablerange'] === 'true');
+    }
+    if ('disablestream' in hashParams) {
+      _app_options.AppOptions.set('disableStream', hashParams['disablestream'] === 'true');
+    }
+    if ('disableautofetch' in hashParams) {
+      _app_options.AppOptions.set('disableAutoFetch', hashParams['disableautofetch'] === 'true');
+    }
+    if ('disablefontface' in hashParams) {
+      _app_options.AppOptions.set('disableFontFace', hashParams['disablefontface'] === 'true');
+    }
+    if ('disablehistory' in hashParams) {
+      _app_options.AppOptions.set('disableHistory', hashParams['disablehistory'] === 'true');
+    }
+    if ('webgl' in hashParams) {
+      _app_options.AppOptions.set('enableWebGL', hashParams['webgl'] === 'true');
+    }
+    if ('useonlycsszoom' in hashParams) {
+      _app_options.AppOptions.set('useOnlyCssZoom', hashParams['useonlycsszoom'] === 'true');
+    }
+    if ('verbosity' in hashParams) {
+      _app_options.AppOptions.set('verbosity', hashParams['verbosity'] | 0);
+    }
+    if ('textlayer' in hashParams) {
+      switch (hashParams['textlayer']) {
+        case 'off':
+          _app_options.AppOptions.set('textLayerMode', _ui_utils.TextLayerMode.DISABLE);
+          break;
+        case 'visible':
+        case 'shadow':
+        case 'hover':
+          let viewer = this.appConfig.viewerContainer;
+          viewer.classList.add('textLayer-' + hashParams['textlayer']);
+          break;
+      }
+    }
+    if ('pdfbug' in hashParams) {
+      _app_options.AppOptions.set('pdfBug', true);
+      let enabled = hashParams['pdfbug'].split(',');
+      waitOn.push(loadAndEnablePDFBug(enabled));
     }
     return Promise.all(waitOn);
   },
-  _initializeL10n() {
+  async _initializeL10n() {
     this.l10n = this.externalServices.createL10n({ locale: _app_options.AppOptions.get('locale') });
-    return this.l10n.getDirection().then(dir => {
-      document.getElementsByTagName('html')[0].dir = dir;
-    });
+    const dir = await this.l10n.getDirection();
+    document.getElementsByTagName('html')[0].dir = dir;
   },
-  _initializeViewerComponents() {
-    let { appConfig } = this;
-    return new Promise((resolve, reject) => {
-      this.overlayManager = new _overlay_manager.OverlayManager();
-      const dispatchToDOM = _app_options.AppOptions.get('eventBusDispatchToDOM');
-      let eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)(dispatchToDOM);
-      this.eventBus = eventBus;
-      let pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
-      pdfRenderingQueue.onIdle = this.cleanup.bind(this);
-      this.pdfRenderingQueue = pdfRenderingQueue;
-      let pdfLinkService = new _pdf_link_service.PDFLinkService({
-        eventBus,
-        externalLinkTarget: _app_options.AppOptions.get('externalLinkTarget'),
-        externalLinkRel: _app_options.AppOptions.get('externalLinkRel')
-      });
-      this.pdfLinkService = pdfLinkService;
-      let downloadManager = this.externalServices.createDownloadManager({ disableCreateObjectURL: _app_options.AppOptions.get('disableCreateObjectURL') });
-      this.downloadManager = downloadManager;
-      let container = appConfig.mainContainer;
-      let viewer = appConfig.viewerContainer;
-      this.pdfViewer = new _pdf_viewer.PDFViewer({
+  async _initializeViewerComponents() {
+    const appConfig = this.appConfig;
+    this.overlayManager = new _overlay_manager.OverlayManager();
+    const dispatchToDOM = _app_options.AppOptions.get('eventBusDispatchToDOM');
+    let eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)(dispatchToDOM);
+    this.eventBus = eventBus;
+    let pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
+    pdfRenderingQueue.onIdle = this.cleanup.bind(this);
+    this.pdfRenderingQueue = pdfRenderingQueue;
+    let pdfLinkService = new _pdf_link_service.PDFLinkService({
+      eventBus,
+      externalLinkTarget: _app_options.AppOptions.get('externalLinkTarget'),
+      externalLinkRel: _app_options.AppOptions.get('externalLinkRel')
+    });
+    this.pdfLinkService = pdfLinkService;
+    let downloadManager = this.externalServices.createDownloadManager({ disableCreateObjectURL: _app_options.AppOptions.get('disableCreateObjectURL') });
+    this.downloadManager = downloadManager;
+    let container = appConfig.mainContainer;
+    let viewer = appConfig.viewerContainer;
+    this.pdfViewer = new _pdf_viewer.PDFViewer({
+      container,
+      viewer,
+      eventBus,
+      renderingQueue: pdfRenderingQueue,
+      linkService: pdfLinkService,
+      downloadManager,
+      renderer: _app_options.AppOptions.get('renderer'),
+      enableWebGL: _app_options.AppOptions.get('enableWebGL'),
+      l10n: this.l10n,
+      textLayerMode: _app_options.AppOptions.get('textLayerMode'),
+      imageResourcesPath: _app_options.AppOptions.get('imageResourcesPath'),
+      renderInteractiveForms: _app_options.AppOptions.get('renderInteractiveForms'),
+      enablePrintAutoRotate: _app_options.AppOptions.get('enablePrintAutoRotate'),
+      useOnlyCssZoom: _app_options.AppOptions.get('useOnlyCssZoom'),
+      maxCanvasPixels: _app_options.AppOptions.get('maxCanvasPixels')
+    });
+    pdfRenderingQueue.setViewer(this.pdfViewer);
+    pdfLinkService.setViewer(this.pdfViewer);
+    let thumbnailContainer = appConfig.sidebar.thumbnailView;
+    this.pdfThumbnailViewer = new _pdf_thumbnail_viewer.PDFThumbnailViewer({
+      container: thumbnailContainer,
+      renderingQueue: pdfRenderingQueue,
+      linkService: pdfLinkService,
+      l10n: this.l10n
+    });
+    pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
+    this.pdfHistory = new _pdf_history.PDFHistory({
+      linkService: pdfLinkService,
+      eventBus
+    });
+    pdfLinkService.setHistory(this.pdfHistory);
+    this.findController = new _pdf_find_controller.PDFFindController({
+      pdfViewer: this.pdfViewer,
+      eventBus
+    });
+    this.findController.onUpdateResultsCount = matchesCount => {
+      if (this.supportsIntegratedFind) {
+        this.externalServices.updateFindMatchesCount(matchesCount);
+      } else {
+        this.findBar.updateResultsCount(matchesCount);
+      }
+    };
+    this.findController.onUpdateState = (state, previous, matchesCount) => {
+      if (this.supportsIntegratedFind) {
+        this.externalServices.updateFindControlState({
+          result: state,
+          findPrevious: previous,
+          matchesCount
+        });
+      } else {
+        this.findBar.updateUIState(state, previous, matchesCount);
+      }
+    };
+    this.pdfViewer.setFindController(this.findController);
+    let findBarConfig = Object.create(appConfig.findBar);
+    findBarConfig.findController = this.findController;
+    findBarConfig.eventBus = eventBus;
+    this.findBar = new _pdf_find_bar.PDFFindBar(findBarConfig, this.l10n);
+    this.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, this.l10n);
+    this.pdfCursorTools = new _pdf_cursor_tools.PDFCursorTools({
+      container,
+      eventBus,
+      cursorToolOnLoad: _app_options.AppOptions.get('cursorToolOnLoad')
+    });
+    this.toolbar = new _toolbar.Toolbar(appConfig.toolbar, container, eventBus, this.l10n);
+    this.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
+    if (this.supportsFullscreen) {
+      this.pdfPresentationMode = new _pdf_presentation_mode.PDFPresentationMode({
         container,
         viewer,
+        pdfViewer: this.pdfViewer,
         eventBus,
-        renderingQueue: pdfRenderingQueue,
-        linkService: pdfLinkService,
-        downloadManager,
-        renderer: _app_options.AppOptions.get('renderer'),
-        enableWebGL: _app_options.AppOptions.get('enableWebGL'),
-        l10n: this.l10n,
-        textLayerMode: _app_options.AppOptions.get('textLayerMode'),
-        imageResourcesPath: _app_options.AppOptions.get('imageResourcesPath'),
-        renderInteractiveForms: _app_options.AppOptions.get('renderInteractiveForms'),
-        enablePrintAutoRotate: _app_options.AppOptions.get('enablePrintAutoRotate'),
-        useOnlyCssZoom: _app_options.AppOptions.get('useOnlyCssZoom'),
-        maxCanvasPixels: _app_options.AppOptions.get('maxCanvasPixels')
-      });
-      pdfRenderingQueue.setViewer(this.pdfViewer);
-      pdfLinkService.setViewer(this.pdfViewer);
-      let thumbnailContainer = appConfig.sidebar.thumbnailView;
-      this.pdfThumbnailViewer = new _pdf_thumbnail_viewer.PDFThumbnailViewer({
-        container: thumbnailContainer,
-        renderingQueue: pdfRenderingQueue,
-        linkService: pdfLinkService,
-        l10n: this.l10n
-      });
-      pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
-      this.pdfHistory = new _pdf_history.PDFHistory({
-        linkService: pdfLinkService,
-        eventBus
-      });
-      pdfLinkService.setHistory(this.pdfHistory);
-      this.findController = new _pdf_find_controller.PDFFindController({
-        pdfViewer: this.pdfViewer,
-        eventBus
+        contextMenuItems: appConfig.fullscreen
       });
-      this.findController.onUpdateResultsCount = matchCount => {
-        if (this.supportsIntegratedFind) {
-          return;
-        }
-        this.findBar.updateResultsCount(matchCount);
-      };
-      this.findController.onUpdateState = (state, previous, matchCount) => {
-        if (this.supportsIntegratedFind) {
-          this.externalServices.updateFindControlState({
-            result: state,
-            findPrevious: previous
-          });
-        } else {
-          this.findBar.updateUIState(state, previous, matchCount);
-        }
-      };
-      this.pdfViewer.setFindController(this.findController);
-      let findBarConfig = Object.create(appConfig.findBar);
-      findBarConfig.findController = this.findController;
-      findBarConfig.eventBus = eventBus;
-      this.findBar = new _pdf_find_bar.PDFFindBar(findBarConfig, this.l10n);
-      this.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, this.l10n);
-      this.pdfCursorTools = new _pdf_cursor_tools.PDFCursorTools({
-        container,
-        eventBus,
-        cursorToolOnLoad: _app_options.AppOptions.get('cursorToolOnLoad')
-      });
-      this.toolbar = new _toolbar.Toolbar(appConfig.toolbar, container, eventBus, this.l10n);
-      this.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
-      if (this.supportsFullscreen) {
-        this.pdfPresentationMode = new _pdf_presentation_mode.PDFPresentationMode({
-          container,
-          viewer,
-          pdfViewer: this.pdfViewer,
-          eventBus,
-          contextMenuItems: appConfig.fullscreen
-        });
-      }
-      this.passwordPrompt = new _password_prompt.PasswordPrompt(appConfig.passwordOverlay, this.overlayManager, this.l10n);
-      this.pdfOutlineViewer = new _pdf_outline_viewer.PDFOutlineViewer({
-        container: appConfig.sidebar.outlineView,
-        eventBus,
-        linkService: pdfLinkService
-      });
-      this.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({
-        container: appConfig.sidebar.attachmentsView,
-        eventBus,
-        downloadManager
-      });
-      let sidebarConfig = Object.create(appConfig.sidebar);
-      sidebarConfig.pdfViewer = this.pdfViewer;
-      sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
-      sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;
-      sidebarConfig.eventBus = eventBus;
-      this.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig, this.l10n);
-      this.pdfSidebar.onToggled = this.forceRendering.bind(this);
-      this.pdfSidebarResizer = new _pdf_sidebar_resizer.PDFSidebarResizer(appConfig.sidebarResizer, eventBus, this.l10n);
-      resolve(undefined);
-    });
+    }
+    this.passwordPrompt = new _password_prompt.PasswordPrompt(appConfig.passwordOverlay, this.overlayManager, this.l10n);
+    this.pdfOutlineViewer = new _pdf_outline_viewer.PDFOutlineViewer({
+      container: appConfig.sidebar.outlineView,
+      eventBus,
+      linkService: pdfLinkService
+    });
+    this.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({
+      container: appConfig.sidebar.attachmentsView,
+      eventBus,
+      downloadManager
+    });
+    let sidebarConfig = Object.create(appConfig.sidebar);
+    sidebarConfig.pdfViewer = this.pdfViewer;
+    sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
+    sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;
+    sidebarConfig.eventBus = eventBus;
+    this.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig, this.l10n);
+    this.pdfSidebar.onToggled = this.forceRendering.bind(this);
+    this.pdfSidebarResizer = new _pdf_sidebar_resizer.PDFSidebarResizer(appConfig.sidebarResizer, eventBus, this.l10n);
   },
   run(config) {
     this.initialize(config).then(webViewerInitialized);
   },
   zoomIn(ticks) {
     let newScale = this.pdfViewer.currentScale;
     do {
       newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
@@ -698,21 +695,21 @@ let PDFViewerApplication = {
     this.setTitle(title);
   },
   setTitle(title) {
     if (this.isViewerEmbedded) {
       return;
     }
     document.title = title;
   },
-  close() {
+  async close() {
     let errorWrapper = this.appConfig.errorWrapper.container;
     errorWrapper.setAttribute('hidden', 'true');
     if (!this.pdfLoadingTask) {
-      return Promise.resolve();
+      return;
     }
     let promise = this.pdfLoadingTask.destroy();
     this.pdfLoadingTask = null;
     if (this.pdfDocument) {
       this.pdfDocument = null;
       this.pdfThumbnailViewer.setDocument(null);
       this.pdfViewer.setDocument(null);
       this.pdfLinkService.setDocument(null, null);
@@ -731,21 +728,19 @@ let PDFViewerApplication = {
     this.findBar.reset();
     this.toolbar.reset();
     this.secondaryToolbar.reset();
     if (typeof PDFBug !== 'undefined') {
       PDFBug.cleanup();
     }
     return promise;
   },
-  open(file, args) {
+  async open(file, args) {
     if (this.pdfLoadingTask) {
-      return this.close().then(() => {
-        return this.open(file, args);
-      });
+      await this.close();
     }
     const workerParameters = _app_options.AppOptions.getAll('worker');
     for (let key in workerParameters) {
       _pdfjsLib.GlobalWorkerOptions[key] = workerParameters[key];
     }
     let parameters = Object.create(null);
     if (typeof file === 'string') {
       this.setTitleUsingUrl(file);
@@ -910,80 +905,66 @@ let PDFViewerApplication = {
       if (!_app_options.AppOptions.get('disableHistory') && !this.isViewerEmbedded) {
         let resetHistory = !_app_options.AppOptions.get('showPreviousViewOnLoad');
         this.pdfHistory.initialize(pdfDocument.fingerprint, resetHistory);
         if (this.pdfHistory.initialBookmark) {
           this.initialBookmark = this.pdfHistory.initialBookmark;
           this.initialRotation = this.pdfHistory.initialRotation;
         }
       }
-      let initialParams = {
-        bookmark: null,
-        hash: null
-      };
       let storePromise = store.getMultiple({
         page: null,
         zoom: _ui_utils.DEFAULT_SCALE_VALUE,
         scrollLeft: '0',
         scrollTop: '0',
         rotation: null,
         sidebarView: _pdf_sidebar.SidebarView.NONE,
         scrollMode: null,
         spreadMode: null
       }).catch(() => {});
-      Promise.all([storePromise, pageModePromise]).then(([values = {}, pageMode]) => {
+      Promise.all([storePromise, pageModePromise]).then(async ([values = {}, pageMode]) => {
+        const initialBookmark = this.initialBookmark;
         const zoom = _app_options.AppOptions.get('defaultZoomValue');
         let hash = zoom ? `zoom=${zoom}` : null;
         let rotation = null;
         let sidebarView = _app_options.AppOptions.get('sidebarViewOnLoad');
         let scrollMode = _app_options.AppOptions.get('scrollModeOnLoad');
         let spreadMode = _app_options.AppOptions.get('spreadModeOnLoad');
         if (values.page && _app_options.AppOptions.get('showPreviousViewOnLoad')) {
           hash = 'page=' + values.page + '&zoom=' + (zoom || values.zoom) + ',' + values.scrollLeft + ',' + values.scrollTop;
           rotation = parseInt(values.rotation, 10);
           sidebarView = sidebarView || values.sidebarView | 0;
           scrollMode = scrollMode || values.scrollMode | 0;
           spreadMode = spreadMode || values.spreadMode | 0;
         }
         if (pageMode && !_app_options.AppOptions.get('disablePageMode')) {
           sidebarView = sidebarView || apiPageModeToSidebarView(pageMode);
         }
-        return {
-          hash,
-          rotation,
-          sidebarView,
-          scrollMode,
-          spreadMode
-        };
-      }).then(({ hash, rotation, sidebarView, scrollMode, spreadMode }) => {
-        initialParams.bookmark = this.initialBookmark;
-        initialParams.hash = hash;
         this.setInitialView(hash, {
           rotation,
           sidebarView,
           scrollMode,
           spreadMode
         });
         this.eventBus.dispatch('documentinit', { source: this });
         if (!this.isViewerEmbedded) {
           pdfViewer.focus();
         }
-        return Promise.race([pagesPromise, new Promise(resolve => {
+        await Promise.race([pagesPromise, new Promise(resolve => {
           setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT);
         })]);
-      }).then(() => {
-        if (!initialParams.bookmark && !initialParams.hash) {
+        if (!initialBookmark && !hash) {
           return;
         }
         if (pdfViewer.hasEqualPageSizes) {
           return;
         }
-        this.initialBookmark = initialParams.bookmark;
+        this.initialBookmark = initialBookmark;
         pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;
-        this.setInitialView(initialParams.hash);
+        this.setInitialView(hash);
       }).then(function () {
         pdfViewer.update();
       });
     });
     pdfDocument.getPageLabels().then(labels => {
       if (!labels || _app_options.AppOptions.get('disablePageLabels')) {
         return;
       }
@@ -1340,23 +1321,23 @@ function webViewerInitialized() {
   appConfig.mainContainer.addEventListener('transitionend', function (evt) {
     if (evt.target === this) {
       PDFViewerApplication.eventBus.dispatch('resize', { source: this });
     }
   }, true);
   appConfig.sidebar.toggleButton.addEventListener('click', function () {
     PDFViewerApplication.pdfSidebar.toggle();
   });
-  Promise.resolve().then(function () {
+  try {
     webViewerOpenFileViaURL(file);
-  }).catch(function (reason) {
+  } catch (reason) {
     PDFViewerApplication.l10n.get('loading_error', null, 'An error occurred while loading the PDF.').then(msg => {
       PDFViewerApplication.error(msg, reason);
     });
-  });
+  }
 }
 let webViewerOpenFileViaURL;
 {
   webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) {
     PDFViewerApplication.setTitleUsingUrl(file);
     PDFViewerApplication.initPassiveLoading();
   };
 }
@@ -1557,25 +1538,27 @@ function webViewerSwitchSpreadMode(evt) 
 function webViewerDocumentProperties() {
   PDFViewerApplication.pdfDocumentProperties.open();
 }
 function webViewerFind(evt) {
   PDFViewerApplication.findController.executeCommand('find' + evt.type, {
     query: evt.query,
     phraseSearch: evt.phraseSearch,
     caseSensitive: evt.caseSensitive,
+    entireWord: evt.entireWord,
     highlightAll: evt.highlightAll,
     findPrevious: evt.findPrevious
   });
 }
 function webViewerFindFromUrlHash(evt) {
   PDFViewerApplication.findController.executeCommand('find', {
     query: evt.query,
     phraseSearch: evt.phraseSearch,
     caseSensitive: false,
+    entireWord: false,
     highlightAll: true,
     findPrevious: false
   });
 }
 function webViewerScaleChanging(evt) {
   PDFViewerApplication.toolbar.setPageScale(evt.presetValue, evt.scale);
   PDFViewerApplication.pdfViewer.update();
 }
@@ -1669,16 +1652,17 @@ function webViewerKeyDown(evt) {
       case 71:
         if (!PDFViewerApplication.supportsIntegratedFind) {
           let findState = PDFViewerApplication.findController.state;
           if (findState) {
             PDFViewerApplication.findController.executeCommand('findagain', {
               query: findState.query,
               phraseSearch: findState.phraseSearch,
               caseSensitive: findState.caseSensitive,
+              entireWord: findState.entireWord,
               highlightAll: findState.highlightAll,
               findPrevious: cmd === 5 || cmd === 12
             });
           }
           handled = true;
         }
         break;
       case 61:
@@ -1936,28 +1920,26 @@ function formatL10nValue(text, args) {
   if (!args) {
     return text;
   }
   return text.replace(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => {
     return name in args ? args[name] : '{{' + name + '}}';
   });
 }
 let NullL10n = {
-  getLanguage() {
-    return Promise.resolve('en-us');
-  },
-  getDirection() {
-    return Promise.resolve('ltr');
+  async getLanguage() {
+    return 'en-us';
   },
-  get(property, args, fallback) {
-    return Promise.resolve(formatL10nValue(fallback, args));
+  async getDirection() {
+    return 'ltr';
   },
-  translate(element) {
-    return Promise.resolve();
-  }
+  async get(property, args, fallback) {
+    return formatL10nValue(fallback, args);
+  },
+  async translate(element) {}
 };
 function getOutputScale(ctx) {
   let devicePixelRatio = window.devicePixelRatio || 1;
   let backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
   let pixelRatio = devicePixelRatio / backingStoreRatio;
   return {
     sx: pixelRatio,
     sy: pixelRatio,
@@ -3475,79 +3457,67 @@ class OverlayManager {
   constructor() {
     this._overlays = {};
     this._active = null;
     this._keyDownBound = this._keyDown.bind(this);
   }
   get active() {
     return this._active;
   }
-  register(name, element, callerCloseMethod = null, canForceClose = false) {
-    return new Promise(resolve => {
-      let container;
-      if (!name || !element || !(container = element.parentNode)) {
-        throw new Error('Not enough parameters.');
-      } else if (this._overlays[name]) {
-        throw new Error('The overlay is already registered.');
-      }
-      this._overlays[name] = {
-        element,
-        container,
-        callerCloseMethod,
-        canForceClose
-      };
-      resolve();
-    });
-  }
-  unregister(name) {
-    return new Promise(resolve => {
-      if (!this._overlays[name]) {
-        throw new Error('The overlay does not exist.');
+  async register(name, element, callerCloseMethod = null, canForceClose = false) {
+    let container;
+    if (!name || !element || !(container = element.parentNode)) {
+      throw new Error('Not enough parameters.');
+    } else if (this._overlays[name]) {
+      throw new Error('The overlay is already registered.');
+    }
+    this._overlays[name] = {
+      element,
+      container,
+      callerCloseMethod,
+      canForceClose
+    };
+  }
+  async unregister(name) {
+    if (!this._overlays[name]) {
+      throw new Error('The overlay does not exist.');
+    } else if (this._active === name) {
+      throw new Error('The overlay cannot be removed while it is active.');
+    }
+    delete this._overlays[name];
+  }
+  async open(name) {
+    if (!this._overlays[name]) {
+      throw new Error('The overlay does not exist.');
+    } else if (this._active) {
+      if (this._overlays[name].canForceClose) {
+        this._closeThroughCaller();
       } else if (this._active === name) {
-        throw new Error('The overlay cannot be removed while it is active.');
-      }
-      delete this._overlays[name];
-      resolve();
-    });
-  }
-  open(name) {
-    return new Promise(resolve => {
-      if (!this._overlays[name]) {
-        throw new Error('The overlay does not exist.');
-      } else if (this._active) {
-        if (this._overlays[name].canForceClose) {
-          this._closeThroughCaller();
-        } else if (this._active === name) {
-          throw new Error('The overlay is already active.');
-        } else {
-          throw new Error('Another overlay is currently active.');
-        }
-      }
-      this._active = name;
-      this._overlays[this._active].element.classList.remove('hidden');
-      this._overlays[this._active].container.classList.remove('hidden');
-      window.addEventListener('keydown', this._keyDownBound);
-      resolve();
-    });
-  }
-  close(name) {
-    return new Promise(resolve => {
-      if (!this._overlays[name]) {
-        throw new Error('The overlay does not exist.');
-      } else if (!this._active) {
-        throw new Error('The overlay is currently not active.');
-      } else if (this._active !== name) {
+        throw new Error('The overlay is already active.');
+      } else {
         throw new Error('Another overlay is currently active.');
       }
-      this._overlays[this._active].container.classList.add('hidden');
-      this._overlays[this._active].element.classList.add('hidden');
-      this._active = null;
-      window.removeEventListener('keydown', this._keyDownBound);
-      resolve();
-    });
+    }
+    this._active = name;
+    this._overlays[this._active].element.classList.remove('hidden');
+    this._overlays[this._active].container.classList.remove('hidden');
+    window.addEventListener('keydown', this._keyDownBound);
+  }
+  async close(name) {
+    if (!this._overlays[name]) {
+      throw new Error('The overlay does not exist.');
+    } else if (!this._active) {
+      throw new Error('The overlay is currently not active.');
+    } else if (this._active !== name) {
+      throw new Error('Another overlay is currently active.');
+    }
+    this._overlays[this._active].container.classList.add('hidden');
+    this._overlays[this._active].element.classList.add('hidden');
+    this._active = null;
+    window.removeEventListener('keydown', this._keyDownBound);
   }
   _keyDown(evt) {
     if (this._active && evt.keyCode === 27) {
       this._closeThroughCaller();
       evt.preventDefault();
     }
   }
   _closeThroughCaller() {
@@ -4017,27 +3987,28 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.PDFFindBar = undefined;
 
 var _pdf_find_controller = __webpack_require__(16);
 
 var _ui_utils = __webpack_require__(2);
 
+const MATCHES_COUNT_LIMIT = 1000;
 class PDFFindBar {
   constructor(options, l10n = _ui_utils.NullL10n) {
     this.opened = false;
     this.bar = options.bar || null;
     this.toggleButton = options.toggleButton || null;
     this.findField = options.findField || null;
     this.highlightAll = options.highlightAllCheckbox || null;
     this.caseSensitive = options.caseSensitiveCheckbox || null;
+    this.entireWord = options.entireWordCheckbox || null;
     this.findMsg = options.findMsg || null;
     this.findResultsCount = options.findResultsCount || null;
-    this.findStatusIcon = options.findStatusIcon || null;
     this.findPreviousButton = options.findPreviousButton || null;
     this.findNextButton = options.findNextButton || null;
     this.findController = options.findController || null;
     this.eventBus = options.eventBus;
     this.l10n = l10n;
     if (this.findController === null) {
       throw new Error('PDFFindBar cannot be used without a ' + 'PDFFindController instance.');
     }
@@ -4066,33 +4037,37 @@ class PDFFindBar {
       this.dispatchEvent('again', false);
     });
     this.highlightAll.addEventListener('click', () => {
       this.dispatchEvent('highlightallchange');
     });
     this.caseSensitive.addEventListener('click', () => {
       this.dispatchEvent('casesensitivitychange');
     });
+    this.entireWord.addEventListener('click', () => {
+      this.dispatchEvent('entirewordchange');
+    });
     this.eventBus.on('resize', this._adjustWidth.bind(this));
   }
   reset() {
     this.updateUIState();
   }
   dispatchEvent(type, findPrev) {
     this.eventBus.dispatch('find', {
       source: this,
       type,
       query: this.findField.value,
+      phraseSearch: true,
       caseSensitive: this.caseSensitive.checked,
-      phraseSearch: true,
+      entireWord: this.entireWord.checked,
       highlightAll: this.highlightAll.checked,
       findPrevious: findPrev
     });
   }
-  updateUIState(state, previous, matchCount) {
+  updateUIState(state, previous, matchesCount) {
     let notFound = false;
     let findMsg = '';
     let status = '';
     switch (state) {
       case _pdf_find_controller.FindState.FOUND:
         break;
       case _pdf_find_controller.FindState.PENDING:
         status = 'pending';
@@ -4114,30 +4089,38 @@ class PDFFindBar {
     } else {
       this.findField.classList.remove('notFound');
     }
     this.findField.setAttribute('data-status', status);
     Promise.resolve(findMsg).then(msg => {
       this.findMsg.textContent = msg;
       this._adjustWidth();
     });
-    this.updateResultsCount(matchCount);
-  }
-  updateResultsCount(matchCount) {
+    this.updateResultsCount(matchesCount);
+  }
+  updateResultsCount({ current = 0, total = 0 } = {}) {
     if (!this.findResultsCount) {
       return;
     }
-    if (!matchCount) {
-      this.findResultsCount.classList.add('hidden');
-      this.findResultsCount.textContent = '';
-    } else {
-      this.findResultsCount.textContent = matchCount.toLocaleString();
-      this.findResultsCount.classList.remove('hidden');
-    }
-    this._adjustWidth();
+    let matchesCountMsg = '';
+    if (total) {
+      if (total > MATCHES_COUNT_LIMIT) {
+        matchesCountMsg = this.l10n.get('find_matches_count_limit', { limit: MATCHES_COUNT_LIMIT.toLocaleString() }, 'More than {{limit}} matches');
+      } else {
+        matchesCountMsg = this.l10n.get('find_matches_count', {
+          current: current.toLocaleString(),
+          total: total.toLocaleString()
+        }, '{{current}} of {{total}} matches');
+      }
+    }
+    Promise.resolve(matchesCountMsg).then(msg => {
+      this.findResultsCount.textContent = msg;
+      this.findResultsCount.classList[!total ? 'add' : 'remove']('hidden');
+      this._adjustWidth();
+    });
   }
   open() {
     if (!this.opened) {
       this.opened = true;
       this.toggleButton.classList.add('toggled');
       this.bar.classList.remove('hidden');
     }
     this.findField.select();
@@ -4183,16 +4166,18 @@ exports.PDFFindBar = PDFFindBar;
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.PDFFindController = exports.FindState = undefined;
 
 var _pdfjsLib = __webpack_require__(3);
 
+var _pdf_find_utils = __webpack_require__(17);
+
 var _dom_events = __webpack_require__(10);
 
 var _ui_utils = __webpack_require__(2);
 
 const FindState = {
   FOUND: 0,
   NOT_FOUND: 1,
   WRAPPED: 2,
@@ -4227,17 +4212,17 @@ class PDFFindController {
   reset() {
     this.startedTextExtraction = false;
     this.extractTextPromises = [];
     this.pendingFindMatches = Object.create(null);
     this.active = false;
     this.pageContents = [];
     this.pageMatches = [];
     this.pageMatchesLength = null;
-    this.matchCount = 0;
+    this.matchesCountTotal = 0;
     this.selected = {
       pageIdx: -1,
       matchIdx: -1
     };
     this.offset = {
       pageIdx: null,
       matchIdx: null
     };
@@ -4313,41 +4298,65 @@ class PDFFindController {
     for (let i = 0, len = matchesWithLength.length; i < len; i++) {
       if (isSubTerm(matchesWithLength, i)) {
         continue;
       }
       matches.push(matchesWithLength[i].match);
       matchesLength.push(matchesWithLength[i].matchLength);
     }
   }
-  _calculatePhraseMatch(query, pageIndex, pageContent) {
+  _isEntireWord(content, startIdx, length) {
+    if (startIdx > 0) {
+      const first = content.charCodeAt(startIdx);
+      const limit = content.charCodeAt(startIdx - 1);
+      if ((0, _pdf_find_utils.getCharacterType)(first) === (0, _pdf_find_utils.getCharacterType)(limit)) {
+        return false;
+      }
+    }
+    const endIdx = startIdx + length - 1;
+    if (endIdx < content.length - 1) {
+      const last = content.charCodeAt(endIdx);
+      const limit = content.charCodeAt(endIdx + 1);
+      if ((0, _pdf_find_utils.getCharacterType)(last) === (0, _pdf_find_utils.getCharacterType)(limit)) {
+        return false;
+      }
+    }
+    return true;
+  }
+  _calculatePhraseMatch(query, pageIndex, pageContent, entireWord) {
     let matches = [];
     let queryLen = query.length;
     let matchIdx = -queryLen;
     while (true) {
       matchIdx = pageContent.indexOf(query, matchIdx + queryLen);
       if (matchIdx === -1) {
         break;
       }
+      if (entireWord && !this._isEntireWord(pageContent, matchIdx, queryLen)) {
+        continue;
+      }
       matches.push(matchIdx);
     }
     this.pageMatches[pageIndex] = matches;
   }
-  _calculateWordMatch(query, pageIndex, pageContent) {
+  _calculateWordMatch(query, pageIndex, pageContent, entireWord) {
     let matchesWithLength = [];
     let queryArray = query.match(/\S+/g);
     for (let i = 0, len = queryArray.length; i < len; i++) {
       let subquery = queryArray[i];
       let subqueryLen = subquery.length;
       let matchIdx = -subqueryLen;
       while (true) {
         matchIdx = pageContent.indexOf(subquery, matchIdx + subqueryLen);
         if (matchIdx === -1) {
           break;
         }
+        if (entireWord && !this._isEntireWord(pageContent, matchIdx, subqueryLen)) {
+          continue;
+        }
         matchesWithLength.push({
           match: matchIdx,
           matchLength: subqueryLen,
           skipped: false
         });
       }
     }
     if (!this.pageMatchesLength) {
@@ -4357,36 +4366,38 @@ class PDFFindController {
     this.pageMatches[pageIndex] = [];
     this._prepareMatches(matchesWithLength, this.pageMatches[pageIndex], this.pageMatchesLength[pageIndex]);
   }
   _calculateMatch(pageIndex) {
     let pageContent = this._normalize(this.pageContents[pageIndex]);
     let query = this._normalize(this.state.query);
     let caseSensitive = this.state.caseSensitive;
     let phraseSearch = this.state.phraseSearch;
+    const entireWord = this.state.entireWord;
     let queryLen = query.length;
     if (queryLen === 0) {
       return;
     }
     if (!caseSensitive) {
       pageContent = pageContent.toLowerCase();
       query = query.toLowerCase();
     }
     if (phraseSearch) {
-      this._calculatePhraseMatch(query, pageIndex, pageContent);
+      this._calculatePhraseMatch(query, pageIndex, pageContent, entireWord);
     } else {
-      this._calculateWordMatch(query, pageIndex, pageContent);
+      this._calculateWordMatch(query, pageIndex, pageContent, entireWord);
     }
     this._updatePage(pageIndex);
     if (this.resumePageIdx === pageIndex) {
       this.resumePageIdx = null;
       this._nextPageMatch();
     }
-    if (this.pageMatches[pageIndex].length > 0) {
-      this.matchCount += this.pageMatches[pageIndex].length;
+    const pageMatchesCount = this.pageMatches[pageIndex].length;
+    if (pageMatchesCount > 0) {
+      this.matchesCountTotal += pageMatchesCount;
       this._updateUIResultsCount();
     }
   }
   _extractText() {
     if (this.startedTextExtraction) {
       return;
     }
     this.startedTextExtraction = true;
@@ -4429,17 +4440,17 @@ class PDFFindController {
     if (this.dirtyMatch) {
       this.dirtyMatch = false;
       this.selected.pageIdx = this.selected.matchIdx = -1;
       this.offset.pageIdx = currentPageIndex;
       this.offset.matchIdx = null;
       this.hadMatch = false;
       this.resumePageIdx = null;
       this.pageMatches = [];
-      this.matchCount = 0;
+      this.matchesCountTotal = 0;
       this.pageMatchesLength = null;
       for (let i = 0; i < numPages; i++) {
         this._updatePage(i);
         if (!(i in this.pendingFindMatches)) {
           this.pendingFindMatches[i] = true;
           this.extractTextPromises[i].then(pageIdx => {
             delete this.pendingFindMatches[pageIdx];
             this._calculateMatch(pageIdx);
@@ -4526,40 +4537,138 @@ class PDFFindController {
         this._updatePage(previousPage);
       }
     }
     this._updateUIState(state, this.state.findPrevious);
     if (this.selected.pageIdx !== -1) {
       this._updatePage(this.selected.pageIdx);
     }
   }
+  _requestMatchesCount() {
+    const { pageIdx, matchIdx } = this.selected;
+    let current = 0;
+    if (matchIdx !== -1) {
+      for (let i = 0; i < pageIdx; i++) {
+        current += this.pageMatches[i] && this.pageMatches[i].length || 0;
+      }
+      current += matchIdx + 1;
+    }
+    return {
+      current,
+      total: this.matchesCountTotal
+    };
+  }
   _updateUIResultsCount() {
-    if (this.onUpdateResultsCount) {
-      this.onUpdateResultsCount(this.matchCount);
-    }
+    if (!this.onUpdateResultsCount) {
+      return;
+    }
+    const matchesCount = this._requestMatchesCount();
+    this.onUpdateResultsCount(matchesCount);
   }
   _updateUIState(state, previous) {
-    if (this.onUpdateState) {
-      this.onUpdateState(state, previous, this.matchCount);
-    }
+    if (!this.onUpdateState) {
+      return;
+    }
+    const matchesCount = this._requestMatchesCount();
+    this.onUpdateState(state, previous, matchesCount);
   }
 }
 exports.FindState = FindState;
 exports.PDFFindController = PDFFindController;
 
 /***/ }),
 /* 17 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+const CharacterType = {
+  SPACE: 0,
+  ALPHA_LETTER: 1,
+  PUNCT: 2,
+  HAN_LETTER: 3,
+  KATAKANA_LETTER: 4,
+  HIRAGANA_LETTER: 5,
+  HALFWIDTH_KATAKANA_LETTER: 6,
+  THAI_LETTER: 7
+};
+function isAlphabeticalScript(charCode) {
+  return charCode < 0x2E80;
+}
+function isAscii(charCode) {
+  return (charCode & 0xFF80) === 0;
+}
+function isAsciiAlpha(charCode) {
+  return charCode >= 0x61 && charCode <= 0x7A || charCode >= 0x41 && charCode <= 0x5A;
+}
+function isAsciiDigit(charCode) {
+  return charCode >= 0x30 && charCode <= 0x39;
+}
+function isAsciiSpace(charCode) {
+  return charCode === 0x20 || charCode === 0x09 || charCode === 0x0D || charCode === 0x0A;
+}
+function isHan(charCode) {
+  return charCode >= 0x3400 && charCode <= 0x9FFF || charCode >= 0xF900 && charCode <= 0xFAFF;
+}
+function isKatakana(charCode) {
+  return charCode >= 0x30A0 && charCode <= 0x30FF;
+}
+function isHiragana(charCode) {
+  return charCode >= 0x3040 && charCode <= 0x309F;
+}
+function isHalfwidthKatakana(charCode) {
+  return charCode >= 0xFF60 && charCode <= 0xFF9F;
+}
+function isThai(charCode) {
+  return (charCode & 0xFF80) === 0x0E00;
+}
+function getCharacterType(charCode) {
+  if (isAlphabeticalScript(charCode)) {
+    if (isAscii(charCode)) {
+      if (isAsciiSpace(charCode)) {
+        return CharacterType.SPACE;
+      } else if (isAsciiAlpha(charCode) || isAsciiDigit(charCode) || charCode === 0x5F) {
+        return CharacterType.ALPHA_LETTER;
+      }
+      return CharacterType.PUNCT;
+    } else if (isThai(charCode)) {
+      return CharacterType.THAI_LETTER;
+    } else if (charCode === 0xA0) {
+      return CharacterType.SPACE;
+    }
+    return CharacterType.ALPHA_LETTER;
+  }
+  if (isHan(charCode)) {
+    return CharacterType.HAN_LETTER;
+  } else if (isKatakana(charCode)) {
+    return CharacterType.KATAKANA_LETTER;
+  } else if (isHiragana(charCode)) {
+    return CharacterType.HIRAGANA_LETTER;
+  } else if (isHalfwidthKatakana(charCode)) {
+    return CharacterType.HALFWIDTH_KATAKANA_LETTER;
+  }
+  return CharacterType.ALPHA_LETTER;
+}
+exports.CharacterType = CharacterType;
+exports.getCharacterType = getCharacterType;
+
+/***/ }),
+/* 18 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
 exports.isDestArraysEqual = exports.isDestHashesEqual = exports.PDFHistory = undefined;
 
 var _ui_utils = __webpack_require__(2);
 
 var _dom_events = __webpack_require__(10);
 
 const HASH_CHANGE_TIMEOUT = 1000;
 const POSITION_UPDATED_THRESHOLD = 50;
@@ -4918,17 +5027,17 @@ function isDestArraysEqual(firstDest, se
   }
   return true;
 }
 exports.PDFHistory = PDFHistory;
 exports.isDestHashesEqual = isDestHashesEqual;
 exports.isDestArraysEqual = isDestArraysEqual;
 
 /***/ }),
-/* 18 */
+/* 19 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -5252,17 +5361,17 @@ class SimpleLinkService {
   executeNamedAction(action) {}
   onFileAttachmentAnnotation({ id, filename, content }) {}
   cachePageRef(pageNum, pageRef) {}
 }
 exports.PDFLinkService = PDFLinkService;
 exports.SimpleLinkService = SimpleLinkService;
 
 /***/ }),
-/* 19 */
+/* 20 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -5393,17 +5502,17 @@ class PDFOutlineViewer {
     }
     this.container.appendChild(fragment);
     this._dispatchEvent(outlineCount);
   }
 }
 exports.PDFOutlineViewer = PDFOutlineViewer;
 
 /***/ }),
-/* 20 */
+/* 21 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -5710,17 +5819,17 @@ class PDFPresentationMode {
     window.removeEventListener('fullscreenchange', this.fullscreenChangeBind);
     window.removeEventListener('mozfullscreenchange', this.fullscreenChangeBind);
     delete this.fullscreenChangeBind;
   }
 }
 exports.PDFPresentationMode = PDFPresentationMode;
 
 /***/ }),
-/* 21 */
+/* 22 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -5830,30 +5939,30 @@ class PDFSidebarResizer {
         }
       }
     });
   }
 }
 exports.PDFSidebarResizer = PDFSidebarResizer;
 
 /***/ }),
-/* 22 */
+/* 23 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.PDFThumbnailViewer = undefined;
 
 var _ui_utils = __webpack_require__(2);
 
-var _pdf_thumbnail_view = __webpack_require__(23);
+var _pdf_thumbnail_view = __webpack_require__(24);
 
 const THUMBNAIL_SCROLL_MARGIN = -19;
 const THUMBNAIL_SELECTED_CLASS = 'selected';
 class PDFThumbnailViewer {
   constructor({ container, linkService, renderingQueue, l10n = _ui_utils.NullL10n }) {
     this.container = container;
     this.linkService = linkService;
     this.renderingQueue = renderingQueue;
@@ -6019,17 +6128,17 @@ class PDFThumbnailViewer {
       return true;
     }
     return false;
   }
 }
 exports.PDFThumbnailViewer = PDFThumbnailViewer;
 
 /***/ }),
-/* 23 */
+/* 24 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -6327,28 +6436,28 @@ class PDFThumbnailView {
   }
   static cleanup() {
     TempImageFactory.destroyCanvas();
   }
 }
 exports.PDFThumbnailView = PDFThumbnailView;
 
 /***/ }),
-/* 24 */
+/* 25 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.PDFViewer = undefined;
 
-var _base_viewer = __webpack_require__(25);
+var _base_viewer = __webpack_require__(26);
 
 var _ui_utils = __webpack_require__(2);
 
 var _pdfjsLib = __webpack_require__(3);
 
 class PDFViewer extends _base_viewer.BaseViewer {
   get _setDocumentViewerElement() {
     return (0, _pdfjsLib.shadow)(this, '_setDocumentViewerElement', this.viewer);
@@ -6417,42 +6526,42 @@ class PDFViewer extends _base_viewer.Bas
   }
   get _isScrollModeHorizontal() {
     return this.isInPresentationMode ? false : this._scrollMode === _base_viewer.ScrollMode.HORIZONTAL;
   }
 }
 exports.PDFViewer = PDFViewer;
 
 /***/ }),
-/* 25 */
+/* 26 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.SpreadMode = exports.ScrollMode = exports.BaseViewer = undefined;
 
 var _ui_utils = __webpack_require__(2);
 
 var _pdf_rendering_queue = __webpack_require__(6);
 
-var _annotation_layer_builder = __webpack_require__(26);
+var _annotation_layer_builder = __webpack_require__(27);
 
 var _pdfjsLib = __webpack_require__(3);
 
 var _dom_events = __webpack_require__(10);
 
-var _pdf_page_view = __webpack_require__(27);
-
-var _pdf_link_service = __webpack_require__(18);
-
-var _text_layer_builder = __webpack_require__(28);
+var _pdf_page_view = __webpack_require__(28);
+
+var _pdf_link_service = __webpack_require__(19);
+
+var _text_layer_builder = __webpack_require__(29);
 
 const DEFAULT_CACHE_SIZE = 10;
 const ScrollMode = {
   VERTICAL: 0,
   HORIZONTAL: 1,
   WRAPPED: 2
 };
 const SpreadMode = {
@@ -7225,32 +7334,32 @@ class BaseViewer {
     this.update();
   }
 }
 exports.BaseViewer = BaseViewer;
 exports.ScrollMode = ScrollMode;
 exports.SpreadMode = SpreadMode;
 
 /***/ }),
-/* 26 */
+/* 27 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.DefaultAnnotationLayerFactory = exports.AnnotationLayerBuilder = undefined;
 
 var _pdfjsLib = __webpack_require__(3);
 
 var _ui_utils = __webpack_require__(2);
 
-var _pdf_link_service = __webpack_require__(18);
+var _pdf_link_service = __webpack_require__(19);
 
 class AnnotationLayerBuilder {
   constructor({ pageDiv, pdfPage, linkService, downloadManager, imageResourcesPath = '', renderInteractiveForms = false, l10n = _ui_utils.NullL10n }) {
     this.pageDiv = pageDiv;
     this.pdfPage = pdfPage;
     this.linkService = linkService;
     this.downloadManager = downloadManager;
     this.imageResourcesPath = imageResourcesPath;
@@ -7310,17 +7419,17 @@ class DefaultAnnotationLayerFactory {
       l10n
     });
   }
 }
 exports.AnnotationLayerBuilder = AnnotationLayerBuilder;
 exports.DefaultAnnotationLayerFactory = DefaultAnnotationLayerFactory;
 
 /***/ }),
-/* 27 */
+/* 28 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -7767,17 +7876,17 @@ class PDFPageView {
     } else {
       this.div.removeAttribute('data-page-label');
     }
   }
 }
 exports.PDFPageView = PDFPageView;
 
 /***/ }),
-/* 28 */
+/* 29 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -8036,32 +8145,32 @@ class DefaultTextLayerFactory {
       enhanceTextSelection
     });
   }
 }
 exports.TextLayerBuilder = TextLayerBuilder;
 exports.DefaultTextLayerFactory = DefaultTextLayerFactory;
 
 /***/ }),
-/* 29 */
+/* 30 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.SecondaryToolbar = undefined;
 
-var _base_viewer = __webpack_require__(25);
+var _base_viewer = __webpack_require__(26);
 
 var _pdf_cursor_tools = __webpack_require__(4);
 
-var _pdf_single_page_viewer = __webpack_require__(30);
+var _pdf_single_page_viewer = __webpack_require__(31);
 
 var _ui_utils = __webpack_require__(2);
 
 class SecondaryToolbar {
   constructor(options, mainContainer, eventBus) {
     this.toolbar = options.toolbar;
     this.toggleButton = options.toggleButton;
     this.toolbarButtonContainer = options.toolbarButtonContainer;
@@ -8314,28 +8423,28 @@ class SecondaryToolbar {
     }
     this.toolbarButtonContainer.setAttribute('style', 'max-height: ' + (this.containerHeight - _ui_utils.SCROLLBAR_PADDING) + 'px;');
     this.previousContainerHeight = this.containerHeight;
   }
 }
 exports.SecondaryToolbar = SecondaryToolbar;
 
 /***/ }),
-/* 30 */
+/* 31 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.PDFSinglePageViewer = undefined;
 
-var _base_viewer = __webpack_require__(25);
+var _base_viewer = __webpack_require__(26);
 
 var _ui_utils = __webpack_require__(2);
 
 var _pdfjsLib = __webpack_require__(3);
 
 class PDFSinglePageViewer extends _base_viewer.BaseViewer {
   constructor(options) {
     super(options);
@@ -8439,17 +8548,17 @@ class PDFSinglePageViewer extends _base_
     return (0, _pdfjsLib.shadow)(this, '_isScrollModeHorizontal', false);
   }
   _updateScrollMode() {}
   _updateSpreadMode() {}
 }
 exports.PDFSinglePageViewer = PDFSinglePageViewer;
 
 /***/ }),
-/* 31 */
+/* 32 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -8624,17 +8733,17 @@ class Toolbar {
         container.setAttribute('style', 'min-width: ' + width + 'px; ' + 'max-width: ' + width + 'px;');
       }
     });
   }
 }
 exports.Toolbar = Toolbar;
 
 /***/ }),
-/* 32 */
+/* 33 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -8662,78 +8771,69 @@ class ViewHistory {
       }
       if (index === -1) {
         index = database.files.push({ fingerprint: this.fingerprint }) - 1;
       }
       this.file = database.files[index];
       this.database = database;
     });
   }
-  _writeToStorage() {
-    return new Promise(resolve => {
-      let databaseStr = JSON.stringify(this.database);
-      sessionStorage.setItem('pdfjs.history', databaseStr);
-      resolve();
-    });
-  }
-  _readFromStorage() {
-    return new Promise(function (resolve) {
-      resolve(sessionStorage.getItem('pdfjs.history'));
-    });
-  }
-  set(name, val) {
-    return this._initializedPromise.then(() => {
-      this.file[name] = val;
-      return this._writeToStorage();
-    });
-  }
-  setMultiple(properties) {
-    return this._initializedPromise.then(() => {
-      for (let name in properties) {
-        this.file[name] = properties[name];
-      }
-      return this._writeToStorage();
-    });
-  }
-  get(name, defaultValue) {
-    return this._initializedPromise.then(() => {
+  async _writeToStorage() {
+    let databaseStr = JSON.stringify(this.database);
+    sessionStorage.setItem('pdfjs.history', databaseStr);
+  }
+  async _readFromStorage() {
+    return sessionStorage.getItem('pdfjs.history');
+  }
+  async set(name, val) {
+    await this._initializedPromise;
+    this.file[name] = val;
+    return this._writeToStorage();
+  }
+  async setMultiple(properties) {
+    await this._initializedPromise;
+    for (let name in properties) {
+      this.file[name] = properties[name];
+    }
+    return this._writeToStorage();
+  }
+  async get(name, defaultValue) {
+    await this._initializedPromise;
+    let val = this.file[name];
+    return val !== undefined ? val : defaultValue;
+  }
+  async getMultiple(properties) {
+    await this._initializedPromise;
+    let values = Object.create(null);
+    for (let name in properties) {
       let val = this.file[name];
-      return val !== undefined ? val : defaultValue;
-    });
-  }
-  getMultiple(properties) {
-    return this._initializedPromise.then(() => {
-      let values = Object.create(null);
-      for (let name in properties) {
-        let val = this.file[name];
-        values[name] = val !== undefined ? val : properties[name];
-      }
-      return values;
-    });
+      values[name] = val !== undefined ? val : properties[name];
+    }
+    return values;
   }
 }
 exports.ViewHistory = ViewHistory;
 
 /***/ }),
-/* 33 */
+/* 34 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.FirefoxCom = exports.DownloadManager = undefined;
 
-__webpack_require__(34);
+__webpack_require__(35);
 
 var _pdfjsLib = __webpack_require__(3);
 
-var _preferences = __webpack_require__(35);
+var _preferences = __webpack_require__(36);
 
 var _app = __webpack_require__(1);
 
 ;
 let FirefoxCom = function FirefoxComClosure() {
   return {
     requestSync(action, data) {
       let request = document.createTextNode('');
@@ -8802,66 +8902,66 @@ class DownloadManager {
     FirefoxCom.request('download', {
       blobUrl,
       originalUrl: url,
       filename
     }, onResponse);
   }
 }
 class FirefoxPreferences extends _preferences.BasePreferences {
-  _writeToStorage(prefObj) {
+  async _writeToStorage(prefObj) {
     return new Promise(function (resolve) {
       FirefoxCom.request('setPreferences', prefObj, resolve);
     });
   }
-  _readFromStorage(prefObj) {
+  async _readFromStorage(prefObj) {
     return new Promise(function (resolve) {
       FirefoxCom.request('getPreferences', prefObj, function (prefStr) {
         let readPrefs = JSON.parse(prefStr);
         resolve(readPrefs);
       });
     });
   }
 }
 class MozL10n {
   constructor(mozL10n) {
     this.mozL10n = mozL10n;
   }
-  getLanguage() {
-    return Promise.resolve(this.mozL10n.getLanguage());
-  }
-  getDirection() {
-    return Promise.resolve(this.mozL10n.getDirection());
-  }
-  get(property, args, fallback) {
-    return Promise.resolve(this.mozL10n.get(property, args, fallback));
-  }
-  translate(element) {
+  async getLanguage() {
+    return this.mozL10n.getLanguage();
+  }
+  async getDirection() {
+    return this.mozL10n.getDirection();
+  }
+  async get(property, args, fallback) {
+    return this.mozL10n.get(property, args, fallback);
+  }
+  async translate(element) {
     this.mozL10n.translate(element);
-    return Promise.resolve();
   }
 }
 (function listenFindEvents() {
-  const events = ['find', 'findagain', 'findhighlightallchange', 'findcasesensitivitychange'];
+  const events = ['find', 'findagain', 'findhighlightallchange', 'findcasesensitivitychange', 'findentirewordchange'];
   let handleEvent = function (evt) {
     if (!_app.PDFViewerApplication.initialized) {
       return;
     }
     _app.PDFViewerApplication.eventBus.dispatch('find', {
       source: window,
       type: evt.type.substring('find'.length),
       query: evt.detail.query,
       phraseSearch: true,
       caseSensitive: !!evt.detail.caseSensitive,
+      entireWord: !!evt.detail.entireWord,
       highlightAll: !!evt.detail.highlightAll,
       findPrevious: !!evt.detail.findPrevious
     });
   };
-  for (let i = 0, len = events.length; i < len; i++) {
-    window.addEventListener(events[i], handleEvent);
+  for (let event of events) {
+    window.addEventListener(event, handleEvent);
   }
 })();
 function FirefoxComDataRangeTransport(length, initialData) {
   _pdfjsLib.PDFDataRangeTransport.call(this, length, initialData);
 }
 FirefoxComDataRangeTransport.prototype = Object.create(_pdfjsLib.PDFDataRangeTransport.prototype);
 FirefoxComDataRangeTransport.prototype.requestDataRange = function FirefoxComDataRangeTransport_requestDataRange(begin, end) {
   FirefoxCom.request('requestDataRange', {
@@ -8871,16 +8971,17 @@ FirefoxComDataRangeTransport.prototype.r
 };
 FirefoxComDataRangeTransport.prototype.abort = function FirefoxComDataRangeTransport_abort() {
   FirefoxCom.requestSync('abortLoading', null);
 };
 _app.PDFViewerApplication.externalServices = {
   updateFindControlState(data) {
     FirefoxCom.request('updateFindControlState', data);
   },
+  updateFindMatchesCount(data) {},
   initPassiveLoading(callbacks) {
     let pdfDataRangeTransport;
     window.addEventListener('message', function windowMessage(e) {
       if (e.source !== null) {
         console.warn('Rejected untrusted message from ' + e.origin);
         return;
       }
       let args = e.data;
@@ -8955,17 +9056,17 @@ document.mozL10n.setExternalLocalizerSer
   getStrings(key) {
     return FirefoxCom.requestSync('getStrings', key);
   }
 });
 exports.DownloadManager = DownloadManager;
 exports.FirefoxCom = FirefoxCom;
 
 /***/ }),
-/* 34 */
+/* 35 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 (function (window) {
   var gLanguage = "";
   var gExternalLocalizerServices = null;
@@ -9053,17 +9154,17 @@ exports.FirefoxCom = FirefoxCom;
       gLanguage = gExternalLocalizerServices.getLocale();
       gReadyState = "complete";
     },
     translate: translateFragment
   };
 })(undefined);
 
 /***/ }),
-/* 35 */
+/* 36 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
@@ -9120,76 +9221,73 @@ class BasePreferences {
               prefValue = prefs[name];
         if (defaultValue === undefined || typeof prefValue !== typeof defaultValue) {
           continue;
         }
         this.prefs[name] = prefValue;
       }
     });
   }
-  _writeToStorage(prefObj) {
-    return Promise.reject(new Error('Not implemented: _writeToStorage'));
-  }
-  _readFromStorage(prefObj) {
-    return Promise.reject(new Error('Not implemented: _readFromStorage'));
-  }
-  reset() {
-    return this._initializedPromise.then(() => {
-      this.prefs = Object.assign(Object.create(null), this.defaults);
-      return this._writeToStorage(this.defaults);
-    });
-  }
-  set(name, value) {
-    return this._initializedPromise.then(() => {
-      if (this.defaults[name] === undefined) {
-        throw new Error(`Set preference: "${name}" is undefined.`);
-      } else if (value === undefined) {
-        throw new Error('Set preference: no value is specified.');
-      }
-      let valueType = typeof value;
-      let defaultType = typeof this.defaults[name];
-      if (valueType !== defaultType) {
-        if (valueType === 'number' && defaultType === 'string') {
-          value = value.toString();
-        } else {
-          throw new Error(`Set preference: "${value}" is a ${valueType}, ` + `expected a ${defaultType}.`);
-        }
+  async _writeToStorage(prefObj) {
+    throw new Error('Not implemented: _writeToStorage');
+  }
+  async _readFromStorage(prefObj) {
+    throw new Error('Not implemented: _readFromStorage');
+  }
+  async reset() {
+    await this._initializedPromise;
+    this.prefs = Object.assign(Object.create(null), this.defaults);
+    return this._writeToStorage(this.defaults);
+  }
+  async set(name, value) {
+    await this._initializedPromise;
+    let defaultValue = this.defaults[name];
+    if (defaultValue === undefined) {
+      throw new Error(`Set preference: "${name}" is undefined.`);
+    } else if (value === undefined) {
+      throw new Error('Set preference: no value is specified.');
+    }
+    let valueType = typeof value;
+    let defaultType = typeof defaultValue;
+    if (valueType !== defaultType) {
+      if (valueType === 'number' && defaultType === 'string') {
+        value = value.toString();
       } else {
-        if (valueType === 'number' && !Number.isInteger(value)) {
-          throw new Error(`Set preference: "${value}" must be an integer.`);
-        }
-      }
-      this.prefs[name] = value;
-      return this._writeToStorage(this.prefs);
-    });
-  }
-  get(name) {
-    return this._initializedPromise.then(() => {
-      let defaultValue = this.defaults[name];
-      if (defaultValue === undefined) {
-        throw new Error(`Get preference: "${name}" is undefined.`);
-      } else {
-        let prefValue = this.prefs[name];
-        if (prefValue !== undefined) {
-          return prefValue;
-        }
-      }
-      return defaultValue;
-    });
-  }
-  getAll() {
-    return this._initializedPromise.then(() => {
-      return Object.assign(Object.create(null), this.defaults, this.prefs);
-    });
+        throw new Error(`Set preference: "${value}" is a ${valueType}, ` + `expected a ${defaultType}.`);
+      }
+    } else {
+      if (valueType === 'number' && !Number.isInteger(value)) {
+        throw new Error(`Set preference: "${value}" must be an integer.`);
+      }
+    }
+    this.prefs[name] = value;
+    return this._writeToStorage(this.prefs);
+  }
+  async get(name) {
+    await this._initializedPromise;
+    let defaultValue = this.defaults[name];
+    if (defaultValue === undefined) {
+      throw new Error(`Get preference: "${name}" is undefined.`);
+    } else {
+      let prefValue = this.prefs[name];
+      if (prefValue !== undefined) {
+        return prefValue;
+      }
+    }
+    return defaultValue;
+  }
+  async getAll() {
+    await this._initializedPromise;
+    return Object.assign(Object.create(null), this.defaults, this.prefs);
   }
 }
 exports.BasePreferences = BasePreferences;
 
 /***/ }),
-/* 36 */
+/* 37 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
--- a/browser/extensions/pdfjs/moz.yaml
+++ b/browser/extensions/pdfjs/moz.yaml
@@ -15,15 +15,15 @@ origin:
   description: Portable Document Format (PDF) viewer that is built with HTML5
 
   # Full URL for the package's homepage/etc
   # Usually different from repository url
   url: https://github.com/mozilla/pdf.js
 
   # Human-readable identifier for this version/release
   # Generally "version NNN", "tag SSS", "bookmark SSS"
-  release: version 2.0.815
+  release: version 2.0.843
 
   # The package's license, where possible using the mnemonic from
   # https://spdx.org/licenses/
   # Multiple licenses can be specified (as a YAML list)
   # A "LICENSE" file must exist containing the full license text
   license: Apache-2.0
--- a/browser/locales/en-US/pdfviewer/viewer.properties
+++ b/browser/locales/en-US/pdfviewer/viewer.properties
@@ -160,18 +160,26 @@ thumb_page_canvas=Thumbnail of Page {{pa
 find_input.title=Find
 find_input.placeholder=Find in document…
 find_previous.title=Find the previous occurrence of the phrase
 find_previous_label=Previous
 find_next.title=Find the next occurrence of the phrase
 find_next_label=Next
 find_highlight=Highlight all
 find_match_case_label=Match case
+find_entire_word_label=Whole words
 find_reached_top=Reached top of document, continued from bottom
 find_reached_bottom=Reached end of document, continued from top
+# LOCALIZATION NOTE (find_matches_count): "{{current}}" and "{{total}}" will be
+# replaced by a number representing the index of the currently active find result,
+# respectively a number representing the total number of matches in the document.
+find_matches_count={{current}} of {{total}} matches
+# LOCALIZATION NOTE (find_matches_count_limit): "{{limit}}" will be replaced by
+# a numerical value.
+find_matches_count_limit=More than {{limit}} matches
 find_not_found=Phrase not found
 
 # Error panel labels
 error_more_info=More Information
 error_less_info=Less Information
 error_close=Close
 # LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be
 # replaced by the PDF.JS version and build ID.