Merge m-c to graphics
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 02 May 2017 09:45:11 -0400
changeset 357024 7e836ca5016ae4b4120a376c3cc427d91c88e7c1
parent 357023 ae9f92d425425e98d585b4c905a351da04ed2543 (current diff)
parent 355970 48c0fd9c9ec5d68061ea7b59358874ae8da72572 (diff)
child 357025 1ba304cfe3908fcf53109d2e8435532448887c78
push id31780
push userkwierso@gmail.com
push dateMon, 08 May 2017 20:34:47 +0000
treeherdermozilla-central@bab7046ee2d8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to graphics MozReview-Commit-ID: 9XwZUWIhGir
config/tests/makefiles/autodeps/check_mkdir.py
config/tests/makefiles/autodeps/testor.tmpl
devtools/client/themes/commandline.inc.css
devtools/client/themes/responsivedesign.inc.css
gfx/layers/Layers.h
gfx/layers/moz.build
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/painting/nsDisplayList.cpp
parser/html/javasrc/HtmlAttributes.java
parser/html/nsHtml5ReleasableAttributeName.cpp
parser/html/nsHtml5ReleasableAttributeName.h
tools/profiler/core/ProfilerMarkers.cpp
tools/profiler/public/ProfilerMarkers.h
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -1137,19 +1137,18 @@ nsAccessibilityService::CreateAccessible
     // XBL bindings may use @role attribute to point the accessible type
     // they belong to.
     newAcc = CreateAccessibleByType(content, document);
 
     // Any XUL box can be used as tabpanel, make sure we create a proper
     // accessible for it.
     if (!newAcc && aContext->IsXULTabpanels() &&
         content->GetParent() == aContext->GetContent()) {
-      nsIAtom* frameType = frame->GetType();
-      if (frameType == nsGkAtoms::boxFrame ||
-          frameType == nsGkAtoms::scrollFrame) {
+      FrameType frameType = frame->Type();
+      if (frameType == FrameType::Box || frameType == FrameType::Scroll) {
         newAcc = new XULTabpanelAccessible(content, document);
       }
     }
   }
 
   if (!newAcc) {
     if (content->IsSVGElement()) {
       SVGGeometryFrame* geometryFrame = do_QueryFrame(frame);
@@ -1610,22 +1609,22 @@ nsAccessibilityService::CreateAccessible
       // accessible HTML table or a direct child of accessible of HTML table.
       Accessible* table = aContext->IsTable() ? aContext : nullptr;
       if (!table && aContext->Parent() && aContext->Parent()->IsTable())
         table = aContext->Parent();
 
       if (table) {
         nsIContent* parentContent = aContent->GetParent();
         nsIFrame* parentFrame = parentContent->GetPrimaryFrame();
-        if (parentFrame->GetType() != nsGkAtoms::tableWrapperFrame) {
+        if (!parentFrame->IsTableWrapperFrame()) {
           parentContent = parentContent->GetParent();
           parentFrame = parentContent->GetPrimaryFrame();
         }
 
-        if (parentFrame->GetType() == nsGkAtoms::tableWrapperFrame &&
+        if (parentFrame->IsTableWrapperFrame() &&
             table->GetContent() == parentContent) {
           newAcc = new HTMLTableRowAccessible(aContent, document);
         }
       }
       break;
     }
     case eHTMLTextFieldType:
       newAcc = new HTMLTextFieldAccessible(aContent, document);
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -380,17 +380,17 @@ Accessible::VisibilityState()
     curFrame = parentFrame;
   } while (curFrame);
 
   // Zero area rects can occur in the first frame of a multi-frame text flow,
   // in which case the rendered text is not empty and the frame should not be
   // marked invisible.
   // XXX Can we just remove this check? Why do we need to mark empty
   // text invisible?
-  if (frame->GetType() == nsGkAtoms::textFrame &&
+  if (frame->IsTextFrame() &&
       !(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
       frame->GetRect().IsEmpty()) {
     nsIFrame::RenderedText text = frame->GetRenderedText(0,
         UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
         nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
     if (text.mString.IsEmpty()) {
       return states::INVISIBLE;
     }
@@ -631,17 +631,18 @@ Accessible::RelativeBounds(nsIFrame** aB
   if (frame && mContent) {
     bool* hasHitRegionRect = static_cast<bool*>(mContent->GetProperty(nsGkAtoms::hitregion));
 
     if (hasHitRegionRect && mContent->IsElement()) {
       // This is for canvas fallback content
       // Find a canvas frame the found hit region is relative to.
       nsIFrame* canvasFrame = frame->GetParent();
       if (canvasFrame) {
-        canvasFrame = nsLayoutUtils::GetClosestFrameOfType(canvasFrame, nsGkAtoms::HTMLCanvasFrame);
+        canvasFrame = nsLayoutUtils::GetClosestFrameOfType(
+          canvasFrame, FrameType::HTMLCanvas);
       }
 
       // make the canvas the bounding frame
       if (canvasFrame) {
         *aBoundingFrame = canvasFrame;
         dom::HTMLCanvasElement *canvas =
           dom::HTMLCanvasElement::FromContent(canvasFrame->GetContent());
 
@@ -1883,17 +1884,17 @@ Accessible::AppendTextTo(nsAString& aTex
 
   nsIFrame *frame = GetFrame();
   if (!frame)
     return;
 
   NS_ASSERTION(mParent,
                "Called on accessible unbound from tree. Result can be wrong.");
 
-  if (frame->GetType() == nsGkAtoms::brFrame) {
+  if (frame->IsBrFrame()) {
     aText += kForcedNewLineChar;
   } else if (mParent && nsAccUtils::MustPrune(mParent)) {
     // Expose the embedded object accessible as imaginary embedded object
     // character if its parent hypertext accessible doesn't expose children to
     // AT.
     aText += kImaginaryEmbeddedObjectChar;
   } else {
     aText += kEmbeddedObjectChar;
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1476,16 +1476,19 @@ DocAccessible::DoInitialUpdate()
 {
   if (nsCoreUtils::IsTabDocument(mDocumentNode)) {
     mDocFlags |= eTabDocument;
     if (IPCAccessibilityActive()) {
       nsIDocShell* docShell = mDocumentNode->GetDocShell();
       if (RefPtr<dom::TabChild> tabChild = dom::TabChild::GetFrom(docShell)) {
         DocAccessibleChild* ipcDoc = new DocAccessibleChild(this, tabChild);
         SetIPCDoc(ipcDoc);
+        if (IsRoot()) {
+          tabChild->SetTopLevelDocAccessibleChild(ipcDoc);
+        }
 
 #if defined(XP_WIN)
         IAccessibleHolder holder(CreateHolderFromAccessible(this));
         int32_t childID = AccessibleWrap::GetChildIDFor(this);
 #else
         int32_t holder = 0, childID = 0;
 #endif
         tabChild->SendPDocAccessibleConstructor(ipcDoc, nullptr, 0, childID,
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -60,17 +60,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAc
 role
 HyperTextAccessible::NativeRole()
 {
   a11y::role r = GetAccService()->MarkupRole(mContent);
   if (r != roles::NOTHING)
     return r;
 
   nsIFrame* frame = GetFrame();
-  if (frame && frame->GetType() == nsGkAtoms::inlineFrame)
+  if (frame && frame->IsInlineFrame())
     return roles::TEXT;
 
   return roles::TEXT_CONTAINER;
 }
 
 uint64_t
 HyperTextAccessible::NativeState()
 {
@@ -91,17 +91,17 @@ HyperTextAccessible::NativeState()
 }
 
 nsIntRect
 HyperTextAccessible::GetBoundsInFrame(nsIFrame* aFrame,
                                       uint32_t aStartRenderedOffset,
                                       uint32_t aEndRenderedOffset)
 {
   nsPresContext* presContext = mDoc->PresContext();
-  if (aFrame->GetType() != nsGkAtoms::textFrame) {
+  if (!aFrame->IsTextFrame()) {
     return aFrame->GetScreenRectInAppUnits().
       ToNearestPixels(presContext->AppUnitsPerDevPixel());
   }
 
   // Substring must be entirely within the same text node.
   int32_t startContentOffset, endContentOffset;
   nsresult rv = RenderedToContentOffset(aFrame, aStartRenderedOffset, &startContentOffset);
   NS_ENSURE_SUCCESS(rv, nsIntRect());
@@ -534,17 +534,17 @@ HyperTextAccessible::FindOffset(uint32_t
   nsIFrame* childFrame = child->GetFrame();
   if (!childFrame) {
     NS_ERROR("No child frame");
     return 0;
   }
 
   int32_t innerContentOffset = innerOffset;
   if (child->IsTextLeaf()) {
-    NS_ASSERTION(childFrame->GetType() == nsGkAtoms::textFrame, "Wrong frame!");
+    NS_ASSERTION(childFrame->IsTextFrame(), "Wrong frame!");
     RenderedToContentOffset(childFrame, innerOffset, &innerContentOffset);
   }
 
   nsIFrame* frameAtOffset = childFrame;
   int32_t unusedOffsetInFrame = 0;
   childFrame->GetChildFrameContainingOffset(innerContentOffset, true,
                                             &unusedOffsetInFrame,
                                             &frameAtOffset);
@@ -912,17 +912,17 @@ HyperTextAccessible::TextAttributes(bool
   int32_t offsetInAcc = offset - startOffset;
 
   TextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
                             accAtOffsetIdx);
   textAttrsMgr.GetAttributes(attributes, &startOffset, &endOffset);
 
   // Compute spelling attributes on text accessible only.
   nsIFrame *offsetFrame = accAtOffset->GetFrame();
-  if (offsetFrame && offsetFrame->GetType() == nsGkAtoms::textFrame) {
+  if (offsetFrame && offsetFrame->IsTextFrame()) {
     int32_t nodeOffset = 0;
     RenderedToContentOffset(offsetFrame, offsetInAcc, &nodeOffset);
 
     // Set 'misspelled' text attribute.
     GetSpellTextAttr(accAtOffset->GetNode(), nodeOffset,
                      &startOffset, &endOffset, attributes);
   }
 
@@ -1104,17 +1104,17 @@ already_AddRefed<nsIPersistentProperties
 HyperTextAccessible::NativeAttributes()
 {
   nsCOMPtr<nsIPersistentProperties> attributes =
     AccessibleWrap::NativeAttributes();
 
   // 'formatting' attribute is deprecated, 'display' attribute should be
   // instead.
   nsIFrame *frame = GetFrame();
-  if (frame && frame->GetType() == nsGkAtoms::blockFrame) {
+  if (frame && frame->IsBlockFrame()) {
     nsAutoString unused;
     attributes->SetStringProperty(NS_LITERAL_CSTRING("formatting"),
                                   NS_LITERAL_STRING("block"), unused);
   }
 
   if (FocusMgr()->IsFocused(this)) {
     int32_t lineNumber = CaretLineNumber();
     if (lineNumber >= 1) {
@@ -1218,17 +1218,17 @@ HyperTextAccessible::OffsetAtPoint(int32
     nsIFrame *frame = primaryFrame;
     while (frame) {
       nsIContent *content = frame->GetContent();
       NS_ENSURE_TRUE(content, -1);
       nsPoint pointInFrame = pointInHyperText - frame->GetOffsetTo(hyperFrame);
       nsSize frameSize = frame->GetSize();
       if (pointInFrame.x < frameSize.width && pointInFrame.y < frameSize.height) {
         // Finished
-        if (frame->GetType() == nsGkAtoms::textFrame) {
+        if (frame->IsTextFrame()) {
           nsIFrame::ContentOffsets contentOffsets =
             frame->GetContentOffsetsFromPointExternal(pointInFrame, nsIFrame::IGNORE_SELECTION_STYLE);
           if (contentOffsets.IsNull() || contentOffsets.content != content) {
             return -1; // Not found
           }
           uint32_t addToOffset;
           nsresult rv = ContentToRenderedOffset(primaryFrame,
                                                 contentOffsets.offset,
@@ -1966,18 +1966,17 @@ HyperTextAccessible::ContentToRenderedOf
     return NS_OK;
   }
 
   if (IsTextField()) {
     *aRenderedOffset = aContentOffset;
     return NS_OK;
   }
 
-  NS_ASSERTION(aFrame->GetType() == nsGkAtoms::textFrame,
-               "Need text frame for offset conversion");
+  NS_ASSERTION(aFrame->IsTextFrame(), "Need text frame for offset conversion");
   NS_ASSERTION(aFrame->GetPrevContinuation() == nullptr,
                "Call on primary frame only");
 
   nsIFrame::RenderedText text = aFrame->GetRenderedText(aContentOffset,
       aContentOffset + 1, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
       nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
   *aRenderedOffset = text.mOffsetWithinNodeRenderedText;
 
@@ -1991,18 +1990,17 @@ HyperTextAccessible::RenderedToContentOf
   if (IsTextField()) {
     *aContentOffset = aRenderedOffset;
     return NS_OK;
   }
 
   *aContentOffset = 0;
   NS_ENSURE_TRUE(aFrame, NS_ERROR_FAILURE);
 
-  NS_ASSERTION(aFrame->GetType() == nsGkAtoms::textFrame,
-               "Need text frame for offset conversion");
+  NS_ASSERTION(aFrame->IsTextFrame(), "Need text frame for offset conversion");
   NS_ASSERTION(aFrame->GetPrevContinuation() == nullptr,
                "Call on primary frame only");
 
   nsIFrame::RenderedText text = aFrame->GetRenderedText(aRenderedOffset,
       aRenderedOffset + 1, nsIFrame::TextOffsetType::OFFSETS_IN_RENDERED_TEXT,
       nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
   *aContentOffset = text.mOffsetWithinNodeText;
 
@@ -2095,17 +2093,17 @@ HyperTextAccessible::GetDOMPointByFrameO
     nsIContent* content = aAccessible->GetContent();
     NS_ASSERTION(content, "Shouldn't operate on defunct accessible!");
 
     nsIContent* parent = content->GetParent();
 
     aPoint->idx = parent->IndexOf(content) + 1;
     aPoint->node = parent;
 
-  } else if (aFrame->GetType() == nsGkAtoms::textFrame) {
+  } else if (aFrame->IsTextFrame()) {
     nsIContent* content = aFrame->GetContent();
     NS_ENSURE_STATE(content);
 
     nsIFrame *primaryFrame = content->GetPrimaryFrame();
     nsresult rv = RenderedToContentOffset(primaryFrame, aOffset, &(aPoint->idx));
     NS_ENSURE_SUCCESS(rv, rv);
 
     aPoint->node = content;
--- a/accessible/ipc/win/DocAccessibleChild.cpp
+++ b/accessible/ipc/win/DocAccessibleChild.cpp
@@ -97,28 +97,18 @@ DocAccessibleChild::PushDeferredEvent(Un
   if (mDoc && mDoc->IsRoot()) {
     topLevelIPCDoc = this;
   } else {
     auto tabChild = static_cast<dom::TabChild*>(Manager());
     if (!tabChild) {
       return;
     }
 
-    nsTArray<PDocAccessibleChild*> ipcDocAccs;
-    tabChild->ManagedPDocAccessibleChild(ipcDocAccs);
-
-    // Look for the top-level DocAccessibleChild - there will only be one
-    // per TabChild.
-    for (uint32_t i = 0, l = ipcDocAccs.Length(); i < l; ++i) {
-      auto ipcDocAcc = static_cast<DocAccessibleChild*>(ipcDocAccs[i]);
-      if (ipcDocAcc->mDoc && ipcDocAcc->mDoc->IsRoot()) {
-        topLevelIPCDoc = ipcDocAcc;
-        break;
-      }
-    }
+    topLevelIPCDoc =
+      static_cast<DocAccessibleChild*>(tabChild->GetTopLevelDocAccessibleChild());
   }
 
   if (topLevelIPCDoc) {
     topLevelIPCDoc->mDeferredEvents.AppendElement(Move(aEvent));
   }
 }
 
 bool
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3483,33 +3483,51 @@ function getPEMString(cert) {
   var wrapped = derb64.replace(/(\S{64}(?!$))/g, "$1\r\n");
   return "-----BEGIN CERTIFICATE-----\r\n"
          + wrapped
          + "\r\n-----END CERTIFICATE-----\r\n";
 }
 
 var PrintPreviewListener = {
   _printPreviewTab: null,
+  _simplifiedPrintPreviewTab: null,
   _tabBeforePrintPreview: null,
   _simplifyPageTab: null,
-
+  _lastRequestedPrintPreviewTab: null,
+
+  _createPPBrowser() {
+    if (!this._tabBeforePrintPreview) {
+      this._tabBeforePrintPreview = gBrowser.selectedTab;
+    }
+    let browser = this._tabBeforePrintPreview.linkedBrowser;
+    let preferredRemoteType = browser.remoteType;
+    return gBrowser.loadOneTab("about:printpreview", {
+      inBackground: true,
+      preferredRemoteType,
+      sameProcessAsFrameLoader: browser.frameLoader
+    });
+  },
   getPrintPreviewBrowser() {
     if (!this._printPreviewTab) {
-      let browser = gBrowser.selectedBrowser;
-      let preferredRemoteType = browser.remoteType;
-      this._tabBeforePrintPreview = gBrowser.selectedTab;
-      this._printPreviewTab = gBrowser.loadOneTab("about:printpreview", {
-        inBackground: false,
-        preferredRemoteType,
-        sameProcessAsFrameLoader: browser.frameLoader
-      });
-      gBrowser.selectedTab = this._printPreviewTab;
-    }
+      this._printPreviewTab = this._createPPBrowser();
+    }
+    gBrowser._allowTabChange = true;
+    this._lastRequestedPrintPreviewTab = gBrowser.selectedTab = this._printPreviewTab;
+    gBrowser._allowTabChange = false;
     return gBrowser.getBrowserForTab(this._printPreviewTab);
   },
+  getSimplifiedPrintPreviewBrowser() {
+    if (!this._simplifiedPrintPreviewTab) {
+      this._simplifiedPrintPreviewTab = this._createPPBrowser();
+    }
+    gBrowser._allowTabChange = true;
+    this._lastRequestedPrintPreviewTab = gBrowser.selectedTab = this._simplifiedPrintPreviewTab;
+    gBrowser._allowTabChange = false;
+    return gBrowser.getBrowserForTab(this._simplifiedPrintPreviewTab);
+  },
   createSimplifiedBrowser() {
     let browser = this._tabBeforePrintPreview.linkedBrowser;
     this._simplifyPageTab = gBrowser.loadOneTab("about:printpreview", {
       inBackground: true,
       sameProcessAsFrameLoader: browser.frameLoader
      });
     return this.getSimplifiedSourceBrowser();
   },
@@ -3522,34 +3540,36 @@ var PrintPreviewListener = {
       gBrowser.getBrowserForTab(this._simplifyPageTab) : null;
   },
   getNavToolbox() {
     return gNavToolbox;
   },
   onEnter() {
     // We might have accidentally switched tabs since the user invoked print
     // preview
-    if (gBrowser.selectedTab != this._printPreviewTab) {
-      gBrowser.selectedTab = this._printPreviewTab;
+    if (gBrowser.selectedTab != this._lastRequestedPrintPreviewTab) {
+      gBrowser.selectedTab = this._lastRequestedPrintPreviewTab;
     }
     gInPrintPreviewMode = true;
     this._toggleAffectedChrome();
   },
   onExit() {
     gBrowser.selectedTab = this._tabBeforePrintPreview;
     this._tabBeforePrintPreview = null;
     gInPrintPreviewMode = false;
     this._toggleAffectedChrome();
-    if (this._simplifyPageTab) {
-      gBrowser.removeTab(this._simplifyPageTab);
-      this._simplifyPageTab = null;
-    }
-    gBrowser.removeTab(this._printPreviewTab);
+    let tabsToRemove = ["_simplifyPageTab", "_printPreviewTab", "_simplifiedPrintPreviewTab"];
+    for (let tabProp of tabsToRemove) {
+      if (this[tabProp]) {
+        gBrowser.removeTab(this[tabProp]);
+        this[tabProp] = null;
+      }
+    }
     gBrowser.deactivatePrintPreviewBrowsers();
-    this._printPreviewTab = null;
+    this._lastRequestedPrintPreviewTab = null;
   },
   _toggleAffectedChrome() {
     gNavToolbox.collapsed = gInPrintPreviewMode;
 
     if (gInPrintPreviewMode)
       this._hideChrome();
     else
       this._showChrome();
@@ -4277,36 +4297,55 @@ function BrowserCustomizeToolbar() {
 function updateEditUIVisibility() {
   if (AppConstants.platform == "macosx")
     return;
 
   let editMenuPopupState = document.getElementById("menu_EditPopup").state;
   let contextMenuPopupState = document.getElementById("contentAreaContextMenu").state;
   let placesContextMenuPopupState = document.getElementById("placesContext").state;
 
+  let oldVisible = gEditUIVisible;
+
   // The UI is visible if the Edit menu is opening or open, if the context menu
   // is open, or if the toolbar has been customized to include the Cut, Copy,
   // or Paste toolbar buttons.
   gEditUIVisible = editMenuPopupState == "showing" ||
                    editMenuPopupState == "open" ||
                    contextMenuPopupState == "showing" ||
                    contextMenuPopupState == "open" ||
                    placesContextMenuPopupState == "showing" ||
-                   placesContextMenuPopupState == "open" ||
-                   document.getElementById("edit-controls") ? true : false;
+                   placesContextMenuPopupState == "open";
+  if (!gEditUIVisible) {
+    // Now check the edit-controls toolbar buttons.
+    let placement = CustomizableUI.getPlacementOfWidget("edit-controls");
+    let areaType = placement ? CustomizableUI.getAreaType(placement.area) : "";
+    if (areaType == CustomizableUI.TYPE_MENU_PANEL) {
+      let panelUIMenuPopupState = document.getElementById("PanelUI-popup").state;
+      if (panelUIMenuPopupState == "showing" || panelUIMenuPopupState == "open") {
+        gEditUIVisible = true;
+      }
+    } else if (areaType == CustomizableUI.TYPE_TOOLBAR) {
+      // The edit controls are on a toolbar, so they are visible.
+      gEditUIVisible = true;
+    }
+  }
+
+  // No need to update commands if the edit UI visibility has not changed.
+  if (gEditUIVisible == oldVisible) {
+    return;
+  }
 
   // If UI is visible, update the edit commands' enabled state to reflect
   // whether or not they are actually enabled for the current focus/selection.
-  if (gEditUIVisible)
+  if (gEditUIVisible) {
     goUpdateGlobalEditMenuItems();
-
-  // Otherwise, enable all commands, so that keyboard shortcuts still work,
-  // then lazily determine their actual enabled state when the user presses
-  // a keyboard shortcut.
-  else {
+  } else {
+    // Otherwise, enable all commands, so that keyboard shortcuts still work,
+    // then lazily determine their actual enabled state when the user presses
+    // a keyboard shortcut.
     goSetCommandEnabled("cmd_undo", true);
     goSetCommandEnabled("cmd_redo", true);
     goSetCommandEnabled("cmd_cut", true);
     goSetCommandEnabled("cmd_copy", true);
     goSetCommandEnabled("cmd_paste", true);
     goSetCommandEnabled("cmd_selectAll", true);
     goSetCommandEnabled("cmd_delete", true);
     goSetCommandEnabled("cmd_switchTextDirection", true);
@@ -6424,16 +6463,21 @@ function CanCloseWindow() {
   // PermitUnload dialogs.
   if (Services.startup.shuttingDown || window.skipNextCanClose) {
     return true;
   }
 
   let timedOutProcesses = new WeakSet();
 
   for (let browser of gBrowser.browsers) {
+    // Don't instantiate lazy browsers.
+    if (!browser.isConnected) {
+      continue;
+    }
+
     let pmm = browser.messageManager.processMessageManager;
 
     if (timedOutProcesses.has(pmm)) {
       continue;
     }
 
     let {permitUnload, timedOut} = browser.permitUnload();
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -4,17 +4,16 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 <?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/content/places/places.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/content/usercontext/usercontext.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/devtools-browser.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/controlcenter/panel.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/customizableui/panelUI.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
 
 <?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
 <?xul-overlay href="chrome://browser/content/baseMenuOverlay.xul"?>
 <?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1060,16 +1060,18 @@
         <parameter name="aForceUpdate"/>
         <body>
           <![CDATA[
             var newBrowser = this.getBrowserAtIndex(this.tabContainer.selectedIndex);
             if (this.mCurrentBrowser == newBrowser && !aForceUpdate)
               return;
 
             if (!aForceUpdate) {
+              document.commandDispatcher.lock();
+
               TelemetryStopwatch.start("FX_TAB_SWITCH_UPDATE_MS");
               if (!gMultiProcessBrowser) {
                 // old way of measuring tab paint which is not valid with e10s.
                 // Waiting until the next MozAfterPaint ensures that we capture
                 // the time it takes to paint, upload the textures to the compositor,
                 // and then composite.
                 if (this._tabSwitchID) {
                   TelemetryStopwatch.cancel("FX_TAB_SWITCH_TOTAL_MS");
@@ -1269,16 +1271,18 @@
             }
 
             updateUserContextUIIndicator();
             gIdentityHandler.updateSharingIndicator();
 
             this.tabContainer._setPositionalAttributes();
 
             if (!gMultiProcessBrowser) {
+              document.commandDispatcher.unlock();
+
               let event = new CustomEvent("TabSwitchDone", {
                 bubbles: true,
                 cancelable: true
               });
               this.dispatchEvent(event);
             }
 
             if (!aForceUpdate)
@@ -3396,17 +3400,17 @@
       </method>
 
       <property name="selectedTab">
         <getter>
           return this.mCurrentTab;
         </getter>
         <setter>
           <![CDATA[
-          if (gNavToolbox.collapsed) {
+          if (gNavToolbox.collapsed && !this._allowTabChange) {
             return this.mTabBox.selectedTab;
           }
           // Update the tab
           this.mTabBox.selectedTab = val;
           return val;
           ]]>
         </setter>
       </property>
@@ -3976,16 +3980,18 @@
               let fromBrowser = this.originalTab.linkedBrowser;
               // It's possible that the tab we're switching from closed
               // before we were able to finalize, in which case, fromBrowser
               // doesn't exist.
               if (fromBrowser) {
                 fromBrowser.removeAttribute("primary");
               }
 
+              document.commandDispatcher.unlock();
+
               let event = new CustomEvent("TabSwitchDone", {
                 bubbles: true,
                 cancelable: true
               });
               this.tabbrowser.dispatchEvent(event);
             },
 
             // This function is called after all the main state changes to
--- a/browser/base/content/test/tabs/browser.ini
+++ b/browser/base/content/test/tabs/browser.ini
@@ -11,9 +11,10 @@ skip-if = !e10s # Tab spinner is e10s on
 skip-if = !e10s # Tab spinner is e10s only.
 [browser_tabSwitchPrintPreview.js]
 skip-if = os == 'mac'
 [browser_navigatePinnedTab.js]
 [browser_new_web_tab_in_file_process_pref.js]
 skip-if = !e10s # Pref and test only relevant for e10s.
 [browser_opened_file_tab_navigated_to_web.js]
 [browser_reload_deleted_file.js]
+[browser_tabswitch_updatecommands.js]
 [browser_viewsource_of_data_URI_in_file_process.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_tabswitch_updatecommands.js
@@ -0,0 +1,21 @@
+// This test ensures that only one command update happens when switching tabs.
+
+"use strict";
+
+add_task(function* () {
+  const uri = "data:text/html,<body><input>";
+  let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
+  let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
+
+  let updates = 0;
+  function countUpdates(event) { updates++; }
+  let updater = document.getElementById("editMenuCommandSetAll");
+  updater.addEventListener("commandupdate", countUpdates, true);
+  yield BrowserTestUtils.switchTab(gBrowser, tab1);
+
+  is(updates, 1, "only one command update per tab switch");
+
+  updater.removeEventListener("commandupdate", countUpdates, true);
+  yield BrowserTestUtils.removeTab(tab1);
+  yield BrowserTestUtils.removeTab(tab2);
+});
--- a/browser/base/content/test/windows/browser.ini
+++ b/browser/base/content/test/windows/browser.ini
@@ -1,3 +1,2 @@
 [DEFAULT]
 [browser_toolbariconcolor_restyles.js]
-skip-if = (os == "mac" || os == "win") && debug # Bug 1358356
--- a/browser/base/content/test/windows/browser_toolbariconcolor_restyles.js
+++ b/browser/base/content/test/windows/browser_toolbariconcolor_restyles.js
@@ -19,22 +19,22 @@ add_task(function* test_toolbar_element_
 
   let utils1 = SpecialPowers.getDOMWindowUtils(win1);
   restyles.win1.initial = utils1.elementsRestyled;
 
   let utils2 = SpecialPowers.getDOMWindowUtils(win2);
   restyles.win2.initial = utils2.elementsRestyled;
 
   // switch back to 1st window, and snapshot elementsStyled
-  win1.focus();
+  Services.focus.activeWindow = win1;
   restyles.win1.activate = utils1.elementsRestyled;
   restyles.win2.deactivate = utils2.elementsRestyled;
 
   // switch back to 2nd window, and snapshot elementsStyled
-  win2.focus();
+  Services.focus.activeWindow = win2;
   restyles.win2.activate = utils2.elementsRestyled;
   restyles.win1.deactivate = utils1.elementsRestyled;
 
   is(restyles.win1.activate - restyles.win1.deactivate, 0,
       "No elements restyled when re-activating/deactivating a window");
   is(restyles.win2.activate - restyles.win2.deactivate, 0,
       "No elements restyled when re-activating/deactivating a window");
 
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -515,17 +515,22 @@ const CustomizableWidgets = [
       item.setAttribute("targetURI", tabInfo.url);
       item.setAttribute("label", tabInfo.title != "" ? tabInfo.title : tabInfo.url);
       item.setAttribute("image", tabInfo.icon);
       item.setAttribute("tooltiptext", tooltipText);
       // We need to use "click" instead of "command" here so openUILink
       // respects different buttons (eg, to open in a new tab).
       item.addEventListener("click", e => {
         doc.defaultView.openUILink(tabInfo.url, e);
-        CustomizableUI.hidePanelForNode(item);
+        if (doc.defaultView.whereToOpenLink(e) != "current") {
+          e.preventDefault();
+          e.stopPropagation();
+        } else {
+          CustomizableUI.hidePanelForNode(item);
+        }
         BrowserUITelemetry.countSyncedTabEvent("open", "toolbarbutton-subview");
       });
       return item;
     },
     _createShowMoreElement(doc, clientId, showCount) {
       let labelAttr, tooltipAttr;
       if (showCount === Infinity) {
         labelAttr = "showAllLabel";
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -155,21 +155,16 @@ const PanelUI = {
     return new Promise(resolve => {
       this.ensureReady().then(() => {
         if (this.panel.state == "open" ||
             document.documentElement.hasAttribute("customizing")) {
           resolve();
           return;
         }
 
-        let editControlPlacement = CustomizableUI.getPlacementOfWidget("edit-controls");
-        if (editControlPlacement && editControlPlacement.area == CustomizableUI.AREA_PANEL) {
-          updateEditUIVisibility();
-        }
-
         let personalBookmarksPlacement = CustomizableUI.getPlacementOfWidget("personal-bookmarks");
         if (personalBookmarksPlacement &&
             personalBookmarksPlacement.area == CustomizableUI.AREA_PANEL) {
           PlacesToolbarHelper.customizeChange();
         }
 
         let anchor;
         if (!aEvent ||
@@ -287,20 +282,24 @@ const PanelUI = {
     // Ignore context menus and menu button menus showing and hiding:
     if (aEvent.type.startsWith("popup") &&
         aEvent.target != this.panel) {
       return;
     }
     switch (aEvent.type) {
       case "popupshowing":
         this._adjustLabelsForAutoHyphens();
+        updateEditUIVisibility();
         // Fall through
       case "popupshown":
         // Fall through
       case "popuphiding":
+        if (aEvent.type == "popuphiding") {
+          updateEditUIVisibility();
+        }
         // Fall through
       case "popuphidden":
         this._updateNotifications();
         this._updatePanelButton(aEvent.target);
         break;
       case "mousedown":
         if (aEvent.button == 0)
           this.toggle(aEvent);
--- a/browser/components/customizableui/test/browser.ini
+++ b/browser/components/customizableui/test/browser.ini
@@ -150,8 +150,10 @@ skip-if = os == "mac"
 [browser_customizemode_contextmenu_menubuttonstate.js]
 [browser_exit_background_customize_mode.js]
 [browser_overflow_use_subviews.js]
 [browser_panel_toggle.js]
 [browser_panelUINotifications.js]
 [browser_switch_to_customize_mode.js]
 [browser_synced_tabs_menu.js]
 [browser_check_tooltips_in_navbar.js]
+[browser_editcontrols_update.js]
+subsuite = clipboard
new file mode 100644
--- /dev/null
+++ b/browser/components/customizableui/test/browser_editcontrols_update.js
@@ -0,0 +1,162 @@
+// This test checks that the edit command enabled state (cut/paste) is updated
+// properly when the edit controls are on the toolbar, popup and not present.
+// It also verifies that the performance optimiation implemented by
+// updateEditUIVisibility in browser.js is applied.
+
+let isMac = navigator.platform.indexOf("Mac") == 0;
+
+function checkState(allowCut, desc, testWindow = window) {
+  is(testWindow.document.getElementById("cmd_cut").getAttribute("disabled") == "true", !allowCut, desc + " - cut");
+  is(testWindow.document.getElementById("cmd_paste").getAttribute("disabled") == "true", false, desc + " - paste");
+}
+
+// Add a special controller to the urlbar and browser to listen in on when
+// commands are being updated. Return a promise that resolves when 'count'
+// updates have occurred.
+function expectCommandUpdate(count, testWindow = window) {
+  return new Promise((resolve, reject) => {
+    let overrideController = {
+      supportsCommand(cmd) { return cmd == "cmd_delete"; },
+      isCommandEnabled(cmd) {
+        if (!count) {
+          ok(false, "unexpected update");
+          reject();
+        }
+
+        if (!--count) {
+          testWindow.gURLBar.controllers.removeControllerAt(0, overrideController);
+          testWindow.gBrowser.selectedBrowser.controllers.removeControllerAt(0, overrideController);
+          resolve(true);
+        }
+      }
+    };
+
+    if (!count) {
+      SimpleTest.executeSoon(() => {
+        testWindow.gURLBar.controllers.removeControllerAt(0, overrideController);
+        testWindow.gBrowser.selectedBrowser.controllers.removeControllerAt(0, overrideController);
+        resolve(false);
+      });
+    }
+
+    testWindow.gURLBar.controllers.insertControllerAt(0, overrideController);
+    testWindow.gBrowser.selectedBrowser.controllers.insertControllerAt(0, overrideController);
+  });
+}
+
+add_task(function* test_init() {
+  // Put something on the clipboard to verify that the paste button is properly enabled during the test.
+  let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
+  yield new Promise(resolve => {
+    SimpleTest.waitForClipboard("Sample", function() { clipboardHelper.copyString("Sample"); }, resolve);
+  });
+
+  // Open and close the panel first so that it is fully initialized.
+  yield PanelUI.show();
+  let hiddenPromise = promisePanelHidden(window);
+  PanelUI.hide();
+  yield hiddenPromise;
+});
+
+// Test updating when the panel is open with the edit-controls on the panel.
+// Updates should occur.
+add_task(function* test_panelui_opened() {
+  gURLBar.focus();
+  gURLBar.value = "test";
+
+  yield PanelUI.show();
+
+  checkState(false, "Update when edit-controls is on panel and visible");
+
+  let overridePromise = expectCommandUpdate(1);
+  gURLBar.select();
+  yield overridePromise;
+
+  checkState(true, "Update when edit-controls is on panel and selection changed");
+
+  overridePromise = expectCommandUpdate(0);
+  let hiddenPromise = promisePanelHidden(window);
+  PanelUI.hide();
+  yield hiddenPromise;
+  yield overridePromise;
+
+  // Check that updates do not occur after the panel has been closed.
+  checkState(true, "Update when edit-controls is on panel and hidden");
+
+  // Mac will update the enabled st1ate even when the panel is closed so that
+  // main menubar shortcuts will work properly.
+  overridePromise = expectCommandUpdate(isMac ? 1 : 0);
+  gURLBar.select();
+  yield overridePromise;
+  checkState(true, "Update when edit-controls is on panel, hidden and selection changed");
+});
+
+// Test updating when the edit-controls are moved to the toolbar.
+add_task(function* test_panelui_customize_to_toolbar() {
+  yield startCustomizing();
+  let navbar = document.getElementById("nav-bar").customizationTarget;
+  simulateItemDrag(document.getElementById("edit-controls"), navbar);
+  yield endCustomizing();
+
+  // updateEditUIVisibility should be called when customization ends but isn't. See bug 1359790.
+  updateEditUIVisibility();
+
+  let overridePromise = expectCommandUpdate(1);
+  gURLBar.select();
+  gURLBar.focus();
+  gURLBar.value = "other";
+  yield overridePromise;
+  checkState(false, "Update when edit-controls on toolbar and focused");
+
+  overridePromise = expectCommandUpdate(1);
+  gURLBar.select();
+  yield overridePromise;
+  checkState(true, "Update when edit-controls on toolbar and selection changed");
+});
+
+// Test updating when the edit-controls are moved to the palette.
+add_task(function* test_panelui_customize_to_palette() {
+  yield startCustomizing();
+  let palette = document.getElementById("customization-palette");
+  simulateItemDrag(document.getElementById("edit-controls"), palette);
+  yield endCustomizing();
+
+  // updateEditUIVisibility should be called when customization ends but isn't. See bug 1359790.
+  updateEditUIVisibility();
+
+  let overridePromise = expectCommandUpdate(isMac ? 1 : 0);
+  gURLBar.focus();
+  gURLBar.value = "other";
+  gURLBar.select();
+  yield overridePromise;
+
+  // If the UI isn't found, the command is set to be enabled.
+  checkState(true, "Update when edit-controls is on palette, hidden and selection changed");
+});
+
+add_task(function* finish() {
+  yield resetCustomization();
+});
+
+// Test updating in the initial state when the edit-controls are on the panel but
+// have not yet been created. This needs to be done in a new window to ensure that
+// other tests haven't opened the panel.
+add_task(function* test_initial_state() {
+  let testWindow = yield BrowserTestUtils.openNewBrowserWindow();
+  yield SimpleTest.promiseFocus(testWindow);
+
+  let overridePromise = expectCommandUpdate(isMac, testWindow);
+
+  testWindow.gURLBar.focus();
+  testWindow.gURLBar.value = "test";
+
+  yield overridePromise;
+
+  // Commands won't update when no edit UI is present. They default to being
+  // enabled so that keyboard shortcuts will work. The real enabled state will
+  // be checked when shortcut is pressed.
+  checkState(!isMac, "No update when edit-controls is on panel and not visible", testWindow);
+
+  yield BrowserTestUtils.closeWindow(testWindow);
+  yield SimpleTest.promiseFocus(window);
+});
--- a/browser/components/downloads/test/browser/browser.ini
+++ b/browser/components/downloads/test/browser/browser.ini
@@ -6,10 +6,11 @@ support-files = head.js
 skip-if = os == "linux" # Bug 949434
 [browser_overflow_anchor.js]
 skip-if = os == "linux" # Bug 952422
 [browser_confirm_unblock_download.js]
 [browser_iframe_gone_mid_download.js]
 [browser_indicatorDrop.js]
 [browser_libraryDrop.js]
 [browser_downloads_panel_block.js]
+skip-if = true # Bug 1352792
 [browser_downloads_panel_footer.js]
 [browser_downloads_panel_height.js]
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -17,16 +17,19 @@ with Files("tests/unit/test_browserGlue_
     BUG_COMPONENT = ("Firefox", "General")
 
 with Files("tests/unit/test_distribution.js"):
     BUG_COMPONENT = ("Firefox", "Distributions")
 
 with Files("safebrowsing/**"):
     BUG_COMPONENT = ("Toolkit", "Safe Browsing")
 
+with Files('controlcenter/**'):
+    BUG_COMPONENT = ('Firefox', 'General')
+
 
 DIRS += [
     'about',
     'contextualidentity',
     'customizableui',
     'dirprovider',
     'downloads',
     'extensions',
@@ -72,14 +75,8 @@ EXTRA_JS_MODULES += [
 BROWSER_CHROME_MANIFESTS += [
     'safebrowsing/content/test/browser.ini',
     'tests/browser/browser.ini'
 ]
 
 XPCSHELL_TESTS_MANIFESTS += [
     'tests/unit/xpcshell.ini'
 ]
-
-with Files('safebrowsing/*'):
-    BUG_COMPONENT = ('Toolkit', 'Phishing Protection')
-
-with Files('controlcenter/**'):
-    BUG_COMPONENT = ('Firefox', 'General')
--- a/browser/components/newtab/aboutNewTabService.js
+++ b/browser/components/newtab/aboutNewTabService.js
@@ -1,36 +1,34 @@
 /*
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
 
-/* globals XPCOMUtils, NewTabPrefsProvider, Services */
+/* globals XPCOMUtils, Preferences, Services */
 "use strict";
 
 const {utils: Cu, interfaces: Ci} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
-                                  "resource:///modules/NewTabPrefsProvider.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
 
 const LOCAL_NEWTAB_URL = "chrome://browser/content/newtab/newTab.xhtml";
 
 const ACTIVITY_STREAM_URL = "resource://activity-stream/data/content/activity-stream.html";
 
 const ABOUT_URL = "about:newtab";
 
 // Pref that tells if activity stream is enabled
 const PREF_ACTIVITY_STREAM_ENABLED = "browser.newtabpage.activity-stream.enabled";
 
 function AboutNewTabService() {
-  NewTabPrefsProvider.prefs.on(PREF_ACTIVITY_STREAM_ENABLED, this._handleToggleEvent.bind(this));
+  Preferences.observe(PREF_ACTIVITY_STREAM_ENABLED, this._handleToggleEvent.bind(this));
   this.toggleActivityStream(Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_ENABLED));
 }
 
 /*
  * A service that allows for the overriding, at runtime, of the newtab page's url.
  * Additionally, the service manages pref state between a activity stream, or the regular
  * about:newtab page.
  *
@@ -70,18 +68,18 @@ AboutNewTabService.prototype = {
   _overridden: false,
 
   classID: Components.ID("{dfcd2adc-7867-4d3a-ba70-17501f208142}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutNewTabService]),
   _xpcom_categories: [{
     service: true
   }],
 
-  _handleToggleEvent(prefName, stateEnabled, forceState) { // jshint unused:false
-    if (this.toggleActivityStream(stateEnabled, forceState)) {
+  _handleToggleEvent(stateEnabled) {
+    if (this.toggleActivityStream(stateEnabled)) {
       Services.obs.notifyObservers(null, "newtab-url-changed", ABOUT_URL);
     }
   },
 
   /**
    * React to changes to the activity stream pref.
    *
    * If browser.newtabpage.activity-stream.enabled is true, this will change the default URL to the
@@ -90,17 +88,17 @@ AboutNewTabService.prototype = {
    *
    * This will only act if there is a change of state and if not overridden.
    *
    * @returns {Boolean} Returns if there has been a state change
    *
    * @param {Boolean}   stateEnabled    activity stream enabled state to set to
    * @param {Boolean}   forceState      force state change
    */
-  toggleActivityStream(stateEnabled, forceState) {
+  toggleActivityStream(stateEnabled, forceState = false) {
 
     if (!forceState && (this.overridden || stateEnabled === this.activityStreamEnabled)) {
       // exit there is no change of state
       return false;
     }
     if (stateEnabled) {
       this._activityStreamEnabled = true;
     } else {
--- a/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
+++ b/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
@@ -1,45 +1,40 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-/* globals Services, XPCOMUtils, NewTabPrefsProvider, Preferences, aboutNewTabService, do_register_cleanup */
+/* globals Services, XPCOMUtils, Preferences, aboutNewTabService, do_register_cleanup */
 
 "use strict";
 
 const {utils: Cu} = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Preferences.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
-                                  "resource:///modules/NewTabPrefsProvider.jsm");
-
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 const DEFAULT_HREF = aboutNewTabService.activityStreamURL;
 const DEFAULT_CHROME_URL = "chrome://browser/content/newtab/newTab.xhtml";
 const DOWNLOADS_URL = "chrome://browser/content/downloads/contentAreaDownloadsView.xul";
 
 function cleanup() {
   Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
   aboutNewTabService.resetNewTabURL();
-  NewTabPrefsProvider.prefs.uninit();
 }
 
 do_register_cleanup(cleanup);
 
 /**
  * Test the overriding of the default URL
  */
 add_task(function* test_override_activity_stream_disabled() {
-  NewTabPrefsProvider.prefs.init();
   let notificationPromise;
   Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
 
   // tests default is the local newtab resource
   Assert.equal(aboutNewTabService.defaultURL, DEFAULT_CHROME_URL,
                `Default newtab URL should be ${DEFAULT_CHROME_URL}`);
 
   // override with some remote URL
@@ -64,17 +59,16 @@ add_task(function* test_override_activit
   yield notificationPromise;
   Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
   Assert.equal(aboutNewTabService.newTabURL, DOWNLOADS_URL, "Newtab URL should be the custom URL");
 
   cleanup();
 });
 
 add_task(function* test_override_activity_stream_enabled() {
-  NewTabPrefsProvider.prefs.init();
   let notificationPromise;
   // change newtab page to activity stream
   notificationPromise = nextChangeNotificationPromise("about:newtab");
   Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", true);
   yield notificationPromise;
   let activityStreamURL = aboutNewTabService.activityStreamURL;
   Assert.equal(aboutNewTabService.defaultURL, activityStreamURL, "Newtab URL should be the default activity stream URL");
   Assert.ok(!aboutNewTabService.overridden, "Newtab URL should not be overridden");
@@ -100,17 +94,16 @@ add_task(function* test_override_activit
 add_task(function* test_updates() {
   /*
    * Simulates a "cold-boot" situation, with some pref already set before testing a series
    * of changes.
    */
   Preferences.set("browser.newtabpage.activity-stream.enabled", true);
   aboutNewTabService.resetNewTabURL(); // need to set manually because pref notifs are off
   let notificationPromise;
-  NewTabPrefsProvider.prefs.init();
 
   // test update fires on override and reset
   let testURL = "https://example.com/";
   notificationPromise = nextChangeNotificationPromise(
     testURL, "a notification occurs on override");
   aboutNewTabService.newTabURL = testURL;
   yield notificationPromise;
 
--- a/browser/components/newtab/tests/xpcshell/test_NewTabURL.js
+++ b/browser/components/newtab/tests/xpcshell/test_NewTabURL.js
@@ -1,21 +1,19 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-/* globals Services, NewTabURL, XPCOMUtils, aboutNewTabService, NewTabPrefsProvider */
+/* globals Services, NewTabURL, XPCOMUtils, aboutNewTabService */
 "use strict";
 
 const {utils: Cu} = Components;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/NewTabURL.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
-                                  "resource:///modules/NewTabPrefsProvider.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 add_task(function*() {
   let defaultURL = aboutNewTabService.newTabURL;
   Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
 
@@ -29,21 +27,19 @@ add_task(function*() {
 
   notificationPromise = promiseNewtabURLNotification(defaultURL);
   NewTabURL.reset();
   yield notificationPromise;
   Assert.ok(!NewTabURL.overridden, "Newtab URL should not be overridden");
   Assert.equal(NewTabURL.get(), defaultURL, "Newtab URL should be the default");
 
   // change newtab page to activity stream
-  NewTabPrefsProvider.prefs.init();
   Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", true);
   Assert.equal(NewTabURL.get(), "about:newtab", `Newtab URL should be about:newtab`);
   Assert.ok(!NewTabURL.overridden, "Newtab URL should not be overridden");
-  NewTabPrefsProvider.prefs.uninit();
 });
 
 function promiseNewtabURLNotification(aNewURL) {
   return new Promise(resolve => {
     Services.obs.addObserver(function observer(aSubject, aTopic, aData) { // jshint ignore:line
       Services.obs.removeObserver(observer, aTopic);
       Assert.equal(aData, aNewURL, "Data for newtab-url-changed notification should be new URL.");
       resolve();
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -1105,18 +1105,23 @@ this.PlacesUIUtils = {
   },
 
   get leftPaneQueries() {
     // build the map
     this.leftPaneFolderId;
     return this.leftPaneQueries;
   },
 
+  get leftPaneFolderId() {
+    delete this.leftPaneFolderId;
+    return this.leftPaneFolderId = this.maybeRebuildLeftPane();
+  },
+
   // Get the folder id for the organizer left-pane folder.
-  get leftPaneFolderId() {
+  maybeRebuildLeftPane() {
     let leftPaneRoot = -1;
     let allBookmarksId;
 
     // Shortcuts to services.
     let bs = PlacesUtils.bookmarks;
     let as = PlacesUtils.annotations;
 
     // This is the list of the left pane queries.
@@ -1158,18 +1163,18 @@ this.PlacesUIUtils = {
         // This will throw if the annotation is an orphan.
         bs.removeItem(aItemId);
       } catch (e) { /* orphan anno */ }
     }
 
     // Returns true if item really exists, false otherwise.
     function itemExists(aItemId) {
       try {
-        bs.getItemIndex(aItemId);
-        return true;
+        let index = bs.getItemIndex(aItemId);
+        return index > -1;
       } catch (e) {
         return false;
       }
     }
 
     // Get all items marked as being the left pane folder.
     let items = as.getItemsWithAnnotation(this.ORGANIZER_FOLDER_ANNO);
     if (items.length > 1) {
@@ -1246,18 +1251,17 @@ this.PlacesUIUtils = {
       if (corrupt || queriesCount != EXPECTED_QUERY_COUNT) {
         // Queries number is wrong, so the left pane must be corrupt.
         // Note: we can't just remove the leftPaneRoot, because some query could
         // have a bad parent, so we have to remove all items one by one.
         queryItems.forEach(safeRemoveItem);
         safeRemoveItem(leftPaneRoot);
       } else {
         // Everything is fine, return the current left pane folder.
-        delete this.leftPaneFolderId;
-        return this.leftPaneFolderId = leftPaneRoot;
+        return leftPaneRoot;
       }
     }
 
     // Create a new left pane folder.
     var callback = {
       // Helper to create an organizer special query.
       create_query: function CB_create_query(aQueryName, aParentId, aQueryUrl) {
         let itemId = bs.insertBookmark(aParentId,
@@ -1340,18 +1344,17 @@ this.PlacesUIUtils = {
 
         // All Bookmarks->Unfiled Bookmarks Query.
         this.create_query("UnfiledBookmarks", allBookmarksId,
                           "place:folder=UNFILED_BOOKMARKS");
       }
     };
     bs.runInBatchMode(callback, null);
 
-    delete this.leftPaneFolderId;
-    return this.leftPaneFolderId = leftPaneRoot;
+    return leftPaneRoot;
   },
 
   /**
    * Get the folder id for the organizer left-pane folder.
    */
   get allBookmarksFolderId() {
     // ensure the left-pane root is initialized;
     this.leftPaneFolderId;
--- a/browser/components/preferences/in-content/tests/browser_bug731866.js
+++ b/browser/components/preferences/in-content/tests/browser_bug731866.js
@@ -1,16 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 
 const storageManagerDisabled = !SpecialPowers.getBoolPref("browser.storageManager.enabled");
 const offlineGroupDisabled = !SpecialPowers.getBoolPref("browser.preferences.offlineGroup.enabled");
+const browserContainersGroupDisabled = !SpecialPowers.getBoolPref("privacy.userContext.ui.enabled");
 
 function test() {
   waitForExplicitFinish();
   open_preferences(runTest);
 }
 
 var gElements;
 
@@ -33,16 +34,21 @@ function checkElements(expectedPane) {
     }
     // The siteDataGroup in the Storage Management project will replace the offlineGroup eventually,
     // so during the transition period, we have to check the pref to see if the offlineGroup
     // should be hidden always. See the bug 1354530 for the details.
     if (element.id == "offlineGroup" && offlineGroupDisabled) {
       is_element_hidden(element, "Disabled offlineGroup should be hidden");
       continue;
     }
+    // The browserContainersGroup is still only pref-on on Nightly
+    if (element.id == "browserContainersGroup" && browserContainersGroupDisabled) {
+      is_element_hidden(element, "Disabled browserContainersGroup should be hidden");
+      continue;
+    }
 
     let attributeValue = element.getAttribute("data-category");
     let suffix = " (id=" + element.id + ")";
     if (attributeValue == "pane" + expectedPane) {
       is_element_visible(element, expectedPane + " elements should be visible" + suffix);
     } else {
       is_element_hidden(element, "Elements not in " + expectedPane + " should be hidden" + suffix);
     }
--- a/browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js
+++ b/browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js
@@ -16,17 +16,18 @@ function test() {
     Services.perms.removeFromPrincipal(principal, "persistent-storage");
   });
 
   SpecialPowers.pushPrefEnv({set: [
     ["browser.cache.offline.enable", false],
     ["browser.cache.disk.enable", false],
     ["browser.cache.memory.enable", false],
     ["browser.storageManager.enabled", true],
-    ["browser.preferences.offlineGroup.enabled", true]
+    ["browser.preferences.offlineGroup.enabled", true],
+    ["privacy.userContext.ui.enabled", true]
   ]}).then(() => open_preferences(runTest));
 }
 
 function runTest(win) {
   is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
 
   let tab = win.document;
   let elements = tab.getElementById("mainPrefPane").children;
@@ -34,18 +35,18 @@ function runTest(win) {
   // Test if privacy pane is opened correctly
   win.gotoPref("panePrivacy");
   for (let element of elements) {
     if (element.nodeName == "preferences") {
       continue;
     }
     let attributeValue = element.getAttribute("data-category");
     if (attributeValue == "panePrivacy") {
-      is_element_visible(element, "Privacy elements should be visible");
+      is_element_visible(element, `Privacy element of id=${element.id} should be visible`);
     } else {
-      is_element_hidden(element, "Non-Privacy elements should be hidden");
+      is_element_hidden(element, `Non-Privacy element of id=${element.id} should be hidden`);
     }
   }
 
   gBrowser.removeCurrentTab();
   win.close();
   finish();
 }
--- a/browser/config/mozconfigs/linux32/devedition
+++ b/browser/config/mozconfigs/linux32/devedition
@@ -7,10 +7,12 @@ ac_add_options --enable-verify-mar
 
 # This will overwrite the default of stripping everything and keep the symbol table.
 # This is useful for profiling and debugging and only increases the package size
 # by 2 MBs.
 STRIP_FLAGS="--strip-debug"
 
 ac_add_options --with-branding=browser/branding/aurora
 
+mk_add_options MOZ_PGO=1
+
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/devedition
+++ b/browser/config/mozconfigs/linux64/devedition
@@ -7,10 +7,12 @@ ac_add_options --enable-verify-mar
 
 # This will overwrite the default of stripping everything and keep the symbol table.
 # This is useful for profiling and debugging and only increases the package size
 # by 2 MBs.
 STRIP_FLAGS="--strip-debug"
 
 ac_add_options --with-branding=browser/branding/aurora
 
+mk_add_options MOZ_PGO=1
+
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/win32/devedition
+++ b/browser/config/mozconfigs/win32/devedition
@@ -3,10 +3,12 @@
 
 # Add-on signing is not required for DevEdition
 MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
 
 ac_add_options --with-branding=browser/branding/aurora
 
+mk_add_options MOZ_PGO=1
+
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/win64/devedition
+++ b/browser/config/mozconfigs/win64/devedition
@@ -4,10 +4,12 @@
 
 # Add-on signing is not required for DevEdition
 MOZ_REQUIRE_SIGNING=0
 
 ac_add_options --enable-verify-mar
 
 ac_add_options --with-branding=browser/branding/aurora
 
+mk_add_options MOZ_PGO=1
+
 . "$topsrcdir/build/mozconfig.common.override"
 . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/tooltool-manifests/macosx64/clang.manifest
+++ b/browser/config/tooltool-manifests/macosx64/clang.manifest
@@ -1,13 +1,13 @@
 [
   {
     "version": "clang 3.9.0",
-    "size": 184678304,
-    "digest": "cfde9a0f7f59823200f94422b4adb9a2fb5d4d07f240bbd1142c792434f6a1cbb4096d25c9853d77008fc40db0d827daa7003e78016f51241f621d6040ccc635",
+    "size": 185632474,
+    "digest": "0e1a556b65d6398fa812b9ceb5ce5e2dec3eda77d4a032a818182b34fc8ce602412f42388bb1fda6bea265d35c1dde3847a730b264fec01cd7e3dcfd39941660",
     "algorithm": "sha512",
     "filename": "clang.tar.bz2",
     "unpack": true
   },
   {
     "version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
     "size": 81913425,
     "digest": "41a9dc3f1c0df56f125a4f16cac3635bd3cc2af7167388f54eb4346a599cd8be875475a87a8dd1720d52281ecd361a1050d9523f052f424bce686ba061af6d6c",
--- a/browser/config/tooltool-manifests/macosx64/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/releng.manifest
@@ -1,13 +1,13 @@
 [
   {
     "version": "clang 3.9.0",
-    "size": 184678304,
-    "digest": "cfde9a0f7f59823200f94422b4adb9a2fb5d4d07f240bbd1142c792434f6a1cbb4096d25c9853d77008fc40db0d827daa7003e78016f51241f621d6040ccc635",
+    "size": 185632474,
+    "digest": "0e1a556b65d6398fa812b9ceb5ce5e2dec3eda77d4a032a818182b34fc8ce602412f42388bb1fda6bea265d35c1dde3847a730b264fec01cd7e3dcfd39941660",
     "algorithm": "sha512",
     "filename": "clang.tar.bz2",
     "unpack": true
   },
   {
     "version": "rustc 1.17.0 (56124baa9 2017-04-24) repack with cargo 0.19.0-beta.1 (03efb7fc8 2017-04-23)",
     "size": 81913425,
     "digest": "41a9dc3f1c0df56f125a4f16cac3635bd3cc2af7167388f54eb4346a599cd8be875475a87a8dd1720d52281ecd361a1050d9523f052f424bce686ba061af6d6c",
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,3 +1,5 @@
-This is the pdf.js project output, https://github.com/mozilla/pdf.js
+This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 1.8.269
+Current extension version is: 1.8.290
+
+Taken from upstream commit: 60c232bc
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -789,20 +789,20 @@ class FindEventManager {
     this.contentWindow = contentWindow;
     this.winmm = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsIDocShell)
                               .QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsIContentFrameMessageManager);
   }
 
   bind() {
-    var unload = function(e) {
+    var unload = (evt) => {
       this.unbind();
-      this.contentWindow.removeEventListener(e.type, unload);
-    }.bind(this);
+      this.contentWindow.removeEventListener(evt.type, unload);
+    };
     this.contentWindow.addEventListener("unload", unload);
 
     // We cannot directly attach listeners to for the find events
     // since the FindBar is in the parent process. Instead we're
     // asking the PdfjsChromeUtils to do it for us and forward
     // all the find events to us.
     this.winmm.sendAsyncMessage("PDFJS:Parent:addEventListener");
     this.winmm.addMessageListener("PDFJS:Child:handleEvent", this);
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -961,17 +961,17 @@ var createBlob = function createBlob(dat
   if (typeof Blob !== 'undefined') {
     return new Blob([data], { type: contentType });
   }
   throw new Error('The "Blob" constructor is not supported.');
 };
 var createObjectURL = function createObjectURLClosure() {
   var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
   return function createObjectURL(data, contentType, forceDataSchema = false) {
-    if (!forceDataSchema) {
+    if (!forceDataSchema && URL.createObjectURL) {
       var blob = createBlob(data, contentType);
       return URL.createObjectURL(blob);
     }
     var buffer = 'data:' + contentType + ';base64,';
     for (var i = 0, ii = data.length; i < ii; i += 3) {
       var b1 = data[i] & 0xFF;
       var b2 = data[i + 1] & 0xFF;
       var b3 = data[i + 2] & 0xFF;
@@ -3386,18 +3386,18 @@ var _UnsupportedManager = function Unsup
       for (var i = 0, ii = listeners.length; i < ii; i++) {
         listeners[i](featureId);
       }
     }
   };
 }();
 var version, build;
 {
-  exports.version = version = '1.8.269';
-  exports.build = build = 'acdfc2d8';
+  exports.version = version = '1.8.290';
+  exports.build = build = '60c232bc';
 }
 exports.getDocument = getDocument;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports._UnsupportedManager = _UnsupportedManager;
 exports.version = version;
@@ -4389,18 +4389,18 @@ var _text_layer = __w_pdfjs_require__(5)
 var _svg = __w_pdfjs_require__(4);
 
 var isWorker = typeof window === 'undefined';
 if (!_util.globalScope.PDFJS) {
   _util.globalScope.PDFJS = {};
 }
 var PDFJS = _util.globalScope.PDFJS;
 {
-  PDFJS.version = '1.8.269';
-  PDFJS.build = 'acdfc2d8';
+  PDFJS.version = '1.8.290';
+  PDFJS.build = '60c232bc';
 }
 PDFJS.pdfBug = false;
 if (PDFJS.verbosity !== undefined) {
   (0, _util.setVerbosityLevel)(PDFJS.verbosity);
 }
 delete PDFJS.verbosity;
 Object.defineProperty(PDFJS, 'verbosity', {
   get() {
@@ -6703,18 +6703,18 @@ exports.TilingPattern = TilingPattern;
 
 /***/ }),
 /* 13 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '1.8.269';
-var pdfjsBuild = 'acdfc2d8';
+var pdfjsVersion = '1.8.290';
+var pdfjsBuild = '60c232bc';
 var pdfjsSharedUtil = __w_pdfjs_require__(0);
 var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
 var pdfjsDisplayAPI = __w_pdfjs_require__(3);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(5);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(2);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(1);
 var pdfjsDisplaySVG = __w_pdfjs_require__(4);
 exports.PDFJS = pdfjsDisplayGlobal.PDFJS;
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -961,17 +961,17 @@ var createBlob = function createBlob(dat
   if (typeof Blob !== 'undefined') {
     return new Blob([data], { type: contentType });
   }
   throw new Error('The "Blob" constructor is not supported.');
 };
 var createObjectURL = function createObjectURLClosure() {
   var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
   return function createObjectURL(data, contentType, forceDataSchema = false) {
-    if (!forceDataSchema) {
+    if (!forceDataSchema && URL.createObjectURL) {
       var blob = createBlob(data, contentType);
       return URL.createObjectURL(blob);
     }
     var buffer = 'data:' + contentType + ';base64,';
     for (var i = 0, ii = data.length; i < ii; i += 3) {
       var b1 = data[i] & 0xFF;
       var b2 = data[i + 1] & 0xFF;
       var b3 = data[i + 2] & 0xFF;
@@ -2965,17 +2965,17 @@ var CCITTFaxStream = function CCITTFaxSt
 var LZWStream = function LZWStreamClosure() {
   function LZWStream(str, maybeLength, earlyChange) {
     this.str = str;
     this.dict = str.dict;
     this.cachedData = 0;
     this.bitsCached = 0;
     var maxLzwDictionarySize = 4096;
     var lzwState = {
-      earlyChange: earlyChange,
+      earlyChange,
       codeLength: 9,
       nextCode: 258,
       dictionaryValues: new Uint8Array(maxLzwDictionarySize),
       dictionaryLengths: new Uint16Array(maxLzwDictionarySize),
       dictionaryPrevCodes: new Uint16Array(maxLzwDictionarySize),
       currentSequence: new Uint8Array(maxLzwDictionarySize),
       currentSequenceLength: 0
     };
@@ -5035,17 +5035,17 @@ var Linearization = {
     var linDict = parser.getObj();
     var obj, length;
     if (!(isInt(obj1) && isInt(obj2) && isCmd(obj3, 'obj') && isDict(linDict) && isNum(obj = linDict.get('Linearized')) && obj > 0)) {
       return null;
     } else if ((length = getInt('L')) !== stream.length) {
       throw new Error('The "L" parameter in the linearization dictionary ' + 'does not equal the stream length.');
     }
     return {
-      length: length,
+      length,
       hints: getHints(),
       objectNumberFirst: getInt('O'),
       endFirst: getInt('E'),
       numPages: getInt('N'),
       mainXRefEntriesOffset: getInt('T'),
       pageFirst: linDict.has('P') ? getInt('P', true) : 0
     };
   }
@@ -10307,45 +10307,45 @@ var PostScriptCompiler = function PostSc
   AstVariableDefinition.prototype = Object.create(AstNode.prototype);
   AstVariableDefinition.prototype.visit = function (visitor) {
     visitor.visitVariableDefinition(this);
   };
   function ExpressionBuilderVisitor() {
     this.parts = [];
   }
   ExpressionBuilderVisitor.prototype = {
-    visitArgument: function (arg) {
+    visitArgument(arg) {
       this.parts.push('Math.max(', arg.min, ', Math.min(', arg.max, ', src[srcOffset + ', arg.index, ']))');
     },
-    visitVariable: function (variable) {
+    visitVariable(variable) {
       this.parts.push('v', variable.index);
     },
-    visitLiteral: function (literal) {
+    visitLiteral(literal) {
       this.parts.push(literal.number);
     },
-    visitBinaryOperation: function (operation) {
+    visitBinaryOperation(operation) {
       this.parts.push('(');
       operation.arg1.visit(this);
       this.parts.push(' ', operation.op, ' ');
       operation.arg2.visit(this);
       this.parts.push(')');
     },
-    visitVariableDefinition: function (definition) {
+    visitVariableDefinition(definition) {
       this.parts.push('var ');
       definition.variable.visit(this);
       this.parts.push(' = ');
       definition.arg.visit(this);
       this.parts.push(';');
     },
-    visitMin: function (max) {
+    visitMin(max) {
       this.parts.push('Math.min(');
       max.arg.visit(this);
       this.parts.push(', ', max.max, ')');
     },
-    toString: function () {
+    toString() {
       return this.parts.join('');
     }
   };
   function buildAddOperation(num1, num2) {
     if (num2.type === 'literal' && num2.number === 0) {
       return num1;
     }
     if (num1.type === 'literal' && num1.number === 0) {
@@ -13506,19 +13506,19 @@ var CFFParser = function CFFParserClosur
         if (state.seac !== null) {
           seacs[i] = state.seac;
         }
         if (!valid) {
           charStrings.set(i, new Uint8Array([14]));
         }
       }
       return {
-        charStrings: charStrings,
-        seacs: seacs,
-        widths: widths
+        charStrings,
+        seacs,
+        widths
       };
     },
     emptyPrivateDictionary: function CFFParser_emptyPrivateDictionary(parentDict) {
       var privateDict = this.createDict(CFFPrivateDict, [], parentDict.strings);
       parentDict.setByKey(18, [0, 0]);
       parentDict.privateDict = privateDict;
     },
     parsePrivateDict: function CFFParser_parsePrivateDict(parentDict) {
@@ -14537,17 +14537,17 @@ var ChunkedStreamManager = function Chun
       var promise = new Promise(function (resolve, reject) {
         var readChunk = function (chunk) {
           try {
             if (!chunk.done) {
               var data = chunk.value;
               chunks.push(data);
               loaded += arrayByteLength(data);
               if (rangeReader.isStreamingSupported) {
-                manager.onProgress({ loaded: loaded });
+                manager.onProgress({ loaded });
               }
               rangeReader.read().then(readChunk, reject);
               return;
             }
             var chunkData = arraysToBytes(chunks);
             chunks = null;
             resolve(chunkData);
           } catch (e) {
@@ -14557,17 +14557,17 @@ var ChunkedStreamManager = function Chun
         rangeReader.read().then(readChunk, reject);
       });
       promise.then(function (data) {
         if (this.aborted) {
           return;
         }
         this.onReceiveData({
           chunk: data,
-          begin: begin
+          begin
         });
       }.bind(this));
     },
     requestAllChunks: function ChunkedStreamManager_requestAllChunks() {
       var missingChunks = this.stream.getMissingChunks();
       this._requestChunks(missingChunks);
       return this._loadedStreamCapability.promise;
     },
@@ -14643,24 +14643,24 @@ var ChunkedStreamManager = function Chun
       var prevChunk = -1;
       for (var i = 0; i < chunks.length; ++i) {
         var chunk = chunks[i];
         if (beginChunk < 0) {
           beginChunk = chunk;
         }
         if (prevChunk >= 0 && prevChunk + 1 !== chunk) {
           groupedChunks.push({
-            beginChunk: beginChunk,
+            beginChunk,
             endChunk: prevChunk + 1
           });
           beginChunk = chunk;
         }
         if (i + 1 === chunks.length) {
           groupedChunks.push({
-            beginChunk: beginChunk,
+            beginChunk,
             endChunk: chunk + 1
           });
         }
         prevChunk = chunk;
       }
       return groupedChunks;
     },
     onProgress: function ChunkedStreamManager_onProgress(args) {
@@ -16445,20 +16445,20 @@ var PartialEvaluator = function PartialE
   };
   function NativeImageDecoder(xref, resources, handler, forceDataSchema) {
     this.xref = xref;
     this.resources = resources;
     this.handler = handler;
     this.forceDataSchema = forceDataSchema;
   }
   NativeImageDecoder.prototype = {
-    canDecode: function (image) {
+    canDecode(image) {
       return image instanceof JpegStream && NativeImageDecoder.isDecodable(image, this.xref, this.resources);
     },
-    decode: function (image) {
+    decode(image) {
       var dict = image.dict;
       var colorSpace = dict.get('ColorSpace', 'CS');
       colorSpace = ColorSpace.parse(colorSpace, this.xref, this.resources);
       var numComps = colorSpace.numComps;
       var decodePromise = this.handler.sendWithPromise('JpegDecode', [image.getIR(this.forceDataSchema), numComps]);
       return decodePromise.then(function (message) {
         var data = message.data;
         return new Stream(data, 0, data.length, image.dict);
@@ -16485,24 +16485,24 @@ var PartialEvaluator = function PartialE
     this.pdfManager = pdfManager;
     this.xref = xref;
     this.handler = handler;
     this.pageIndex = pageIndex;
     this.idFactory = idFactory;
     this.fontCache = fontCache;
     this.builtInCMapCache = builtInCMapCache;
     this.options = options || DefaultPartialEvaluatorOptions;
-    this.fetchBuiltInCMap = function (name) {
-      var cachedCMap = builtInCMapCache[name];
+    this.fetchBuiltInCMap = name => {
+      var cachedCMap = this.builtInCMapCache[name];
       if (cachedCMap) {
         return Promise.resolve(cachedCMap);
       }
-      return handler.sendWithPromise('FetchBuiltInCMap', { name: name }).then(function (data) {
+      return handler.sendWithPromise('FetchBuiltInCMap', { name }).then(data => {
         if (data.compressionType !== CMapCompressionType.NONE) {
-          builtInCMapCache[name] = data;
+          this.builtInCMapCache[name] = data;
         }
         return data;
       });
     };
   }
   var TIME_SLOT_DURATION_MS = 20;
   var CHECK_TIME_EVERY = 100;
   function TimeSlotManager() {
@@ -16562,18 +16562,17 @@ var PartialEvaluator = function PartialE
     }
     warn('Unsupported blend mode: ' + value.name);
     return 'source-over';
   }
   var deferred = Promise.resolve();
   var TILING_PATTERN = 1,
       SHADING_PATTERN = 2;
   PartialEvaluator.prototype = {
-    clone: function (newOptions) {
-      newOptions = newOptions || DefaultPartialEvaluatorOptions;
+    clone(newOptions = DefaultPartialEvaluatorOptions) {
       var newEvaluator = Object.create(this);
       newEvaluator.options = newOptions;
       return newEvaluator;
     },
     hasBlendModes: function PartialEvaluator_hasBlendModes(resources) {
       if (!isDict(resources)) {
         return false;
       }
@@ -16634,19 +16633,19 @@ var PartialEvaluator = function PartialE
     },
     buildFormXObject: function PartialEvaluator_buildFormXObject(resources, xobj, smask, operatorList, task, initialState) {
       var dict = xobj.dict;
       var matrix = dict.getArray('Matrix');
       var bbox = dict.getArray('BBox');
       var group = dict.get('Group');
       if (group) {
         var groupOptions = {
-          matrix: matrix,
-          bbox: bbox,
-          smask: smask,
+          matrix,
+          bbox,
+          smask,
           isolated: false,
           knockout: false
         };
         var groupSubtype = group.get('S');
         var colorSpace;
         if (isName(groupSubtype, 'Transparency')) {
           groupOptions.isolated = group.get('I') || false;
           groupOptions.knockout = group.get('K') || false;
@@ -16691,17 +16690,17 @@ var PartialEvaluator = function PartialE
         var inverseDecode = !!decode && decode[0] > 0;
         imgData = PDFImage.createMask(imgArray, width, height, image instanceof DecodeStream, inverseDecode);
         imgData.cached = true;
         args = [imgData];
         operatorList.addOp(OPS.paintImageMaskXObject, args);
         if (cacheKey) {
           imageCache[cacheKey] = {
             fn: OPS.paintImageMaskXObject,
-            args: args
+            args
           };
         }
         return;
       }
       var softMask = dict.get('SMask', 'SM') || false;
       var mask = dict.get('Mask') || false;
       var SMALL_IMAGE_DIMENSIONS = 200;
       if (inline && !softMask && !mask && !(image instanceof JpegStream) && w + h < SMALL_IMAGE_DIMENSIONS) {
@@ -16729,17 +16728,17 @@ var PartialEvaluator = function PartialE
       }).then(undefined, function (reason) {
         warn('Unable to decode image: ' + reason);
         self.handler.send('obj', [objId, self.pageIndex, 'Image', null]);
       });
       operatorList.addOp(OPS.paintImageXObject, args);
       if (cacheKey) {
         imageCache[cacheKey] = {
           fn: OPS.paintImageXObject,
-          args: args
+          args
         };
       }
     },
     handleSMask: function PartialEvaluator_handleSmask(smask, resources, operatorList, task, stateManager) {
       var smaskContent = smask.get('G');
       var smaskOptions = {
         subtype: smask.get('S').name,
         backdrop: smask.get('BC')
@@ -18038,19 +18037,19 @@ var PartialEvaluator = function PartialE
       var glyphWidths = Metrics[lookupName];
       if (isNum(glyphWidths)) {
         defaultWidth = glyphWidths;
         monospace = true;
       } else {
         widths = glyphWidths();
       }
       return {
-        defaultWidth: defaultWidth,
-        monospace: monospace,
-        widths: widths
+        defaultWidth,
+        monospace,
+        widths
       };
     },
     buildCharCodeToWidth: function PartialEvaluator_bulildCharCodeToWidth(widthsByGlyphName, properties) {
       var widths = Object.create(null);
       var differences = properties.differences;
       var encoding = properties.defaultEncoding;
       for (var charCode = 0; charCode < 256; charCode++) {
         if (charCode in differences && widthsByGlyphName[differences[charCode]]) {
@@ -18119,20 +18118,20 @@ var PartialEvaluator = function PartialE
         }
         var widths = dict.get('Widths') || baseDict.get('Widths');
         if (widths) {
           uint8array = new Uint8Array(new Uint32Array(widths).buffer);
           hash.update(uint8array);
         }
       }
       return {
-        descriptor: descriptor,
-        dict: dict,
-        baseDict: baseDict,
-        composite: composite,
+        descriptor,
+        dict,
+        baseDict,
+        composite,
         type: type.name,
         hash: hash ? hash.hexdigest() : ''
       };
     },
     translateFont: function PartialEvaluator_translateFont(preEvaluatedFont) {
       var baseDict = preEvaluatedFont.baseDict;
       var dict = preEvaluatedFont.dict;
       var composite = preEvaluatedFont.composite;
@@ -18148,21 +18147,21 @@ var PartialEvaluator = function PartialE
         } else {
           var baseFontName = dict.get('BaseFont');
           assert(isName(baseFontName), 'Base font is not specified');
           baseFontName = baseFontName.name.replace(/[,_]/g, '-');
           var metrics = this.getBaseFontMetrics(baseFontName);
           var fontNameWoStyle = baseFontName.split('-')[0];
           var flags = (this.isSerifFont(fontNameWoStyle) ? FontFlags.Serif : 0) | (metrics.monospace ? FontFlags.FixedPitch : 0) | (getSymbolsFonts()[fontNameWoStyle] ? FontFlags.Symbolic : FontFlags.Nonsymbolic);
           properties = {
-            type: type,
+            type,
             name: baseFontName,
             widths: metrics.widths,
             defaultWidth: metrics.defaultWidth,
-            flags: flags,
+            flags,
             firstChar: 0,
             lastChar: maxCharIndex
           };
           return this.extractDataStructures(dict, dict, properties).then(function (properties) {
             properties.widths = this.buildCharCodeToWidth(metrics.widths, properties);
             return new Font(baseFontName, null, properties);
           }.bind(this));
         }
@@ -18197,25 +18196,25 @@ var PartialEvaluator = function PartialE
             subtype = subtype.name;
           }
           var length1 = fontFile.dict.get('Length1');
           var length2 = fontFile.dict.get('Length2');
           var length3 = fontFile.dict.get('Length3');
         }
       }
       properties = {
-        type: type,
+        type,
         name: fontName.name,
-        subtype: subtype,
+        subtype,
         file: fontFile,
-        length1: length1,
-        length2: length2,
-        length3: length3,
+        length1,
+        length2,
+        length3,
         loadedName: baseDict.loadedName,
-        composite: composite,
+        composite,
         wideChars: composite,
         fixedPitch: false,
         fontMatrix: dict.getArray('FontMatrix') || FONT_IDENTITY_MATRIX,
         firstChar: firstChar || 0,
         lastChar: lastChar || maxCharIndex,
         bbox: descriptor.getArray('FontBBox'),
         ascent: descriptor.get('Ascent'),
         descent: descriptor.get('Descent'),
@@ -18259,25 +18258,25 @@ var TranslatedFont = function Translated
   function TranslatedFont(loadedName, font, dict) {
     this.loadedName = loadedName;
     this.font = font;
     this.dict = dict;
     this.type3Loaded = null;
     this.sent = false;
   }
   TranslatedFont.prototype = {
-    send: function (handler) {
+    send(handler) {
       if (this.sent) {
         return;
       }
       var fontData = this.font.exportData();
       handler.send('commonobj', [this.loadedName, 'Font', fontData]);
       this.sent = true;
     },
-    loadType3Data: function (evaluator, resources, parentOperatorList, task) {
+    loadType3Data(evaluator, resources, parentOperatorList, task) {
       assert(this.font.isType3Font);
       if (this.type3Loaded) {
         return this.type3Loaded;
       }
       var type3Options = Object.create(evaluator.options);
       type3Options.ignoreErrors = false;
       var type3Evaluator = evaluator.clone(type3Options);
       var translatedFont = this.font;
@@ -18340,65 +18339,65 @@ var OperatorList = function OperatorList
   }
   OperatorList.prototype = {
     get length() {
       return this.argsArray.length;
     },
     get totalLength() {
       return this._totalLength + this.length;
     },
-    addOp: function (fn, args) {
+    addOp(fn, args) {
       this.fnArray.push(fn);
       this.argsArray.push(args);
       if (this.messageHandler) {
         if (this.fnArray.length >= CHUNK_SIZE) {
           this.flush();
         } else if (this.fnArray.length >= CHUNK_SIZE_ABOUT && (fn === OPS.restore || fn === OPS.endText)) {
           this.flush();
         }
       }
     },
-    addDependency: function (dependency) {
+    addDependency(dependency) {
       if (dependency in this.dependencies) {
         return;
       }
       this.dependencies[dependency] = true;
       this.addOp(OPS.dependency, [dependency]);
     },
-    addDependencies: function (dependencies) {
+    addDependencies(dependencies) {
       for (var key in dependencies) {
         this.addDependency(key);
       }
     },
-    addOpList: function (opList) {
+    addOpList(opList) {
       Util.extendObj(this.dependencies, opList.dependencies);
       for (var i = 0, ii = opList.length; i < ii; i++) {
         this.addOp(opList.fnArray[i], opList.argsArray[i]);
       }
     },
-    getIR: function () {
+    getIR() {
       return {
         fnArray: this.fnArray,
         argsArray: this.argsArray,
         length: this.length
       };
     },
-    flush: function (lastChunk) {
+    flush(lastChunk) {
       if (this.intent !== 'oplist') {
         new QueueOptimizer().optimize(this);
       }
       var transfers = getTransfers(this);
       var length = this.length;
       this._totalLength += length;
       this.messageHandler.send('RenderPageChunk', {
         operatorList: {
           fnArray: this.fnArray,
           argsArray: this.argsArray,
-          lastChunk: lastChunk,
-          length: length
+          lastChunk,
+          length
         },
         pageIndex: this.pageIndex,
         intent: this.intent
       }, transfers);
       this.dependencies = Object.create(null);
       this.fnArray.length = 0;
       this.argsArray.length = 0;
     }
@@ -18406,28 +18405,28 @@ var OperatorList = function OperatorList
   return OperatorList;
 }();
 var StateManager = function StateManagerClosure() {
   function StateManager(initialState) {
     this.state = initialState;
     this.stateStack = [];
   }
   StateManager.prototype = {
-    save: function () {
+    save() {
       var old = this.state;
       this.stateStack.push(this.state);
       this.state = old.clone();
     },
-    restore: function () {
+    restore() {
       var prev = this.stateStack.pop();
       if (prev) {
         this.state = prev;
       }
     },
-    transform: function (args) {
+    transform(args) {
       this.state.ctm = Util.transform(this.state.ctm, args);
     }
   };
   return StateManager;
 }();
 var TextState = function TextStateClosure() {
   function TextState() {
     this.ctm = new Float32Array(IDENTITY_MATRIX);
@@ -19052,17 +19051,17 @@ var QueueOptimizer = function QueueOptim
       var img = argsArray[iFirstPIIXO + (q << 2)][0];
       if (currentX + img.width > MAX_WIDTH) {
         maxX = Math.max(maxX, currentX);
         currentY += maxLineHeight + 2 * IMAGE_PADDING;
         currentX = 0;
         maxLineHeight = 0;
       }
       map.push({
-        transform: transform,
+        transform,
         x: currentX,
         y: currentY,
         w: img.width,
         h: img.height
       });
       currentX += img.width + 2 * IMAGE_PADDING;
       maxLineHeight = Math.max(maxLineHeight, img.height);
     }
@@ -19266,18 +19265,18 @@ var QueueOptimizer = function QueueOptim
   });
   function QueueOptimizer() {}
   QueueOptimizer.prototype = {
     optimize: function QueueOptimizer_optimize(queue) {
       var fnArray = queue.fnArray,
           argsArray = queue.argsArray;
       var context = {
         iCurr: 0,
-        fnArray: fnArray,
-        argsArray: argsArray
+        fnArray,
+        argsArray
       };
       var state;
       var i = 0,
           ii = fnArray.length;
       while (i < ii) {
         state = (state || InitialState)[fnArray[i]];
         if (typeof state === 'function') {
           context.iCurr = i;
@@ -19740,23 +19739,23 @@ var JpxImage = function JpxImageClosure(
     var precinctHeight = 1 << dimensions.PPy;
     var isZeroRes = resolution.resLevel === 0;
     var precinctWidthInSubband = 1 << dimensions.PPx + (isZeroRes ? 0 : -1);
     var precinctHeightInSubband = 1 << dimensions.PPy + (isZeroRes ? 0 : -1);
     var numprecinctswide = resolution.trx1 > resolution.trx0 ? Math.ceil(resolution.trx1 / precinctWidth) - Math.floor(resolution.trx0 / precinctWidth) : 0;
     var numprecinctshigh = resolution.try1 > resolution.try0 ? Math.ceil(resolution.try1 / precinctHeight) - Math.floor(resolution.try0 / precinctHeight) : 0;
     var numprecincts = numprecinctswide * numprecinctshigh;
     resolution.precinctParameters = {
-      precinctWidth: precinctWidth,
-      precinctHeight: precinctHeight,
-      numprecinctswide: numprecinctswide,
-      numprecinctshigh: numprecinctshigh,
-      numprecincts: numprecincts,
-      precinctWidthInSubband: precinctWidthInSubband,
-      precinctHeightInSubband: precinctHeightInSubband
+      precinctWidth,
+      precinctHeight,
+      numprecinctswide,
+      numprecinctshigh,
+      numprecincts,
+      precinctWidthInSubband,
+      precinctHeightInSubband
     };
   }
   function buildCodeblocks(context, subband, dimensions) {
     var xcb_ = dimensions.xcb_;
     var ycb_ = dimensions.ycb_;
     var codeblockWidth = 1 << xcb_;
     var codeblockHeight = 1 << ycb_;
     var cbx0 = subband.tbx0 >> xcb_;
@@ -19833,17 +19832,17 @@ var JpxImage = function JpxImageClosure(
         var codeblock = codeblocks[j];
         if (codeblock.precinctNumber !== precinctNumber) {
           continue;
         }
         precinctCodeblocks.push(codeblock);
       }
     }
     return {
-      layerNumber: layerNumber,
+      layerNumber,
       codeblocks: precinctCodeblocks
     };
   }
   function LayerResolutionComponentPositionIterator(context) {
     var siz = context.SIZ;
     var tileIndex = context.currentTile.index;
     var tile = context.tiles[tileIndex];
     var layersCount = tile.codingStyleDefaultParameters.layersCount;
@@ -20104,20 +20103,20 @@ var JpxImage = function JpxImageClosure(
         minWidth: minWidthCurrentComponent,
         minHeight: minHeightCurrentComponent,
         maxNumWide: maxNumWideCurrentComponent,
         maxNumHigh: maxNumHighCurrentComponent
       };
     }
     return {
       components: sizePerComponent,
-      minWidth: minWidth,
-      minHeight: minHeight,
-      maxNumWide: maxNumWide,
-      maxNumHigh: maxNumHigh
+      minWidth,
+      minHeight,
+      maxNumWide,
+      maxNumHigh
     };
   }
   function buildPackets(context) {
     var siz = context.SIZ;
     var tileIndex = context.currentTile.index;
     var tile = context.tiles[tileIndex];
     var componentsCount = siz.Csiz;
     for (var c = 0; c < componentsCount; c++) {
@@ -20347,33 +20346,33 @@ var JpxImage = function JpxImageClosure(
         var codingpasses = readCodingpasses();
         while (readBits(1)) {
           codeblock.Lblock++;
         }
         var codingpassesLog2 = log2(codingpasses);
         var bits = (codingpasses < 1 << codingpassesLog2 ? codingpassesLog2 - 1 : codingpassesLog2) + codeblock.Lblock;
         var codedDataLength = readBits(bits);
         queue.push({
-          codeblock: codeblock,
-          codingpasses: codingpasses,
+          codeblock,
+          codingpasses,
           dataLength: codedDataLength
         });
       }
       alignToByte();
       if (ephMarkerUsed) {
         skipMarkerIfEqual(0x92);
       }
       while (queue.length > 0) {
         var packetItem = queue.shift();
         codeblock = packetItem.codeblock;
         if (codeblock['data'] === undefined) {
           codeblock.data = [];
         }
         codeblock.data.push({
-          data: data,
+          data,
           start: offset + position,
           end: offset + position + packetItem.dataLength,
           codingpasses: packetItem.codingpasses
         });
         position += packetItem.dataLength;
       }
     }
     return position;
@@ -20498,18 +20497,18 @@ var JpxImage = function JpxImageClosure(
         }
         var subband = resolution.subbands[j];
         var gainLog2 = SubbandsGainLog2[subband.type];
         var delta = reversible ? 1 : Math.pow(2, precision + gainLog2 - epsilon) * (1 + mu / 2048);
         var mb = guardBits + epsilon - 1;
         copyCoefficients(coefficients, width, height, subband, delta, mb, reversible, segmentationSymbolUsed);
       }
       subbandCoefficients.push({
-        width: width,
-        height: height,
+        width,
+        height,
         items: coefficients
       });
     }
     var result = transform.calculate(subbandCoefficients, component.tcx0, component.tcy0);
     return {
       left: component.tcx0,
       top: component.tcy0,
       width: result.width,
@@ -20627,18 +20626,18 @@ var JpxImage = function JpxImageClosure(
     tile.codingStyleDefaultParameters = context.currentTile.COD;
   }
   var TagTree = function TagTreeClosure() {
     function TagTree(width, height) {
       var levelsLength = log2(Math.max(width, height)) + 1;
       this.levels = [];
       for (var i = 0; i < levelsLength; i++) {
         var level = {
-          width: width,
-          height: height,
+          width,
+          height,
           items: []
         };
         this.levels.push(level);
         width = Math.ceil(width / 2);
         height = Math.ceil(height / 2);
       }
     }
     TagTree.prototype = {
@@ -20690,19 +20689,19 @@ var JpxImage = function JpxImageClosure(
       var levelsLength = log2(Math.max(width, height)) + 1;
       this.levels = [];
       for (var i = 0; i < levelsLength; i++) {
         var items = new Uint8Array(width * height);
         for (var j = 0, jj = items.length; j < jj; j++) {
           items[j] = defaultValue;
         }
         var level = {
-          width: width,
-          height: height,
-          items: items
+          width,
+          height,
+          items
         };
         this.levels.push(level);
         width = Math.ceil(width / 2);
         height = Math.ceil(height / 2);
       }
     }
     InclusionTree.prototype = {
       reset: function InclusionTree_reset(i, j, stopValue) {
@@ -21120,19 +21119,19 @@ var JpxImage = function JpxImageClosure(
               for (b = 0; b < numBuffers; b++) {
                 items[k + b] = colBuffers[b][l];
               }
             }
           }
         }
       }
       return {
-        width: width,
-        height: height,
-        items: items
+        width,
+        height,
+        items
       };
     };
     return Transform;
   }();
   var IrreversibleTransform = function IrreversibleTransformClosure() {
     function IrreversibleTransform() {
       Transform.call(this);
     }
@@ -21336,17 +21335,17 @@ var Catalog = function CatalogClosure() 
         return null;
       }
       obj = obj.getRaw('First');
       if (!isRef(obj)) {
         return null;
       }
       var root = { items: [] };
       var queue = [{
-        obj: obj,
+        obj,
         parent: root
       }];
       var processed = new RefSet();
       processed.put(obj);
       var xref = this.xref,
           blackColor = new Uint8Array(3);
       while (queue.length > 0) {
         var i = queue.shift();
@@ -21382,25 +21381,25 @@ var Catalog = function CatalogClosure() 
           bold: !!(flags & 2),
           italic: !!(flags & 1),
           items: []
         };
         i.parent.items.push(outlineItem);
         obj = outlineDict.getRaw('First');
         if (isRef(obj) && !processed.has(obj)) {
           queue.push({
-            obj: obj,
+            obj,
             parent: outlineItem
           });
           processed.put(obj);
         }
         obj = outlineDict.getRaw('Next');
         if (isRef(obj) && !processed.has(obj)) {
           queue.push({
-            obj: obj,
+            obj,
             parent: i.parent
           });
           processed.put(obj);
         }
       }
       return root.items.length > 0 ? root.items : null;
     },
     get numPages() {
@@ -21987,17 +21986,17 @@ var XRef = function XRefClosure() {
         var streamParameters = stream.dict;
         var byteWidths = streamParameters.get('W');
         var range = streamParameters.get('Index');
         if (!range) {
           range = [0, streamParameters.get('Size')];
         }
         this.streamState = {
           entryRanges: range,
-          byteWidths: byteWidths,
+          byteWidths,
           entryNum: 0,
           streamPos: stream.pos
         };
       }
       this.readXRefStream(stream);
       delete this.streamState;
       return stream.dict;
     },
@@ -23367,23 +23366,23 @@ var WorkerTask = function WorkerTaskClos
     this.name = name;
     this.terminated = false;
     this._capability = createPromiseCapability();
   }
   WorkerTask.prototype = {
     get finished() {
       return this._capability.promise;
     },
-    finish: function () {
+    finish() {
       this._capability.resolve();
     },
-    terminate: function () {
+    terminate() {
       this.terminated = true;
     },
-    ensureNotTerminated: function () {
+    ensureNotTerminated() {
       if (this.terminated) {
         throw new Error('Worker task was terminated');
       }
     }
   };
   return WorkerTask;
 }();
 var PDFWorkerStream = function PDFWorkerStreamClosure() {
@@ -23439,18 +23438,18 @@ var PDFWorkerStream = function PDFWorker
       assert(!this._fullRequestReader);
       var queuedChunks = this._queuedChunks;
       this._queuedChunks = null;
       return new PDFWorkerStreamReader(this, queuedChunks);
     },
     getRangeReader: function PDFWorkerStream_getRangeReader(begin, end) {
       var reader = new PDFWorkerStreamRangeReader(this, begin, end);
       this._msgHandler.send('RequestDataRange', {
-        begin: begin,
-        end: end
+        begin,
+        end
       });
       this._rangeReaders.push(reader);
       return reader;
     },
     cancelAllRequests: function PDFWorkerStream_cancelAllRequests(reason) {
       if (this._fullRequestReader) {
         this._fullRequestReader.cancel(reason);
       }
@@ -23618,17 +23617,17 @@ var WorkerMessageHandler = {
         responseExists = false;
       }
       if (!responseExists) {
         handler.send('test', false);
         return;
       }
       handler.send('test', {
         supportTypedArray: true,
-        supportTransfers: supportTransfers
+        supportTransfers
       });
     });
     handler.on('configure', function wphConfigure(data) {
       setVerbosityLevel(data.verbosity);
     });
     handler.on('GetDocRequest', function wphSetupDoc(data) {
       return WorkerMessageHandler.createDocumentHandler(data, port);
     });
@@ -23720,17 +23719,17 @@ var WorkerMessageHandler = {
           return;
         }
         var disableAutoFetch = source.disableAutoFetch || fullRequest.isStreamingSupported;
         pdfManager = new NetworkPdfManager(docId, pdfStream, {
           msgHandler: handler,
           url: source.url,
           password: source.password,
           length: fullRequest.contentLength,
-          disableAutoFetch: disableAutoFetch,
+          disableAutoFetch,
           rangeChunkSize: source.rangeChunkSize
         }, evaluatorOptions, docBaseUrl);
         pdfManagerCapability.resolve(pdfManager);
         cancelXHRs = null;
       }).catch(function (reason) {
         pdfManagerCapability.reject(reason);
         cancelXHRs = null;
       });
@@ -23759,17 +23758,17 @@ var WorkerMessageHandler = {
               }
               cancelXHRs = null;
               return;
             }
             var data = chunk.value;
             loaded += arrayByteLength(data);
             if (!fullRequest.isStreamingSupported) {
               handler.send('DocProgress', {
-                loaded: loaded,
+                loaded,
                 total: Math.max(loaded, fullRequest.contentLength || 0)
               });
             }
             if (pdfManager) {
               pdfManager.sendProgressiveData(data);
             } else {
               cachedChunks.push(data);
             }
@@ -23937,17 +23936,17 @@ var WorkerMessageHandler = {
             };
           } else {
             wrappedException = {
               message: 'Unknown exception type: ' + typeof e,
               stack: minimumStackMessage
             };
           }
           handler.send('PageError', {
-            pageNum: pageNum,
+            pageNum,
             error: wrappedException,
             intent: data.intent
           });
         });
       });
     }, this);
     handler.on('GetTextContent', function wphExtractText(data) {
       var pageIndex = data.pageIndex;
@@ -24069,22 +24068,22 @@ AnnotationFactory.prototype = {
     var dict = xref.fetchIfRef(ref);
     if (!isDict(dict)) {
       return;
     }
     var id = isRef(ref) ? ref.toString() : 'annot_' + idFactory.createObjId();
     var subtype = dict.get('Subtype');
     subtype = isName(subtype) ? subtype.name : null;
     var parameters = {
-      xref: xref,
-      dict: dict,
+      xref,
+      dict,
       ref: isRef(ref) ? ref : null,
-      subtype: subtype,
-      id: id,
-      pdfManager: pdfManager
+      subtype,
+      id,
+      pdfManager
     };
     switch (subtype) {
       case 'Link':
         return new LinkAnnotation(parameters);
       case 'Text':
         return new TextAnnotation(parameters);
       case 'Widget':
         var fieldType = Util.getInheritableProperty(dict, 'FT');
@@ -24714,17 +24713,17 @@ function reverseValues(arr, start, end) 
   for (var i = start, j = end - 1; i < j; ++i, --j) {
     var temp = arr[i];
     arr[i] = arr[j];
     arr[j] = temp;
   }
 }
 function createBidiText(str, isLTR, vertical) {
   return {
-    str: str,
+    str,
     dir: vertical ? 'ttb' : isLTR ? 'ltr' : 'rtl'
   };
 }
 var chars = [];
 var types = [];
 function bidi(str, startLevel, vertical) {
   var isLTR = true;
   var strLength = str.length;
@@ -24966,72 +24965,72 @@ var CMap = function CMapClosure() {
     this.numCodespaceRanges = 0;
     this._map = [];
     this.name = '';
     this.vertical = false;
     this.useCMap = null;
     this.builtInCMap = builtInCMap;
   }
   CMap.prototype = {
-    addCodespaceRange: function (n, low, high) {
+    addCodespaceRange(n, low, high) {
       this.codespaceRanges[n - 1].push(low, high);
       this.numCodespaceRanges++;
     },
-    mapCidRange: function (low, high, dstLow) {
+    mapCidRange(low, high, dstLow) {
       while (low <= high) {
         this._map[low++] = dstLow++;
       }
     },
-    mapBfRange: function (low, high, dstLow) {
+    mapBfRange(low, high, dstLow) {
       var lastByte = dstLow.length - 1;
       while (low <= high) {
         this._map[low++] = dstLow;
         dstLow = dstLow.substr(0, lastByte) + String.fromCharCode(dstLow.charCodeAt(lastByte) + 1);
       }
     },
-    mapBfRangeToArray: function (low, high, array) {
+    mapBfRangeToArray(low, high, array) {
       var i = 0,
           ii = array.length;
       while (low <= high && i < ii) {
         this._map[low] = array[i++];
         ++low;
       }
     },
-    mapOne: function (src, dst) {
+    mapOne(src, dst) {
       this._map[src] = dst;
     },
-    lookup: function (code) {
+    lookup(code) {
       return this._map[code];
     },
-    contains: function (code) {
+    contains(code) {
       return this._map[code] !== undefined;
     },
-    forEach: function (callback) {
+    forEach(callback) {
       var map = this._map;
       var length = map.length;
       var i;
       if (length <= 0x10000) {
         for (i = 0; i < length; i++) {
           if (map[i] !== undefined) {
             callback(i, map[i]);
           }
         }
       } else {
         for (i in this._map) {
           callback(i, map[i]);
         }
       }
     },
-    charCodeOf: function (value) {
+    charCodeOf(value) {
       return this._map.indexOf(value);
     },
-    getMap: function () {
+    getMap() {
       return this._map;
     },
-    readCharCode: function (str, offset, out) {
+    readCharCode(str, offset, out) {
       var c = 0;
       var codespaceRanges = this.codespaceRanges;
       var codespaceRangesLen = this.codespaceRanges.length;
       for (var n = 0; n < codespaceRangesLen; n++) {
         c = (c << 8 | str.charCodeAt(offset + n)) >>> 0;
         var codespaceRange = codespaceRanges[n];
         for (var k = 0, kk = codespaceRange.length; k < kk;) {
           var low = codespaceRange[k++];
@@ -25070,43 +25069,43 @@ var IdentityCMap = function IdentityCMap
   function IdentityCMap(vertical, n) {
     CMap.call(this);
     this.vertical = vertical;
     this.addCodespaceRange(n, 0, 0xffff);
   }
   Util.inherit(IdentityCMap, CMap, {});
   IdentityCMap.prototype = {
     addCodespaceRange: CMap.prototype.addCodespaceRange,
-    mapCidRange: function (low, high, dstLow) {
+    mapCidRange(low, high, dstLow) {
       error('should not call mapCidRange');
     },
-    mapBfRange: function (low, high, dstLow) {
+    mapBfRange(low, high, dstLow) {
       error('should not call mapBfRange');
     },
-    mapBfRangeToArray: function (low, high, array) {
+    mapBfRangeToArray(low, high, array) {
       error('should not call mapBfRangeToArray');
     },
-    mapOne: function (src, dst) {
+    mapOne(src, dst) {
       error('should not call mapCidOne');
     },
-    lookup: function (code) {
+    lookup(code) {
       return isInt(code) && code <= 0xffff ? code : undefined;
     },
-    contains: function (code) {
+    contains(code) {
       return isInt(code) && code <= 0xffff;
     },
-    forEach: function (callback) {
+    forEach(callback) {
       for (var i = 0; i <= 0xffff; i++) {
         callback(i, i);
       }
     },
-    charCodeOf: function (value) {
+    charCodeOf(value) {
       return isInt(value) && value <= 0xffff ? value : -1;
     },
-    getMap: function () {
+    getMap() {
       var map = new Array(0x10000);
       for (var i = 0; i <= 0xffff; i++) {
         map[i] = i;
       }
       return map;
     },
     readCharCode: CMap.prototype.readCharCode,
     get length() {
@@ -25155,44 +25154,44 @@ var BinaryCMapReader = function BinaryCM
   var MAX_ENCODED_NUM_SIZE = 19;
   function BinaryCMapStream(data) {
     this.buffer = data;
     this.pos = 0;
     this.end = data.length;
     this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE);
   }
   BinaryCMapStream.prototype = {
-    readByte: function () {
+    readByte() {
       if (this.pos >= this.end) {
         return -1;
       }
       return this.buffer[this.pos++];
     },
-    readNumber: function () {
+    readNumber() {
       var n = 0;
       var last;
       do {
         var b = this.readByte();
         if (b < 0) {
           error('unexpected EOF in bcmap');
         }
         last = !(b & 0x80);
         n = n << 7 | b & 0x7F;
       } while (!last);
       return n;
     },
-    readSigned: function () {
+    readSigned() {
       var n = this.readNumber();
       return n & 1 ? ~(n >>> 1) : n >>> 1;
     },
-    readHex: function (num, size) {
+    readHex(num, size) {
       num.set(this.buffer.subarray(this.pos, this.pos + size + 1));
       this.pos += size + 1;
     },
-    readHexNumber: function (num, size) {
+    readHexNumber(num, size) {
       var last;
       var stack = this.tmpBuf,
           sp = 0;
       do {
         var b = this.readByte();
         if (b < 0) {
           error('unexpected EOF in bcmap');
         }
@@ -25208,26 +25207,26 @@ var BinaryCMapReader = function BinaryCM
           bufferSize += 7;
         }
         num[i] = buffer & 255;
         i--;
         buffer >>= 8;
         bufferSize -= 8;
       }
     },
-    readHexSigned: function (num, size) {
+    readHexSigned(num, size) {
       this.readHexNumber(num, size);
       var sign = num[size] & 1 ? 255 : 0;
       var c = 0;
       for (var i = 0; i <= size; i++) {
         c = (c & 1) << 8 | num[i];
         num[i] = c >> 1 ^ sign;
       }
     },
-    readString: function () {
+    readString() {
       var len = this.readNumber();
       var s = '';
       for (var i = 0; i < len; i++) {
         s += String.fromCharCode(this.readNumber());
       }
       return s;
     }
   };
@@ -25611,17 +25610,17 @@ var CMapFactory = function CMapFactoryCl
         });
       }
       assert(compressionType === CMapCompressionType.NONE, 'TODO: Only BINARY/NONE CMap compression is currently supported.');
       var lexer = new Lexer(new Stream(cMapData));
       return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
     });
   }
   return {
-    create: function (params) {
+    create(params) {
       var encoding = params.encoding;
       var fetchBuiltInCMap = params.fetchBuiltInCMap;
       var useCMap = params.useCMap;
       if (isName(encoding)) {
         return createBuiltInCMap(encoding.name, fetchBuiltInCMap);
       } else if (isStream(encoding)) {
         var cMap = new CMap();
         var lexer = new Lexer(encoding);
@@ -25699,17 +25698,17 @@ var Page = function PageClosure() {
     this.ref = ref;
     this.fontCache = fontCache;
     this.builtInCMapCache = builtInCMapCache;
     this.evaluatorOptions = pdfManager.evaluatorOptions;
     this.resourcesPromise = null;
     var uniquePrefix = 'p' + this.pageIndex + '_';
     var idCounters = { obj: 0 };
     this.idFactory = {
-      createObjId: function () {
+      createObjId() {
         return uniquePrefix + ++idCounters.obj;
       }
     };
   }
   Page.prototype = {
     getPageProp: function Page_getPageProp(key) {
       return this.pageDict.get(key);
     },
@@ -25824,17 +25823,17 @@ var Page = function PageClosure() {
       var partialEvaluator = new PartialEvaluator(pdfManager, this.xref, handler, this.pageIndex, this.idFactory, this.fontCache, this.builtInCMapCache, this.evaluatorOptions);
       var dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
       var pageListPromise = dataPromises.then(function (data) {
         var contentStream = data[0];
         var opList = new OperatorList(intent, handler, self.pageIndex);
         handler.send('StartRenderPage', {
           transparency: partialEvaluator.hasBlendModes(self.resources),
           pageIndex: self.pageIndex,
-          intent: intent
+          intent
         });
         return partialEvaluator.getOperatorList(contentStream, task, self.resources, opList).then(function () {
           return opList;
         });
       });
       var annotationsPromise = pdfManager.ensure(this, 'annotations');
       return Promise.all([pageListPromise, annotationsPromise]).then(function (datas) {
         var pageOpList = datas[0];
@@ -26058,20 +26057,19 @@ var PDFDocument = function PDFDocumentCl
       }
     },
     parseStartXRef: function PDFDocument_parseStartXRef() {
       var startXRef = this.startXRef;
       this.xref.setStartXRef(startXRef);
     },
     setup: function PDFDocument_setup(recoveryMode) {
       this.xref.parse(recoveryMode);
-      var self = this;
       var pageFactory = {
-        createPage: function (pageIndex, dict, ref, fontCache, builtInCMapCache) {
-          return new Page(self.pdfManager, self.xref, pageIndex, dict, ref, fontCache, builtInCMapCache);
+        createPage: (pageIndex, dict, ref, fontCache, builtInCMapCache) => {
+          return new Page(this.pdfManager, this.xref, pageIndex, dict, ref, fontCache, builtInCMapCache);
         }
       };
       this.catalog = new Catalog(this.pdfManager, this.xref, pageFactory);
     },
     get numPages() {
       var linearization = this.linearization;
       var num = linearization ? linearization.numPages : this.catalog.numPages;
       return shadow(this, 'numPages', num);
@@ -26352,17 +26350,17 @@ var FontRendererFactory = function FontR
       var points = [];
       while (points.length < numberOfPoints) {
         flags = code[i++];
         var repeat = 1;
         if (flags & 0x08) {
           repeat += code[i++];
         }
         while (repeat-- > 0) {
-          points.push({ flags: flags });
+          points.push({ flags });
         }
       }
       for (j = 0; j < numberOfPoints; j++) {
         switch (points[j].flags & 0x12) {
           case 0x00:
             x += (code[i] << 24 | code[i + 1] << 16) >> 16;
             i += 2;
             break;
@@ -26766,29 +26764,29 @@ var FontRendererFactory = function FontR
   }
   var noop = '';
   function CompiledFont(fontMatrix) {
     this.compiledGlyphs = Object.create(null);
     this.compiledCharCodeToGlyphId = Object.create(null);
     this.fontMatrix = fontMatrix;
   }
   CompiledFont.prototype = {
-    getPathJs: function (unicode) {
+    getPathJs(unicode) {
       var cmap = lookupCmap(this.cmap, unicode);
       var fn = this.compiledGlyphs[cmap.glyphId];
       if (!fn) {
         fn = this.compileGlyph(this.glyphs[cmap.glyphId]);
         this.compiledGlyphs[cmap.glyphId] = fn;
       }
       if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) {
         this.compiledCharCodeToGlyphId[cmap.charCode] = cmap.glyphId;
       }
       return fn;
     },
-    compileGlyph: function (code) {
+    compileGlyph(code) {
       if (!code || code.length === 0 || code[0] === 14) {
         return noop;
       }
       var cmds = [];
       cmds.push({ cmd: 'save' });
       cmds.push({
         cmd: 'transform',
         args: this.fontMatrix.slice()
@@ -26796,48 +26794,48 @@ var FontRendererFactory = function FontR
       cmds.push({
         cmd: 'scale',
         args: ['size', '-size']
       });
       this.compileGlyphImpl(code, cmds);
       cmds.push({ cmd: 'restore' });
       return cmds;
     },
-    compileGlyphImpl: function () {
+    compileGlyphImpl() {
       error('Children classes should implement this.');
     },
-    hasBuiltPath: function (unicode) {
+    hasBuiltPath(unicode) {
       var cmap = lookupCmap(this.cmap, unicode);
       return this.compiledGlyphs[cmap.glyphId] !== undefined && this.compiledCharCodeToGlyphId[cmap.charCode] !== undefined;
     }
   };
   function TrueTypeCompiled(glyphs, cmap, fontMatrix) {
     fontMatrix = fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0];
     CompiledFont.call(this, fontMatrix);
     this.glyphs = glyphs;
     this.cmap = cmap;
   }
   Util.inherit(TrueTypeCompiled, CompiledFont, {
-    compileGlyphImpl: function (code, cmds) {
+    compileGlyphImpl(code, cmds) {
       compileGlyf(code, cmds, this);
     }
   });
   function Type2Compiled(cffInfo, cmap, fontMatrix, glyphNameMap) {
     fontMatrix = fontMatrix || [0.001, 0, 0, 0.001, 0, 0];
     CompiledFont.call(this, fontMatrix);
     this.glyphs = cffInfo.glyphs;
     this.gsubrs = cffInfo.gsubrs || [];
     this.subrs = cffInfo.subrs || [];
     this.cmap = cmap;
     this.glyphNameMap = glyphNameMap || getGlyphsUnicode();
     this.gsubrsBias = this.gsubrs.length < 1240 ? 107 : this.gsubrs.length < 33900 ? 1131 : 32768;
     this.subrsBias = this.subrs.length < 1240 ? 107 : this.subrs.length < 33900 ? 1131 : 32768;
   }
   Util.inherit(Type2Compiled, CompiledFont, {
-    compileGlyphImpl: function (code, cmds) {
+    compileGlyphImpl(code, cmds) {
       compileCharString(code, cmds, this);
     }
   });
   return {
     create: function FontRendererFactory_create(font, seacAnalysisEnabled) {
       var data = new Uint8Array(font.data);
       var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
       var numTables = getUshort(data, 4);
@@ -27042,65 +27040,65 @@ var Glyph = function GlyphClosure() {
 var ToUnicodeMap = function ToUnicodeMapClosure() {
   function ToUnicodeMap(cmap) {
     this._map = cmap;
   }
   ToUnicodeMap.prototype = {
     get length() {
       return this._map.length;
     },
-    forEach: function (callback) {
+    forEach(callback) {
       for (var charCode in this._map) {
         callback(charCode, this._map[charCode].charCodeAt(0));
       }
     },
-    has: function (i) {
+    has(i) {
       return this._map[i] !== undefined;
     },
-    get: function (i) {
+    get(i) {
       return this._map[i];
     },
-    charCodeOf: function (v) {
+    charCodeOf(v) {
       return this._map.indexOf(v);
     },
-    amend: function (map) {
+    amend(map) {
       for (var charCode in map) {
         this._map[charCode] = map[charCode];
       }
     }
   };
   return ToUnicodeMap;
 }();
 var IdentityToUnicodeMap = function IdentityToUnicodeMapClosure() {
   function IdentityToUnicodeMap(firstChar, lastChar) {
     this.firstChar = firstChar;
     this.lastChar = lastChar;
   }
   IdentityToUnicodeMap.prototype = {
     get length() {
       return this.lastChar + 1 - this.firstChar;
     },
-    forEach: function (callback) {
+    forEach(callback) {
       for (var i = this.firstChar, ii = this.lastChar; i <= ii; i++) {
         callback(i, i);
       }
     },
-    has: function (i) {
+    has(i) {
       return this.firstChar <= i && i <= this.lastChar;
     },
-    get: function (i) {
+    get(i) {
       if (this.firstChar <= i && i <= this.lastChar) {
         return String.fromCharCode(i);
       }
       return undefined;
     },
-    charCodeOf: function (v) {
+    charCodeOf(v) {
       return isInt(v) && v >= this.firstChar && v <= this.lastChar ? v : -1;
     },
-    amend: function (map) {
+    amend(map) {
       error('Should not call amend()');
     }
   };
   return IdentityToUnicodeMap;
 }();
 var OpenTypeFileBuilder = function OpenTypeFileBuilderClosure() {
   function writeInt16(dest, offset, num) {
     dest[offset] = num >> 8 & 0xFF;
@@ -27472,19 +27470,19 @@ var Font = function FontClosure() {
           }
         } while (usedFontCharCodes[fontCharCode] !== undefined && nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END);
       }
       newMap[fontCharCode] = glyphId;
       toFontChar[originalCharCode] = fontCharCode;
       usedFontCharCodes[fontCharCode] = true;
     }
     return {
-      toFontChar: toFontChar,
+      toFontChar,
       charCodeToGlyphId: newMap,
-      nextAvailableFontCharCode: nextAvailableFontCharCode
+      nextAvailableFontCharCode
     };
   }
   function getRanges(glyphs, numGlyphs) {
     var codes = [];
     for (var charCode in glyphs) {
       if (glyphs[charCode] >= numGlyphs) {
         continue;
       }
@@ -27738,21 +27736,21 @@ var Font = function FontClosure() {
         file.skip(offset);
         var data = file.getBytes(length);
         file.pos = previousPosition;
         if (tag === 'head') {
           data[8] = data[9] = data[10] = data[11] = 0;
           data[17] |= 0x20;
         }
         return {
-          tag: tag,
-          checksum: checksum,
-          length: length,
-          offset: offset,
-          data: data
+          tag,
+          checksum,
+          length,
+          offset,
+          data
         };
       }
       function readOpenTypeHeader(ttf) {
         return {
           version: bytesToString(ttf.getBytes(4)),
           numTables: ttf.getUint16(),
           searchRange: ttf.getUint16(),
           entrySelector: ttf.getUint16(),
@@ -27791,19 +27789,19 @@ var Font = function FontClosure() {
               canBreak = true;
             }
           } else if (isSymbolicFont && platformId === 3 && encodingId === 0) {
             useTable = true;
             canBreak = true;
           }
           if (useTable) {
             potentialTable = {
-              platformId: platformId,
-              encodingId: encodingId,
-              offset: offset
+              platformId,
+              encodingId,
+              offset
             };
           }
           if (canBreak) {
             break;
           }
         }
         if (potentialTable) {
           font.pos = start + potentialTable.offset;
@@ -27875,29 +27873,29 @@ var Font = function FontClosure() {
             for (j = start; j <= end; j++) {
               if (j === 0xFFFF) {
                 continue;
               }
               glyphId = offsetIndex < 0 ? j : offsets[offsetIndex + j - start];
               glyphId = glyphId + delta & 0xFFFF;
               mappings.push({
                 charCode: j,
-                glyphId: glyphId
+                glyphId
               });
             }
           }
         } else if (format === 6) {
           var firstCode = font.getUint16();
           var entryCount = font.getUint16();
           for (j = 0; j < entryCount; j++) {
             glyphId = font.getUint16();
             var charCode = firstCode + j;
             mappings.push({
-              charCode: charCode,
-              glyphId: glyphId
+              charCode,
+              glyphId
             });
           }
         } else {
           warn('cmap table has unsupported format: ' + format);
           return {
             platformId: -1,
             encodingId: -1,
             mappings: [],
@@ -27911,18 +27909,18 @@ var Font = function FontClosure() {
           if (mappings[i - 1].charCode === mappings[i].charCode) {
             mappings.splice(i, 1);
             i--;
           }
         }
         return {
           platformId: potentialTable.platformId,
           encodingId: potentialTable.encodingId,
-          mappings: mappings,
-          hasShortCmap: hasShortCmap
+          mappings,
+          hasShortCmap
         };
       }
       function sanitizeMetrics(font, header, metrics, numGlyphs) {
         if (!header) {
           if (metrics) {
             metrics.data = null;
           }
           return;
@@ -28287,18 +28285,18 @@ var Font = function FontClosure() {
           } else if (op === 0x2B && !tooComplexToFollowFunctions) {
             if (!inFDEF && !inELSE) {
               funcId = stack[stack.length - 1];
               ttContext.functionsUsed[funcId] = true;
               if (funcId in ttContext.functionsStackDeltas) {
                 stack.length += ttContext.functionsStackDeltas[funcId];
               } else if (funcId in ttContext.functionsDefined && functionsCalled.indexOf(funcId) < 0) {
                 callstack.push({
-                  data: data,
-                  i: i,
+                  data,
+                  i,
                   stackTop: stack.length - 1
                 });
                 functionsCalled.push(funcId);
                 pc = ttContext.functionsDefined[funcId];
                 if (!pc) {
                   warn('TT: CALL non-existent function');
                   ttContext.hintsValid = false;
                   return;
@@ -28311,18 +28309,18 @@ var Font = function FontClosure() {
             if (inFDEF || inELSE) {
               warn('TT: nested FDEFs not allowed');
               tooComplexToFollowFunctions = true;
             }
             inFDEF = true;
             lastDeff = i;
             funcId = stack.pop();
             ttContext.functionsDefined[funcId] = {
-              data: data,
-              i: i
+              data,
+              i
             };
           } else if (op === 0x2D) {
             if (inFDEF) {
               inFDEF = false;
               lastEndf = i;
             } else {
               pc = callstack.pop();
               if (!pc) {
@@ -28772,19 +28770,19 @@ var Font = function FontClosure() {
             continue;
           }
           for (var i = 0, ii = charCodes.length; i < ii; i++) {
             var charCode = charCodes[i];
             var charCodeToGlyphId = newMapping.charCodeToGlyphId;
             var baseFontCharCode = createCharCode(charCodeToGlyphId, baseGlyphId);
             var accentFontCharCode = createCharCode(charCodeToGlyphId, accentGlyphId);
             seacMap[charCode] = {
-              baseFontCharCode: baseFontCharCode,
-              accentFontCharCode: accentFontCharCode,
-              accentOffset: accentOffset
+              baseFontCharCode,
+              accentFontCharCode,
+              accentOffset
             };
           }
         }
         properties.seacMap = seacMap;
       }
       var unitsPerEm = 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0];
       var builder = new OpenTypeFileBuilder('\x4F\x54\x54\x4F');
       builder.addTable('CFF ', font.data);
@@ -29014,17 +29012,17 @@ var Type1Font = function Type1FontClosur
           i++;
         }
         found = true;
         break;
       }
       i++;
     }
     return {
-      found: found,
+      found,
       length: i
     };
   }
   function getHeaderBlock(stream, suggestedLength) {
     var EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63];
     var streamStartPos = stream.pos;
     var headerBytes, headerBytesLength, block;
     try {
@@ -29521,19 +29519,19 @@ var PDFImage = function PDFImageClosure(
       }
     }
     if (inverseDecode) {
       for (i = 0; i < actualLength; i++) {
         data[i] = ~data[i];
       }
     }
     return {
-      data: data,
-      width: width,
-      height: height
+      data,
+      width,
+      height
     };
   };
   PDFImage.prototype = {
     get drawWidth() {
       return Math.max(this.width, this.smask && this.smask.width || 0, this.mask && this.mask.width || 0);
     },
     get drawHeight() {
       return Math.max(this.height, this.smask && this.smask.height || 0, this.mask && this.mask.height || 0);
@@ -29835,17 +29833,17 @@ var log2 = sharedUtil.log2;
 var readInt8 = sharedUtil.readInt8;
 var readUint16 = sharedUtil.readUint16;
 var readUint32 = sharedUtil.readUint32;
 var shadow = sharedUtil.shadow;
 var ArithmeticDecoder = coreArithmeticDecoder.ArithmeticDecoder;
 var Jbig2Image = function Jbig2ImageClosure() {
   function ContextCache() {}
   ContextCache.prototype = {
-    getContexts: function (id) {
+    getContexts(id) {
       if (id in this) {
         return this[id];
       }
       return this[id] = new Int8Array(1 << 16);
     }
   };
   function DecodingContext(data, start, end) {
     this.data = data;
@@ -30270,18 +30268,18 @@ var Jbig2Image = function Jbig2ImageClos
           j0 = j + codingTemplateX[k];
           if (i0 < 0 || j0 < 0 || j0 >= width) {
             contextLabel <<= 1;
           } else {
             contextLabel = contextLabel << 1 | bitmap[i0][j0];
           }
         }
         for (k = 0; k < referenceTemplateLength; k++) {
-          i0 = i + referenceTemplateY[k] + offsetY;
-          j0 = j + referenceTemplateX[k] + offsetX;
+          i0 = i + referenceTemplateY[k] - offsetY;
+          j0 = j + referenceTemplateX[k] - offsetX;
           if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth) {
             contextLabel <<= 1;
           } else {
             contextLabel = contextLabel << 1 | referenceBitmap[i0][j0];
           }
         }
         var pixel = decoder.readBit(contexts, contextLabel);
         row[j] = pixel;
@@ -30536,17 +30534,17 @@ var Jbig2Image = function Jbig2ImageClos
   function readSegments(header, data, start, end) {
     var segments = [];
     var position = start;
     while (position < end) {
       var segmentHeader = readSegmentHeader(data, position);
       position = segmentHeader.headerEnd;
       var segment = {
         header: segmentHeader,
-        data: data
+        data
       };
       if (!header.randomAccess) {
         segment.start = position;
         position += segmentHeader.length;
         segment.end = position;
       }
       segments.push(segment);
       if (segmentHeader.type === 51) {
@@ -31539,18 +31537,18 @@ var JpegImage = function JpegImageClosur
               if (maxH < h) {
                 maxH = h;
               }
               if (maxV < v) {
                 maxV = v;
               }
               var qId = data[offset + 2];
               l = frame.components.push({
-                h: h,
-                v: v,
+                h,
+                v,
                 quantizationId: qId,
                 quantizationTable: null
               });
               frame.componentIds[componentId] = l - 1;
               offset += 3;
             }
             frame.maxH = maxH;
             frame.maxV = maxV;
@@ -35150,17 +35148,17 @@ Shadings.Mesh = function MeshClosure() {
       ps.push(coords.length);
       coords.push(coord);
       colors.push(color);
     }
     mesh.figures.push({
       type: 'lattice',
       coords: new Int32Array(ps),
       colors: new Int32Array(ps),
-      verticesPerRow: verticesPerRow
+      verticesPerRow
     });
   }
   var MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3;
   var MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20;
   var TRIANGLE_DENSITY = 20;
   var getB = function getBClosure() {
     function buildB(count) {
       var lut = [];
@@ -35244,17 +35242,17 @@ Shadings.Mesh = function MeshClosure() {
     figureCoords[verticesPerRow * splitYBy] = pi[12];
     figureColors[verticesPerRow * splitYBy] = ci[2];
     figureCoords[verticesPerRow * splitYBy + splitXBy] = pi[15];
     figureColors[verticesPerRow * splitYBy + splitXBy] = ci[3];
     mesh.figures[index] = {
       type: 'lattice',
       coords: figureCoords,
       colors: figureColors,
-      verticesPerRow: verticesPerRow
+      verticesPerRow
     };
   }
   function decodeType6Shading(mesh, reader) {
     var coords = mesh.coords;
     var colors = mesh.colors;
     var ps = new Int32Array(16);
     var cs = new Int32Array(4);
     while (reader.hasData) {
@@ -35790,17 +35788,17 @@ var NetworkPdfManager = function Network
     },
     requestRange: function NetworkPdfManager_requestRange(begin, end) {
       return this.streamManager.requestRange(begin, end);
     },
     requestLoadedStream: function NetworkPdfManager_requestLoadedStream() {
       this.streamManager.requestAllChunks();
     },
     sendProgressiveData: function NetworkPdfManager_sendProgressiveData(chunk) {
-      this.streamManager.onReceiveData({ chunk: chunk });
+      this.streamManager.onReceiveData({ chunk });
     },
     onLoadedStream: function NetworkPdfManager_onLoadedStream() {
       return this.streamManager.onLoadedStream();
     },
     terminate: function NetworkPdfManager_terminate() {
       this.streamManager.abort();
     }
   });
@@ -36232,17 +36230,17 @@ var Type1CharString = function Type1Char
           value = -((value - 251) * 256) - encoded[++i] - 108;
         } else {
           value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;
         }
         this.stack.push(value);
       }
       return error;
     },
-    executeCommand: function (howManyArgs, command, keepStack) {
+    executeCommand(howManyArgs, command, keepStack) {
       var stackLength = this.stack.length;
       if (howManyArgs > stackLength) {
         return true;
       }
       var start = stackLength - howManyArgs;
       for (var i = start; i < stackLength; i++) {
         var value = this.stack[i];
         if (value === (value | 0)) {
@@ -36425,18 +36423,18 @@ var Type1Parser = function Type1ParserCl
               encoded = decrypt(data.getBytes(), CHAR_STRS_ENCRYPT_KEY, lenIV);
               stream.skip(length);
               this.nextChar();
               token = this.getToken();
               if (token === 'noaccess') {
                 this.getToken();
               }
               charstrings.push({
-                glyph: glyph,
-                encoded: encoded
+                glyph,
+                encoded
               });
             }
             break;
           case 'Subrs':
             this.readInt();
             this.getToken();
             while ((token = this.getToken()) === 'dup') {
               var index = this.readInt();
@@ -36560,18 +36558,18 @@ exports.Type1Parser = Type1Parser;
 
 /***/ }),
 /* 35 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '1.8.269';
-var pdfjsBuild = 'acdfc2d8';
+var pdfjsVersion = '1.8.290';
+var pdfjsBuild = '60c232bc';
 var pdfjsCoreWorker = __w_pdfjs_require__(17);
 ;
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 36 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
--- a/browser/extensions/pdfjs/content/web/debugger.js
+++ b/browser/extensions/pdfjs/content/web/debugger.js
@@ -454,24 +454,24 @@ var Stats = (function Stats() {
     return false;
   }
   return {
     // Properties/functions needed by PDFBug.
     id: 'Stats',
     name: 'Stats',
     panel: null,
     manager: null,
-    init: function init(pdfjsLib) {
+    init(pdfjsLib) {
       this.panel.setAttribute('style', 'padding: 5px;');
       pdfjsLib.PDFJS.enableStats = true;
     },
     enabled: false,
     active: false,
     // Stats specific functions.
-    add: function(pageNumber, stat) {
+    add(pageNumber, stat) {
       if (!stat) {
         return;
       }
       var statsIndex = getStatIndex(pageNumber);
       if (statsIndex !== false) {
         var b = stats[statsIndex];
         this.panel.removeChild(b.div);
         stats.splice(statsIndex, 1);
@@ -480,26 +480,26 @@ var Stats = (function Stats() {
       wrapper.className = 'stats';
       var title = document.createElement('div');
       title.className = 'title';
       title.textContent = 'Page: ' + pageNumber;
       var statsDiv = document.createElement('div');
       statsDiv.textContent = stat.toString();
       wrapper.appendChild(title);
       wrapper.appendChild(statsDiv);
-      stats.push({ pageNumber: pageNumber, div: wrapper });
+      stats.push({ pageNumber, div: wrapper, });
       stats.sort(function(a, b) {
         return a.pageNumber - b.pageNumber;
       });
       clear(this.panel);
       for (var i = 0, ii = stats.length; i < ii; ++i) {
         this.panel.appendChild(stats[i].div);
       }
     },
-    cleanup: function () {
+    cleanup() {
       stats = [];
       clear(this.panel);
     }
   };
 })();
 
 // Manages all the debugging tools.
 window.PDFBug = (function PDFBugClosure() {
@@ -508,17 +508,17 @@ window.PDFBug = (function PDFBugClosure(
   var activePanel = null;
 
   return {
     tools: [
       FontInspector,
       StepperManager,
       Stats
     ],
-    enable: function(ids) {
+    enable(ids) {
       var all = false, tools = this.tools;
       if (ids.length === 1 && ids[0] === 'all') {
         all = true;
       }
       for (var i = 0; i < tools.length; ++i) {
         var tool = tools[i];
         if (all || ids.indexOf(tool.id) !== -1) {
           tool.enabled = true;
@@ -530,17 +530,17 @@ window.PDFBug = (function PDFBugClosure(
           var indexA = ids.indexOf(a.id);
           indexA = indexA < 0 ? tools.length : indexA;
           var indexB = ids.indexOf(b.id);
           indexB = indexB < 0 ? tools.length : indexB;
           return indexA - indexB;
         });
       }
     },
-    init: function init(pdfjsLib, container) {
+    init(pdfjsLib, container) {
       /*
        * Basic Layout:
        * PDFBug
        *  Controls
        *  Panels
        *    Panel
        *    Panel
        *    ...
@@ -583,24 +583,24 @@ window.PDFBug = (function PDFBugClosure(
           panel.textContent = tool.name + ' is disabled. To enable add ' +
                               ' "' + tool.id + '" to the pdfBug parameter ' +
                               'and refresh (separate multiple by commas).';
         }
         buttons.push(panelButton);
       }
       this.selectPanel(0);
     },
-    cleanup: function cleanup() {
+    cleanup() {
       for (var i = 0, ii = this.tools.length; i < ii; i++) {
         if (this.tools[i].enabled) {
           this.tools[i].cleanup();
         }
       }
     },
-    selectPanel: function selectPanel(index) {
+    selectPanel(index) {
       if (typeof index !== 'number') {
         index = this.tools.indexOf(index);
       }
       if (index === activePanel) {
         return;
       }
       activePanel = index;
       var tools = this.tools;
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -286,34 +286,34 @@ function getVisibleElements(scrollEl, vi
       continue;
     }
     hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, currentHeight + viewHeight - bottom);
     percentHeight = (viewHeight - hiddenHeight) * 100 / viewHeight | 0;
     visible.push({
       id: view.id,
       x: currentWidth,
       y: currentHeight,
-      view: view,
+      view,
       percent: percentHeight
     });
   }
   var first = visible[0];
   var last = visible[visible.length - 1];
   if (sortByVisibility) {
     visible.sort(function (a, b) {
       var pc = a.percent - b.percent;
       if (Math.abs(pc) > 0.001) {
         return -pc;
       }
       return a.id - b.id;
     });
   }
   return {
-    first: first,
-    last: last,
+    first,
+    last,
     views: visible
   };
 }
 function noContextMenuHandler(e) {
   e.preventDefault();
 }
 function isDataSchema(url) {
   var i = 0,
@@ -807,21 +807,21 @@ var DEFAULT_SCALE_DELTA = 1.1;
 var DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
 function configure(PDFJS) {
   PDFJS.imageResourcesPath = './images/';
   PDFJS.workerSrc = '../build/pdf.worker.js';
   PDFJS.cMapUrl = '../web/cmaps/';
   PDFJS.cMapPacked = true;
 }
 var DefaultExternalServices = {
-  updateFindControlState: function (data) {},
-  initPassiveLoading: function (callbacks) {},
-  fallback: function (data, callback) {},
-  reportTelemetry: function (data) {},
-  createDownloadManager: function () {
+  updateFindControlState(data) {},
+  initPassiveLoading(callbacks) {},
+  fallback(data, callback) {},
+  reportTelemetry(data) {},
+  createDownloadManager() {
     throw new Error('Not implemented: createDownloadManager');
   },
   createPreferences() {
     throw new Error('Not implemented: createPreferences');
   },
   supportsIntegratedFind: false,
   supportsDocumentFonts: true,
   supportsDocumentColors: true,
@@ -882,17 +882,17 @@ var PDFViewerApplication = {
       this.bindEvents();
       this.bindWindowEvents();
       if (this.isViewerEmbedded && !_pdfjs.PDFJS.isExternalLinkTargetSet()) {
         _pdfjs.PDFJS.externalLinkTarget = _pdfjs.PDFJS.LinkTarget.TOP;
       }
       this.initialized = true;
     });
   },
-  _readPreferences: function () {
+  _readPreferences() {
     var { preferences, viewerPrefs } = this;
     return Promise.all([preferences.get('enableWebGL').then(function resolved(value) {
       _pdfjs.PDFJS.disableWebGL = !value;
     }), preferences.get('sidebarViewOnLoad').then(function resolved(value) {
       viewerPrefs['sidebarViewOnLoad'] = value;
     }), preferences.get('pdfBugEnabled').then(function resolved(value) {
       viewerPrefs['pdfBugEnabled'] = value;
     }), preferences.get('showPreviousViewOnLoad').then(function resolved(value) {
@@ -935,55 +935,55 @@ var PDFViewerApplication = {
     }), preferences.get('renderInteractiveForms').then(function resolved(value) {
       viewerPrefs['renderInteractiveForms'] = value;
     }), preferences.get('disablePageLabels').then(function resolved(value) {
       viewerPrefs['disablePageLabels'] = value;
     }), preferences.get('enablePrintAutoRotate').then(function resolved(value) {
       viewerPrefs['enablePrintAutoRotate'] = value;
     })]).catch(function (reason) {});
   },
-  _initializeViewerComponents: function () {
+  _initializeViewerComponents() {
     var self = this;
     var appConfig = this.appConfig;
     return new Promise((resolve, reject) => {
       var eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)();
-      self.eventBus = eventBus;
+      this.eventBus = eventBus;
       var pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
       pdfRenderingQueue.onIdle = self.cleanup.bind(self);
       self.pdfRenderingQueue = pdfRenderingQueue;
-      var pdfLinkService = new _pdf_link_service.PDFLinkService({ eventBus: eventBus });
+      var pdfLinkService = new _pdf_link_service.PDFLinkService({ eventBus });
       self.pdfLinkService = pdfLinkService;
       var downloadManager = self.externalServices.createDownloadManager();
       self.downloadManager = downloadManager;
       var container = appConfig.mainContainer;
       var viewer = appConfig.viewerContainer;
       self.pdfViewer = new _pdf_viewer.PDFViewer({
-        container: container,
-        viewer: viewer,
-        eventBus: eventBus,
+        container,
+        viewer,
+        eventBus,
         renderingQueue: pdfRenderingQueue,
         linkService: pdfLinkService,
-        downloadManager: downloadManager,
+        downloadManager,
         renderer: self.viewerPrefs['renderer'],
         enhanceTextSelection: self.viewerPrefs['enhanceTextSelection'],
         renderInteractiveForms: self.viewerPrefs['renderInteractiveForms'],
         enablePrintAutoRotate: self.viewerPrefs['enablePrintAutoRotate']
       });
       pdfRenderingQueue.setViewer(self.pdfViewer);
       pdfLinkService.setViewer(self.pdfViewer);
       var thumbnailContainer = appConfig.sidebar.thumbnailView;
       self.pdfThumbnailViewer = new _pdf_thumbnail_viewer.PDFThumbnailViewer({
         container: thumbnailContainer,
         renderingQueue: pdfRenderingQueue,
         linkService: pdfLinkService
       });
       pdfRenderingQueue.setThumbnailViewer(self.pdfThumbnailViewer);
       self.pdfHistory = new _pdf_history.PDFHistory({
         linkService: pdfLinkService,
-        eventBus: eventBus
+        eventBus
       });
       pdfLinkService.setHistory(self.pdfHistory);
       self.findController = new _pdf_find_controller.PDFFindController({ pdfViewer: self.pdfViewer });
       self.findController.onUpdateResultsCount = function (matchCount) {
         if (self.supportsIntegratedFind) {
           return;
         }
         self.findBar.updateResultsCount(matchCount);
@@ -1009,33 +1009,33 @@ var PDFViewerApplication = {
         eventBus,
         preferences: this.preferences
       });
       self.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties);
       self.toolbar = new _toolbar.Toolbar(appConfig.toolbar, container, eventBus);
       self.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
       if (self.supportsFullscreen) {
         self.pdfPresentationMode = new _pdf_presentation_mode.PDFPresentationMode({
-          container: container,
-          viewer: viewer,
+          container,
+          viewer,
           pdfViewer: self.pdfViewer,
-          eventBus: eventBus,
+          eventBus,
           contextMenuItems: appConfig.fullscreen
         });
       }
       self.passwordPrompt = new _password_prompt.PasswordPrompt(appConfig.passwordOverlay);
       self.pdfOutlineViewer = new _pdf_outline_viewer.PDFOutlineViewer({
         container: appConfig.sidebar.outlineView,
-        eventBus: eventBus,
+        eventBus,
         linkService: pdfLinkService
       });
       self.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({
         container: appConfig.sidebar.attachmentsView,
-        eventBus: eventBus,
-        downloadManager: downloadManager
+        eventBus,
+        downloadManager
       });
       var sidebarConfig = Object.create(appConfig.sidebar);
       sidebarConfig.pdfViewer = self.pdfViewer;
       sidebarConfig.pdfThumbnailViewer = self.pdfThumbnailViewer;
       sidebarConfig.pdfOutlineViewer = self.pdfOutlineViewer;
       sidebarConfig.eventBus = eventBus;
       self.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig);
       self.pdfSidebar.onToggled = self.forceRendering.bind(self);
@@ -1099,43 +1099,43 @@ var PDFViewerApplication = {
     var bar = new _ui_utils.ProgressBar('#loadingBar', {});
     return (0, _pdfjs.shadow)(this, 'loadingBar', bar);
   },
   get supportedMouseWheelZoomModifierKeys() {
     return this.externalServices.supportedMouseWheelZoomModifierKeys;
   },
   initPassiveLoading: function pdfViewInitPassiveLoading() {
     this.externalServices.initPassiveLoading({
-      onOpenWithTransport: function (url, length, transport) {
+      onOpenWithTransport(url, length, transport) {
         PDFViewerApplication.open(url, { range: transport });
         if (length) {
           PDFViewerApplication.pdfDocumentProperties.setFileSize(length);
         }
       },
-      onOpenWithData: function (data) {
+      onOpenWithData(data) {
         PDFViewerApplication.open(data);
       },
-      onOpenWithURL: function (url, length, originalURL) {
+      onOpenWithURL(url, length, originalURL) {
         var file = url,
             args = null;
         if (length !== undefined) {
-          args = { length: length };
+          args = { length };
         }
         if (originalURL !== undefined) {
           file = {
             file: url,
-            originalURL: originalURL
+            originalURL
           };
         }
         PDFViewerApplication.open(file, args);
       },
-      onError: function (e) {
-        PDFViewerApplication.error(_ui_utils.mozL10n.get('loading_error', null, 'An error occurred while loading the PDF.'), e);
+      onError(err) {
+        PDFViewerApplication.error(_ui_utils.mozL10n.get('loading_error', null, 'An error occurred while loading the PDF.'), err);
       },
-      onProgress: function (loaded, total) {
+      onProgress(loaded, total) {
         PDFViewerApplication.progress(loaded / total);
       }
     });
   },
   setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
     this.url = url;
     this.baseUrl = url.split('#')[0];
     var title = (0, _ui_utils.getPDFFileNameFromURL)(url, '');
@@ -1231,17 +1231,17 @@ var PDFViewerApplication = {
       var loadingErrorMessage = _ui_utils.mozL10n.get('loading_error', null, 'An error occurred while loading the PDF.');
       if (exception instanceof _pdfjs.InvalidPDFException) {
         loadingErrorMessage = _ui_utils.mozL10n.get('invalid_file_error', null, 'Invalid or corrupted PDF file.');
       } else if (exception instanceof _pdfjs.MissingPDFException) {
         loadingErrorMessage = _ui_utils.mozL10n.get('missing_file_error', null, 'Missing PDF file.');
       } else if (exception instanceof _pdfjs.UnexpectedResponseException) {
         loadingErrorMessage = _ui_utils.mozL10n.get('unexpected_response_error', null, 'Unexpected server response.');
       }
-      var moreInfo = { message: message };
+      var moreInfo = { message };
       self.error(loadingErrorMessage, moreInfo);
       throw new Error(loadingErrorMessage);
     });
   },
   download: function pdfViewDownload() {
     function downloadByUrl() {
       downloadManager.downloadUrl(url, filename);
     }
@@ -1265,17 +1265,17 @@ var PDFViewerApplication = {
     }, downloadByUrl).then(null, downloadByUrl);
   },
   fallback: function pdfViewFallback(featureId) {
     if (this.fellback) {
       return;
     }
     this.fellback = true;
     this.externalServices.fallback({
-      featureId: featureId,
+      featureId,
       url: this.baseUrl
     }, function response(download) {
       if (!download) {
         return;
       }
       PDFViewerApplication.download();
     });
   },
@@ -1449,20 +1449,20 @@ var PDFViewerApplication = {
               return;
             }
           }
         });
       }
     });
     Promise.all([onePageRendered, _ui_utils.animationStarted]).then(function () {
       pdfDocument.getOutline().then(function (outline) {
-        self.pdfOutlineViewer.render({ outline: outline });
+        self.pdfOutlineViewer.render({ outline });
       });
       pdfDocument.getAttachments().then(function (attachments) {
-        self.pdfAttachmentViewer.render({ attachments: attachments });
+        self.pdfAttachmentViewer.render({ attachments });
       });
     });
     pdfDocument.getMetadata().then(function (data) {
       var info = data.info,
           metadata = data.metadata;
       self.documentInfo = info;
       self.metadata = metadata;
       console.log('PDF ' + pdfDocument.fingerprint + ' [' + info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() + ' / ' + (info.Creator || '-').trim() + ']' + ' (PDF.js: ' + (_pdfjs.version || '-') + (!_pdfjs.PDFJS.disableWebGL ? ' [WebGL]' : '') + ')');
@@ -1495,17 +1495,17 @@ var PDFViewerApplication = {
           return true;
         }.bind(null, info.Producer.toLowerCase()));
       }
       var formType = !info.IsAcroFormPresent ? null : info.IsXFAPresent ? 'xfa' : 'acroform';
       self.externalServices.reportTelemetry({
         type: 'documentInfo',
         version: versionId,
         generator: generatorId,
-        formType: formType
+        formType
       });
     });
   },
   setInitialView(storedHash, options = {}) {
     var { scale = 0, sidebarView = _pdf_sidebar.SidebarView.NONE } = options;
     this.isInitialViewSet = true;
     this.pdfSidebar.setInitialView(sidebarView);
     if (this.initialDestination) {
@@ -1783,17 +1783,17 @@ function webViewerPageRendered(e) {
   }
   if (pageView.error) {
     PDFViewerApplication.error(_ui_utils.mozL10n.get('rendering_error', null, 'An error occurred while rendering the page.'), pageView.error);
   }
   PDFViewerApplication.externalServices.reportTelemetry({ type: 'pageInfo' });
   PDFViewerApplication.pdfDocument.getStats().then(function (stats) {
     PDFViewerApplication.externalServices.reportTelemetry({
       type: 'documentStats',
-      stats: stats
+      stats
     });
   });
 }
 function webViewerTextLayerRendered(e) {
   if (e.numTextDivs > 0 && !PDFViewerApplication.supportsDocumentColors) {
     console.error(_ui_utils.mozL10n.get('document_colors_not_allowed', null, 'PDF documents are not allowed to use their own colors: ' + '\'Allow pages to choose their own colors\' ' + 'is deactivated in the browser.'));
     PDFViewerApplication.fallback();
   }
@@ -2246,17 +2246,17 @@ function webViewerKeyDown(evt) {
   }
 }
 _ui_utils.localized.then(function webViewerLocalized() {
   document.getElementsByTagName('html')[0].dir = _ui_utils.mozL10n.getDirection();
 });
 var PDFPrintServiceFactory = {
   instance: {
     supportsPrinting: false,
-    createPrintService: function () {
+    createPrintService() {
       throw new Error('Not implemented: createPrintService');
     }
   }
 };
 exports.PDFViewerApplication = PDFViewerApplication;
 exports.DefaultExternalServices = DefaultExternalServices;
 exports.PDFPrintServiceFactory = PDFPrintServiceFactory;
 
@@ -2277,18 +2277,18 @@ var OverlayManager = {
     return new Promise(function (resolve) {
       var 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: element,
-        container: container,
+        element,
+        container,
         callerCloseMethod: callerCloseMethod || null,
         canForceClose: canForceClose || false
       };
       resolve();
     }.bind(this));
   },
   unregister: function overlayManagerUnregister(name) {
     return new Promise(function (resolve) {
@@ -2420,22 +2420,22 @@ var PDFLinkService = function PDFLinkSer
           return;
         }
         if (pageNumber) {
           if (pageNumber < 1 || pageNumber > self.pagesCount) {
             console.error('PDFLinkService_navigateTo: "' + pageNumber + '" is a non-existent page number.');
             return;
           }
           self.pdfViewer.scrollPageIntoView({
-            pageNumber: pageNumber,
+            pageNumber,
             destArray: dest
           });
           if (self.pdfHistory) {
             self.pdfHistory.push({
-              dest: dest,
+              dest,
               hash: destString,
               page: pageNumber
             });
           }
         } else {
           self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {
             self.cachePageRef(pageIndex + 1, destRef);
             goToDestination(destRef);
@@ -2577,20 +2577,20 @@ var PDFLinkService = function PDFLinkSer
         case 'FirstPage':
           this.page = 1;
           break;
         default:
           break;
       }
       this.eventBus.dispatch('namedaction', {
         source: this,
-        action: action
+        action
       });
     },
-    onFileAttachmentAnnotation: function (params) {
+    onFileAttachmentAnnotation(params = {}) {
       this.eventBus.dispatch('fileattachmentannotation', {
         source: this,
         id: params.id,
         filename: params.filename,
         content: params.content
       });
     },
     cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) {
@@ -2657,27 +2657,27 @@ var PDFLinkService = function PDFLinkSer
 }();
 var SimpleLinkService = function SimpleLinkServiceClosure() {
   function SimpleLinkService() {}
   SimpleLinkService.prototype = {
     get page() {
       return 0;
     },
     set page(value) {},
-    navigateTo: function (dest) {},
-    getDestinationHash: function (dest) {
+    navigateTo(dest) {},
+    getDestinationHash(dest) {
       return '#';
     },
-    getAnchorUrl: function (hash) {
+    getAnchorUrl(hash) {
       return '#';
     },
-    setHash: function (hash) {},
-    executeNamedAction: function (action) {},
-    onFileAttachmentAnnotation: function (params) {},
-    cachePageRef: function (pageNum, pageRef) {}
+    setHash(hash) {},
+    executeNamedAction(action) {},
+    onFileAttachmentAnnotation(params) {},
+    cachePageRef(pageNum, pageRef) {}
   };
   return SimpleLinkService;
 }();
 exports.PDFLinkService = PDFLinkService;
 exports.SimpleLinkService = SimpleLinkService;
 
 /***/ }),
 /* 7 */
@@ -3105,36 +3105,36 @@ function composePage(pdfDocument, pageNu
   };
 }
 function FirefoxPrintService(pdfDocument, pagesOverview, printContainer) {
   this.pdfDocument = pdfDocument;
   this.pagesOverview = pagesOverview;
   this.printContainer = printContainer;
 }
 FirefoxPrintService.prototype = {
-  layout: function () {
+  layout() {
     var pdfDocument = this.pdfDocument;
     var printContainer = this.printContainer;
     var body = document.querySelector('body');
     body.setAttribute('data-pdfjsprinting', true);
     for (var i = 0, ii = this.pagesOverview.length; i < ii; ++i) {
       composePage(pdfDocument, i + 1, this.pagesOverview[i], printContainer);
     }
   },
-  destroy: function () {
+  destroy() {
     this.printContainer.textContent = '';
   }
 };
 _app.PDFPrintServiceFactory.instance = {
   get supportsPrinting() {
     var canvas = document.createElement('canvas');
     var value = 'mozPrintCallback' in canvas;
     return (0, _pdfjs.shadow)(this, 'supportsPrinting', value);
   },
-  createPrintService: function (pdfDocument, pagesOverview, printContainer) {
+  createPrintService(pdfDocument, pagesOverview, printContainer) {
     return new FirefoxPrintService(pdfDocument, pagesOverview, printContainer);
   }
 };
 exports.FirefoxPrintService = FirefoxPrintService;
 
 /***/ }),
 /* 9 */
 /***/ (function(module, exports, __webpack_require__) {
@@ -3151,77 +3151,77 @@ var _pdfjs = __webpack_require__(1);
 
 var _preferences = __webpack_require__(25);
 
 var _app = __webpack_require__(4);
 
 ;
 var FirefoxCom = function FirefoxComClosure() {
   return {
-    requestSync: function (action, data) {
+    requestSync(action, data) {
       var request = document.createTextNode('');
       document.documentElement.appendChild(request);
       var sender = document.createEvent('CustomEvent');
       sender.initCustomEvent('pdf.js.message', true, false, {
-        action: action,
-        data: data,
+        action,
+        data,
         sync: true
       });
       request.dispatchEvent(sender);
       var response = sender.detail.response;
       document.documentElement.removeChild(request);
       return response;
     },
-    request: function (action, data, callback) {
+    request(action, data, callback) {
       var request = document.createTextNode('');
       if (callback) {
         document.addEventListener('pdf.js.response', function listener(event) {
           var node = event.target;
           var response = event.detail.response;
           document.documentElement.removeChild(node);
           document.removeEventListener('pdf.js.response', listener);
           return callback(response);
         });
       }
       document.documentElement.appendChild(request);
       var sender = document.createEvent('CustomEvent');
       sender.initCustomEvent('pdf.js.message', true, false, {
-        action: action,
-        data: data,
+        action,
+        data,
         sync: false,
         responseExpected: !!callback
       });
       return request.dispatchEvent(sender);
     }
   };
 }();
 var DownloadManager = function DownloadManagerClosure() {
   function DownloadManager() {}
   DownloadManager.prototype = {
     downloadUrl: function DownloadManager_downloadUrl(url, filename) {
       FirefoxCom.request('download', {
         originalUrl: url,
-        filename: filename
+        filename
       });
     },
     downloadData: function DownloadManager_downloadData(data, filename, contentType) {
       var blobUrl = (0, _pdfjs.createObjectURL)(data, contentType, false);
       FirefoxCom.request('download', {
-        blobUrl: blobUrl,
+        blobUrl,
         originalUrl: blobUrl,
-        filename: filename,
+        filename,
         isAttachment: true
       });
     },
     download: function DownloadManager_download(blob, url, filename) {
       var blobUrl = window.URL.createObjectURL(blob);
       FirefoxCom.request('download', {
-        blobUrl: blobUrl,
+        blobUrl,
         originalUrl: url,
-        filename: filename
+        filename
       }, function response(err) {
         if (err && this.onerror) {
           this.onerror(err);
         }
         window.URL.revokeObjectURL(blobUrl);
       }.bind(this));
     }
   };
@@ -3263,28 +3263,28 @@ class FirefoxPreferences extends _prefer
   }
 })();
 function FirefoxComDataRangeTransport(length, initialData) {
   _pdfjs.PDFDataRangeTransport.call(this, length, initialData);
 }
 FirefoxComDataRangeTransport.prototype = Object.create(_pdfjs.PDFDataRangeTransport.prototype);
 FirefoxComDataRangeTransport.prototype.requestDataRange = function FirefoxComDataRangeTransport_requestDataRange(begin, end) {
   FirefoxCom.request('requestDataRange', {
-    begin: begin,
-    end: end
+    begin,
+    end
   });
 };
 FirefoxComDataRangeTransport.prototype.abort = function FirefoxComDataRangeTransport_abort() {
   FirefoxCom.requestSync('abortLoading', null);
 };
 _app.PDFViewerApplication.externalServices = {
-  updateFindControlState: function (data) {
+  updateFindControlState(data) {
     FirefoxCom.request('updateFindControlState', data);
   },
-  initPassiveLoading: function (callbacks) {
+  initPassiveLoading(callbacks) {
     var pdfDataRangeTransport;
     window.addEventListener('message', function windowMessage(e) {
       if (e.source !== null) {
         console.warn('Rejected untrusted message from ' + e.origin);
         return;
       }
       var args = e.data;
       if (typeof args !== 'object' || !('pdfjsLoadAction' in args)) {
@@ -3313,23 +3313,23 @@ FirefoxComDataRangeTransport.prototype.a
             break;
           }
           callbacks.onOpenWithData(args.data);
           break;
       }
     });
     FirefoxCom.requestSync('initPassiveLoading', null);
   },
-  fallback: function (data, callback) {
+  fallback(data, callback) {
     FirefoxCom.request('fallback', data, callback);
   },
-  reportTelemetry: function (data) {
+  reportTelemetry(data) {
     FirefoxCom.request('reportTelemetry', JSON.stringify(data));
   },
-  createDownloadManager: function () {
+  createDownloadManager() {
     return new DownloadManager();
   },
   createPreferences() {
     return new FirefoxPreferences();
   },
   get supportsIntegratedFind() {
     var support = FirefoxCom.requestSync('supportsIntegratedFind');
     return (0, _pdfjs.shadow)(this, 'supportsIntegratedFind', support);
@@ -3343,20 +3343,20 @@ FirefoxComDataRangeTransport.prototype.a
     return (0, _pdfjs.shadow)(this, 'supportsDocumentColors', support);
   },
   get supportedMouseWheelZoomModifierKeys() {
     var support = FirefoxCom.requestSync('supportedMouseWheelZoomModifierKeys');
     return (0, _pdfjs.shadow)(this, 'supportedMouseWheelZoomModifierKeys', support);
   }
 };
 document.mozL10n.setExternalLocalizerServices({
-  getLocale: function () {
+  getLocale() {
     return FirefoxCom.requestSync('getLocale', null);
   },
-  getStrings: function (key) {
+  getStrings(key) {
     return FirefoxCom.requestSync('getStrings', key);
   }
 });
 exports.DownloadManager = DownloadManager;
 exports.FirefoxCom = FirefoxCom;
 
 /***/ }),
 /* 10 */
@@ -3593,19 +3593,19 @@ var _ui_utils = __webpack_require__(0);
 var HandTool = function HandToolClosure() {
   function HandTool(options) {
     this.container = options.container;
     this.eventBus = options.eventBus;
     var preferences = options.preferences;
     this.wasActive = false;
     this.handTool = new _grab_to_pan.GrabToPan({
       element: this.container,
-      onActiveChanged: function (isActive) {
-        this.eventBus.dispatch('handtoolchanged', { isActive: isActive });
-      }.bind(this)
+      onActiveChanged: isActive => {
+        this.eventBus.dispatch('handtoolchanged', { isActive });
+      }
     });
     this.eventBus.on('togglehandtool', this.toggle.bind(this));
     Promise.all([_ui_utils.localized, preferences.get('enableHandToolOnLoad')]).then(values => {
       if (values[1] === true) {
         this.handTool.activate();
       }
     }).catch(function rejected(reason) {});
     this.eventBus.on('presentationmodechanged', function (e) {
@@ -4649,17 +4649,17 @@ var PDFPageView = function PDFPageViewCl
       this.reset();
     },
     destroy: function PDFPageView_destroy() {
       this.reset();
       if (this.pdfPage) {
         this.pdfPage.cleanup();
       }
     },
-    _resetZoomLayer: function (removeFromDOM) {
+    _resetZoomLayer(removeFromDOM = false) {
       if (!this.zoomLayer) {
         return;
       }
       var zoomLayerCanvas = this.zoomLayer.firstChild;
       this.paintedViewportMap.delete(zoomLayerCanvas);
       zoomLayerCanvas.width = 0;
       zoomLayerCanvas.height = 0;
       if (removeFromDOM) {
@@ -4928,24 +4928,24 @@ var PDFPageView = function PDFPageViewCl
         this.annotationLayer.render(this.viewport, 'display');
       }
       div.setAttribute('data-loaded', true);
       if (this.onBeforeDraw) {
         this.onBeforeDraw();
       }
       return resultPromise;
     },
-    paintOnCanvas: function (canvasWrapper) {
+    paintOnCanvas(canvasWrapper) {
       var renderCapability = (0, _pdfjs.createPromiseCapability)();
       var result = {
         promise: renderCapability.promise,
-        onRenderContinue: function (cont) {
+        onRenderContinue(cont) {
           cont();
         },
-        cancel: function () {
+        cancel() {
           renderTask.cancel();
         }
       };
       var viewport = this.viewport;
       var canvas = document.createElement('canvas');
       canvas.id = 'page' + this.id;
       canvas.setAttribute('hidden', 'hidden');
       var isCanvasHidden = true;
@@ -4984,17 +4984,17 @@ var PDFPageView = function PDFPageViewCl
       canvas.width = (0, _ui_utils.roundToDivide)(viewport.width * outputScale.sx, sfx[0]);
       canvas.height = (0, _ui_utils.roundToDivide)(viewport.height * outputScale.sy, sfy[0]);
       canvas.style.width = (0, _ui_utils.roundToDivide)(viewport.width, sfx[1]) + 'px';
       canvas.style.height = (0, _ui_utils.roundToDivide)(viewport.height, sfy[1]) + 'px';
       this.paintedViewportMap.set(canvas, viewport);
       var transform = !outputScale.scaled ? null : [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
       var renderContext = {
         canvasContext: ctx,
-        transform: transform,
+        transform,
         viewport: this.viewport,
         renderInteractiveForms: this.renderInteractiveForms
       };
       var renderTask = this.pdfPage.render(renderContext);
       renderTask.onContinue = function (cont) {
         showCanvas();
         if (result.onRenderContinue) {
           result.onRenderContinue(cont);
@@ -5009,18 +5009,18 @@ var PDFPageView = function PDFPageViewCl
         showCanvas();
         renderCapability.reject(error);
       });
       return result;
     },
     paintOnSvg: function PDFPageView_paintOnSvg(wrapper) {
       return {
         promise: Promise.reject(new Error('SVG rendering is not supported.')),
-        onRenderContinue: function (cont) {},
-        cancel: function () {}
+        onRenderContinue(cont) {},
+        cancel() {}
       };
     },
     setPageLabel: function PDFView_setPageLabel(label) {
       this.pageLabel = typeof label === 'string' ? label : null;
       if (this.pageLabel !== null) {
         this.div.setAttribute('data-page-label', this.pageLabel);
       } else {
         this.div.removeAttribute('data-page-label');
@@ -6056,39 +6056,39 @@ var PDFThumbnailViewer = function PDFThu
         this._pageLabels = labels;
       }
       for (var i = 0, ii = this.thumbnails.length; i < ii; i++) {
         var thumbnailView = this.thumbnails[i];
         var label = this._pageLabels && this._pageLabels[i];
         thumbnailView.setPageLabel(label);
       }
     },
-    _ensurePdfPageLoaded: function PDFThumbnailViewer_ensurePdfPageLoaded(thumbView) {
+    _ensurePdfPageLoaded(thumbView) {
       if (thumbView.pdfPage) {
         return Promise.resolve(thumbView.pdfPage);
       }
       var pageNumber = thumbView.id;
       if (this._pagesRequests[pageNumber]) {
         return this._pagesRequests[pageNumber];
       }
-      var promise = this.pdfDocument.getPage(pageNumber).then(function (pdfPage) {
+      var promise = this.pdfDocument.getPage(pageNumber).then(pdfPage => {
         thumbView.setPdfPage(pdfPage);
         this._pagesRequests[pageNumber] = null;
         return pdfPage;
-      }.bind(this));
+      });
       this._pagesRequests[pageNumber] = promise;
       return promise;
     },
-    forceRendering: function () {
+    forceRendering() {
       var visibleThumbs = this._getVisibleThumbs();
       var thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, this.thumbnails, this.scroll.down);
       if (thumbView) {
-        this._ensurePdfPageLoaded(thumbView).then(function () {
+        this._ensurePdfPageLoaded(thumbView).then(() => {
           this.renderingQueue.renderView(thumbView);
-        }.bind(this));
+        });
         return true;
       }
       return false;
     }
   };
   return PDFThumbnailViewer;
 }();
 exports.PDFThumbnailViewer = PDFThumbnailViewer;
@@ -6184,17 +6184,17 @@ var PDFViewer = function pdfViewer() {
     if (this.removePageBorders) {
       this.viewer.classList.add('removePageBorders');
     }
   }
   PDFViewer.prototype = {
     get pagesCount() {
       return this._pages.length;
     },
-    getPageView: function (index) {
+    getPageView(index) {
       return this._pages[index];
     },
     get pageViewsReady() {
       return this._pageViewsReady;
     },
     get currentPageNumber() {
       return this._currentPageNumber;
     },
@@ -6284,17 +6284,17 @@ var PDFViewer = function pdfViewer() {
         var pageView = this._pages[i];
         pageView.update(pageView.scale, rotation);
       }
       this._setScale(this._currentScaleValue, true);
       if (this.defaultRenderingQueue) {
         this.update();
       }
     },
-    setDocument: function (pdfDocument) {
+    setDocument(pdfDocument) {
       if (this.pdfDocument) {
         this._cancelRendering();
         this._resetView();
       }
       this.pdfDocument = pdfDocument;
       if (!pdfDocument) {
         return;
       }
@@ -6331,20 +6331,20 @@ var PDFViewer = function pdfViewer() {
           var textLayerFactory = null;
           if (!_pdfjs.PDFJS.disableTextLayer) {
             textLayerFactory = this;
           }
           var pageView = new _pdf_page_view.PDFPageView({
             container: this.viewer,
             eventBus: this.eventBus,
             id: pageNum,
-            scale: scale,
+            scale,
             defaultViewport: viewport.clone(),
             renderingQueue: this.renderingQueue,
-            textLayerFactory: textLayerFactory,
+            textLayerFactory,
             annotationLayerFactory: this,
             enhanceTextSelection: this.enhanceTextSelection,
             renderInteractiveForms: this.renderInteractiveForms,
             renderer: this.renderer
           });
           bindOnAfterAndBeforeDraw(pageView);
           this._pages.push(pageView);
         }
@@ -6389,17 +6389,17 @@ var PDFViewer = function pdfViewer() {
         this._pageLabels = labels;
       }
       for (var i = 0, ii = this._pages.length; i < ii; i++) {
         var pageView = this._pages[i];
         var label = this._pageLabels && this._pageLabels[i];
         pageView.setPageLabel(label);
       }
     },
-    _resetView: function () {
+    _resetView() {
       this._pages = [];
       this._currentPageNumber = 1;
       this._currentScale = _ui_utils.UNKNOWN_SCALE;
       this._currentScaleValue = null;
       this._pageLabels = null;
       this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE);
       this._location = null;
       this._pagesRotation = 0;
@@ -6488,17 +6488,17 @@ var PDFViewer = function pdfViewer() {
             break;
           default:
             console.error('PDFViewer_setScale: "' + value + '" is an unknown zoom value.');
             return;
         }
         this._setScaleUpdatePages(scale, value, noScroll, true);
       }
     },
-    _resetCurrentPageView: function () {
+    _resetCurrentPageView() {
       if (this.isInPresentationMode) {
         this._setScale(this._currentScaleValue, true);
       }
       var pageView = this._pages[this._currentPageNumber - 1];
       (0, _ui_utils.scrollIntoView)(pageView.div);
     },
     scrollPageIntoView: function PDFViewer_scrollPageIntoView(params) {
       if (!this.pdfDocument) {
@@ -6581,39 +6581,39 @@ var PDFViewer = function pdfViewer() {
       var boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)];
       var left = Math.min(boundingRect[0][0], boundingRect[1][0]);
       var top = Math.min(boundingRect[0][1], boundingRect[1][1]);
       if (!allowNegativeOffset) {
         left = Math.max(left, 0);
         top = Math.max(top, 0);
       }
       (0, _ui_utils.scrollIntoView)(pageView.div, {
-        left: left,
-        top: top
+        left,
+        top
       });
     },
-    _updateLocation: function (firstPage) {
+    _updateLocation(firstPage) {
       var currentScale = this._currentScale;
       var currentScaleValue = this._currentScaleValue;
       var normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue;
       var pageNumber = firstPage.id;
       var pdfOpenParams = '#page=' + pageNumber;
       pdfOpenParams += '&zoom=' + normalizedScaleValue;
       var currentPageView = this._pages[pageNumber - 1];
       var container = this.container;
       var topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y);
       var intLeft = Math.round(topLeft[0]);
       var intTop = Math.round(topLeft[1]);
       pdfOpenParams += ',' + intLeft + ',' + intTop;
       this._location = {
-        pageNumber: pageNumber,
+        pageNumber,
         scale: normalizedScaleValue,
         top: intTop,
         left: intLeft,
-        pdfOpenParams: pdfOpenParams
+        pdfOpenParams
       };
     },
     update: function PDFViewer_update() {
       var visible = this._getVisiblePages();
       var visiblePages = visible.views;
       if (visiblePages.length === 0) {
         return;
       }
@@ -6639,62 +6639,62 @@ var PDFViewer = function pdfViewer() {
         this._setCurrentPageNumber(currentId);
       }
       this._updateLocation(firstPage);
       this.eventBus.dispatch('updateviewarea', {
         source: this,
         location: this._location
       });
     },
-    containsElement: function (element) {
+    containsElement(element) {
       return this.container.contains(element);
     },
-    focus: function () {
+    focus() {
       this.container.focus();
     },
     get isInPresentationMode() {
       return this.presentationModeState === PresentationModeState.FULLSCREEN;
     },
     get isChangingPresentationMode() {
       return this.presentationModeState === PresentationModeState.CHANGING;
     },
     get isHorizontalScrollbarEnabled() {
       return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth;
     },
-    _getVisiblePages: function () {
+    _getVisiblePages() {
       if (!this.isInPresentationMode) {
         return (0, _ui_utils.getVisibleElements)(this.container, this._pages, true);
       }
       var visible = [];
       var currentPage = this._pages[this._currentPageNumber - 1];
       visible.push({
         id: currentPage.id,
         view: currentPage
       });
       return {
         first: currentPage,
         last: currentPage,
         views: visible
       };
     },
-    cleanup: function () {
+    cleanup() {
       for (var i = 0, ii = this._pages.length; i < ii; i++) {
         if (this._pages[i] && this._pages[i].renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) {
           this._pages[i].reset();
         }
       }
     },
     _cancelRendering: function PDFViewer_cancelRendering() {
       for (var i = 0, ii = this._pages.length; i < ii; i++) {
         if (this._pages[i]) {
           this._pages[i].cancelRendering();
         }
       }
     },
-    _ensurePdfPageLoaded: function (pageView) {
+    _ensurePdfPageLoaded(pageView) {
       if (pageView.pdfPage) {
         return Promise.resolve(pageView.pdfPage);
       }
       var pageNumber = pageView.id;
       if (this._pagesRequests[pageNumber]) {
         return this._pagesRequests[pageNumber];
       }
       var promise = this.pdfDocument.getPage(pageNumber).then(pdfPage => {
@@ -6702,55 +6702,55 @@ var PDFViewer = function pdfViewer() {
           pageView.setPdfPage(pdfPage);
         }
         this._pagesRequests[pageNumber] = null;
         return pdfPage;
       });
       this._pagesRequests[pageNumber] = promise;
       return promise;
     },
-    forceRendering: function (currentlyVisiblePages) {
+    forceRendering(currentlyVisiblePages) {
       var visiblePages = currentlyVisiblePages || this._getVisiblePages();
       var pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, this.scroll.down);
       if (pageView) {
         this._ensurePdfPageLoaded(pageView).then(() => {
           this.renderingQueue.renderView(pageView);
         });
         return true;
       }
       return false;
     },
-    getPageTextContent: function (pageIndex) {
+    getPageTextContent(pageIndex) {
       return this.pdfDocument.getPage(pageIndex + 1).then(function (page) {
         return page.getTextContent({ normalizeWhitespace: true });
       });
     },
-    createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport, enhanceTextSelection) {
+    createTextLayerBuilder(textLayerDiv, pageIndex, viewport, enhanceTextSelection = false) {
       return new _text_layer_builder.TextLayerBuilder({
-        textLayerDiv: textLayerDiv,
+        textLayerDiv,
         eventBus: this.eventBus,
-        pageIndex: pageIndex,
-        viewport: viewport,
+        pageIndex,
+        viewport,
         findController: this.isInPresentationMode ? null : this.findController,
         enhanceTextSelection: this.isInPresentationMode ? false : enhanceTextSelection
       });
     },
-    createAnnotationLayerBuilder: function (pageDiv, pdfPage, renderInteractiveForms) {
+    createAnnotationLayerBuilder(pageDiv, pdfPage, renderInteractiveForms = false) {
       return new _annotation_layer_builder.AnnotationLayerBuilder({
-        pageDiv: pageDiv,
-        pdfPage: pdfPage,
-        renderInteractiveForms: renderInteractiveForms,
+        pageDiv,
+        pdfPage,
+        renderInteractiveForms,
         linkService: this.linkService,
         downloadManager: this.downloadManager
       });
     },
-    setFindController: function (findController) {
+    setFindController(findController) {
       this.findController = findController;
     },
-    getPagesOverview: function () {
+    getPagesOverview() {
       var pagesOverview = this._pages.map(function (pageView) {
         var viewport = pageView.pdfPage.getViewport(1);
         return {
           width: viewport.width,
           height: viewport.height,
           rotation: viewport.rotation
         };
       });
@@ -7133,17 +7133,17 @@ var TextLayerBuilder = function TextLaye
       this.cancel();
       this.textDivs = [];
       var textLayerFrag = document.createDocumentFragment();
       this.textLayerRenderTask = (0, _pdfjs.renderTextLayer)({
         textContent: this.textContent,
         container: textLayerFrag,
         viewport: this.viewport,
         textDivs: this.textDivs,
-        timeout: timeout,
+        timeout,
         enhanceTextSelection: this.enhanceTextSelection
       });
       this.textLayerRenderTask.promise.then(function () {
         this.textLayerDiv.appendChild(textLayerFrag);
         this._finishRendering();
         this.updateMatches();
       }.bind(this), function (reason) {});
     },
@@ -7328,22 +7328,22 @@ var TextLayerBuilder = function TextLaye
         end.classList.remove('active');
       });
     }
   };
   return TextLayerBuilder;
 }();
 function DefaultTextLayerFactory() {}
 DefaultTextLayerFactory.prototype = {
-  createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport, enhanceTextSelection) {
+  createTextLayerBuilder(textLayerDiv, pageIndex, viewport, enhanceTextSelection = false) {
     return new TextLayerBuilder({
-      textLayerDiv: textLayerDiv,
-      pageIndex: pageIndex,
-      viewport: viewport,
-      enhanceTextSelection: enhanceTextSelection
+      textLayerDiv,
+      pageIndex,
+      viewport,
+      enhanceTextSelection
     });
   }
 };
 exports.TextLayerBuilder = TextLayerBuilder;
 exports.DefaultTextLayerFactory = DefaultTextLayerFactory;
 
 /***/ }),
 /* 28 */
@@ -7368,32 +7368,32 @@ var Toolbar = function ToolbarClosure() 
     this.mainContainer = mainContainer;
     this.eventBus = eventBus;
     this.items = options;
     this._wasLocalized = false;
     this.reset();
     this._bindListeners();
   }
   Toolbar.prototype = {
-    setPageNumber: function (pageNumber, pageLabel) {
+    setPageNumber(pageNumber, pageLabel) {
       this.pageNumber = pageNumber;
       this.pageLabel = pageLabel;
       this._updateUIState(false);
     },
-    setPagesCount: function (pagesCount, hasPageLabels) {
+    setPagesCount(pagesCount, hasPageLabels) {
       this.pagesCount = pagesCount;
       this.hasPageLabels = hasPageLabels;
       this._updateUIState(true);
     },
-    setPageScale: function (pageScaleValue, pageScale) {
+    setPageScale(pageScaleValue, pageScale) {
       this.pageScaleValue = pageScaleValue;
       this.pageScale = pageScale;
       this._updateUIState(false);
     },
-    reset: function () {
+    reset() {
       this.pageNumber = 0;
       this.pageLabel = null;
       this.hasPageLabels = false;
       this.pagesCount = 0;
       this.pageScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
       this.pageScale = _ui_utils.DEFAULT_SCALE;
       this._updateUIState(true);
     },
@@ -7478,25 +7478,25 @@ var Toolbar = function ToolbarClosure() 
       var scale = this.pageScale;
       var items = this.items;
       var pagesCount = this.pagesCount;
       if (resetNumPages) {
         if (this.hasPageLabels) {
           items.pageNumber.type = 'text';
         } else {
           items.pageNumber.type = 'number';
-          items.numPages.textContent = _ui_utils.mozL10n.get('of_pages', { pagesCount: pagesCount }, 'of {{pagesCount}}');
+          items.numPages.textContent = _ui_utils.mozL10n.get('of_pages', { pagesCount }, 'of {{pagesCount}}');
         }
         items.pageNumber.max = pagesCount;
       }
       if (this.hasPageLabels) {
         items.pageNumber.value = this.pageLabel;
         items.numPages.textContent = _ui_utils.mozL10n.get('page_of_pages', {
-          pageNumber: pageNumber,
-          pagesCount: pagesCount
+          pageNumber,
+          pagesCount
         }, '({{pageNumber}} of {{pagesCount}})');
       } else {
         items.pageNumber.value = pageNumber;
       }
       items.previous.disabled = pageNumber <= 1;
       items.next.disabled = pageNumber >= pagesCount;
       items.zoomOut.disabled = scale <= _ui_utils.MIN_SCALE;
       items.zoomIn.disabled = scale >= _ui_utils.MAX_SCALE;
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1488,18 +1488,16 @@ toolbarbutton.chevron > .toolbarbutton-i
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 %include ../shared/fullscreen/warning.inc.css
 %include ../shared/ctrlTab.inc.css
-%include ../../../devtools/client/themes/responsivedesign.inc.css
-%include ../../../devtools/client/themes/commandline.inc.css
 %include ../shared/plugin-doorhanger.inc.css
 
 notification.pluginVulnerable > .notification-inner > .messageCloseButton:not(:hover) {
   background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 80, 16, 64);
 }
 
 
 %include downloads/indicator.css
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -3100,18 +3100,16 @@ html|*.addon-webext-perm-list {
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 %include ../shared/fullscreen/warning.inc.css
 %include ../shared/ctrlTab.inc.css
-%include ../../../devtools/client/themes/responsivedesign.inc.css
-%include ../../../devtools/client/themes/commandline.inc.css
 %include ../shared/plugin-doorhanger.inc.css
 
 %include downloads/indicator.css
 
 /* On mac, the popup notification contents are indented by default and so
   the default closebutton margins from notification.css require adjustment */
 
 .click-to-play-plugins-notification-description-box > .popup-notification-closebutton {
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2262,18 +2262,16 @@ notification[value="translation"] {
   /* disabled for triggering grayscale AA (bug 659213)
   border-top-left-radius: .3em;
   */
   margin-left: 1em;
 }
 
 %include ../shared/fullscreen/warning.inc.css
 %include ../shared/ctrlTab.inc.css
-%include ../../../devtools/client/themes/responsivedesign.inc.css
-%include ../../../devtools/client/themes/commandline.inc.css
 %include ../shared/plugin-doorhanger.inc.css
 
 notification.pluginVulnerable > .notification-inner > .messageCloseButton {
   list-style-image: url("chrome://global/skin/icons/close-inverted.png");
 }
 
 @media (min-resolution: 1.1dppx) {
   notification.pluginVulnerable > .notification-inner > .messageCloseButton {
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -246,34 +246,30 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -
              DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
          fi
     else
         DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
     fi
 fi
 
 # bionic in Android < 4.1 doesn't support PIE
-# On OSX, the linker defaults to building PIE programs when targetting OSX 10.7+,
-# but not when targetting OSX < 10.7. OSX < 10.7 doesn't support running PIE
-# programs, so as long as support for OSX 10.6 is kept, we can't build PIE.
-# Even after dropping 10.6 support, MOZ_PIE would not be useful since it's the
-# default (and clang says the -pie option is not used).
+# On OSX, the linker defaults to building PIE programs when targeting OSX 10.7.
 # On other Unix systems, some file managers (Nautilus) can't start PIE programs
 if test -n "$gonkdir" && test "$ANDROID_VERSION" -ge 16; then
     MOZ_PIE=1
 else
     MOZ_PIE=
 fi
 
 MOZ_ARG_ENABLE_BOOL(pie,
 [  --enable-pie           Enable Position Independent Executables],
     MOZ_PIE=1,
     MOZ_PIE= )
 
-if test "$GNU_CC" -a -n "$MOZ_PIE"; then
+if test "$GNU_CC$CLANG_CC" -a -n "$MOZ_PIE"; then
     AC_MSG_CHECKING([for PIE support])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -pie"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes])
                   [MOZ_PROGRAM_LDFLAGS="$MOZ_PROGRAM_LDFLAGS -pie"],
                   AC_MSG_RESULT([no])
                   AC_MSG_ERROR([--enable-pie requires PIE support from the linker.]))
     LDFLAGS=$_SAVE_LDFLAGS
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -423,17 +423,18 @@ def get_vc_paths(topsrcdir):
         version = Version(install['installationVersion'])
         # Skip anything older than VS2015.
         if version < '14':
             continue
         path = install['installationPath']
 
         yield (Version(install['installationVersion']), {
             'x64': [os.path.join(path, r'VC\bin\amd64')],
-            'x86': [os.path.join(path, r'VC\bin\amd64_x86')],
+            # The x64->x86 cross toolchain requires DLLs from the native x64 toolchain.
+            'x86': [os.path.join(path, r'VC\bin\amd64_x86'), os.path.join(path, r'VC\bin\amd64')],
         })
     # Then VS2017 and newer.
     for install in vswhere(['-requires', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64']):
         path = install['installationPath']
         tools_version = open(os.path.join(path, r'VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt'), 'rb').read().strip()
         tools_path = os.path.join(path, r'VC\Tools\MSVC', tools_version, r'bin\HostX64')
         yield (Version(install['installationVersion']), {
             'x64': [os.path.join(tools_path, 'x64')],
deleted file mode 100644
--- a/config/tests/makefiles/autodeps/check_mkdir.py
+++ /dev/null
@@ -1,270 +0,0 @@
-#!/usr/bin/env python
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-
-import os
-import sys
-import tempfile
-
-from subprocess import call
-from shutil     import rmtree
-
-import logging
-import unittest
-import mozunit
-
-
-def banner():
-    """
-    Display interpreter and system info for the test env
-    """
-    print '*' * 75
-    cmd = os.path.basename(__file__)
-    print "%s: python version is %s" % (cmd, sys.version)
-    print '*' * 75
-
-
-def myopts(vals):
-    """
-    Storage for extra command line args passed.
-
-    Returns:
-    hash - argparse::Namespace object values
-    """
-
-    if not hasattr(myopts, 'vals'):
-        if 'argparse' in sys.modules:
-            tmp = { } # key existance enables unittest module debug
-        else:
-            tmp = { 'debug': False, 'verbose': False }
-
-        for k in dir(vals):
-            if k[0:1] == '_':
-                continue
-            tmp[k] = getattr(vals, k)
-        myopts.vals = tmp
-
-    return myopts.vals
-
-
-def path2posix(src):
-    """
-    Normalize directory path syntax
-
-    Keyword arguments:
-    src - path to normalize
-
-    Returns:
-    scalar - a file path with drive separators and windows slashes removed
-
-    Todo:
-    move to {build,config,tools,toolkit}/python for use in a library
-    """
-
-    ## (drive, tail) = os.path.splitdrive(src)
-    ## Support path testing on all platforms
-    drive = ''
-    winpath = src.find(':')
-    if -1 != winpath and 10 > winpath:
-        (drive, tail) = src.split(':', 1)
-
-    if drive:
-        todo = [ '', drive.rstrip(':').lstrip('/').lstrip('\\') ]
-        todo.extend( tail.lstrip('/').lstrip('\\').split('\\') ) # c:\a => [a]
-    else: # os.name == 'posix'
-        todo = src.split('\\')
-
-    dst = '/'.join(todo)
-    return dst
-
-
-def checkMkdir(work, debug=False):
-    """
-    Verify arg permutations for directory mutex creation.
-
-    Keyword arguments:
-    None
-
-    Returns:
-    Exception on error
-
-    Note:
-    Exception() rather than self.assertTrue() is used in this test
-    function to enable scatch cleanup on test exit/failure conditions.
-    Not guaranteed by python closures on early exit.
-    """
-
-    logging.debug("Testing: checkMkdir")
-
-    # On Windows, don't convert paths to POSIX
-    skipposix = sys.platform == "win32"
-    if skipposix:
-        path = os.path.abspath(__file__)
-        dirname_fun = os.path.dirname
-    else:
-        path = path2posix(os.path.abspath(__file__))
-        import posixpath
-        dirname_fun = posixpath.dirname
-
-    src = dirname_fun(path)
-    # root is 5 directories up from path
-    root = reduce(lambda x, _: dirname_fun(x), xrange(5), path)
-
-    rootP = path2posix(root)
-    srcP  = path2posix(src)
-    workP = path2posix(work)
-
-    # C:\foo -vs- /c/foo
-    # [0] command paths use /c/foo
-    # [1] os.path.exists() on mingw() requires C:\
-    paths = [
-        "mkdir_bycall", # function generated
-        "mkdir_bydep",  # explicit dependency
-        "mkdir_bygen",  # by GENERATED_DIRS macro
-    ]
-
-    ## Use make from the parent "make check" call when available
-    cmd = { 'make': 'make' }
-    shell0 = os.environ.get('MAKE')
-    if shell0:
-        shell = os.path.splitext(shell0)[0] # strip: .exe, .py
-        if -1 != shell.find('make'):
-            print "MAKE COMMAND FOUND: %s" % (shell0)
-            cmd['make'] = shell0 if skipposix else path2posix(shell0)
-
-    args = []
-    args.append('%s' % (cmd['make']))
-    args.append('-C %s'                % (work if skipposix else workP))
-    args.append("-f %s/testor.tmpl"    % (src if skipposix else srcP))
-    args.append('topsrcdir=%s'         % (root if skipposix else rootP))
-    args.append('deps_mkdir_bycall=%s' % paths[0])
-    args.append('deps_mkdir_bydep=%s'  % paths[1])
-    args.append('deps_mkdir_bygen=%s'  % paths[2])
-    args.append('checkup') # target
-
-    # Call will fail on mingw with output redirected ?!?
-    if debug:
-        pass
-    if False: # if not debug:
-        args.append('>/dev/null')
-
-    cmd = '%s' % (' '.join(args))
-    logging.debug("Running: %s" % (cmd))
-    rc = call(cmd, shell=True)
-    if rc:
-        raise Exception("make failed ($?=%s): cmd=%s" % (rc, cmd))
-
-    for i in paths:
-        path = os.path.join(work, i)
-        logging.debug("Did testing mkdir(%s) succeed?" % (path))
-        if not os.path.exists(path):
-            raise Exception("Test path %s does not exist" % (path))
-
-
-def parseargs():
-    """
-    Support additional command line arguments for testing
-
-    Returns:
-    hash - arguments of interested parsed from the command line
-    """
-
-    opts = None
-    try:
-        import argparse2
-        parser = argparse.ArgumentParser()
-        parser.add_argument('--debug',
-                            action="store_true",
-                            default=False,
-                            help='Enable debug mode')
-        # Cannot overload verbose, Verbose: False enables debugging
-        parser.add_argument('--verbose',
-                            action="store_true",
-                            default=False,
-                            help='Enable verbose mode')
-        parser.add_argument('unittest_args',
-                            nargs='*'
-                            # help='Slurp/pass remaining args to unittest'
-                            )
-        opts = parser.parse_args()
-
-    except ImportError:
-        pass
-
-    return opts
-
-
-class TestMakeLogic(unittest.TestCase):
-    """
-    Test suite used to validate makefile library rules and macros
-    """
-
-    def setUp(self):
-        opts = myopts(None) # NameSpace object not hash
-        self.debug   = opts['debug']
-        self.verbose = opts['verbose']
-
-        if self.debug:
-            logging.basicConfig(level=logging.DEBUG)
-
-        if self.verbose:
-            print
-            print "ENVIRONMENT DUMP:"
-            print '=' * 75
-            for k,v in os.environ.items():
-                print "env{%s} => %s" % (k, v)
-            print
-
-
-    def test_path2posix(self):
-
-        todo = {
-            '/dev/null'     : '/dev/null',
-            'A:\\a\\b\\c'   : '/A/a/b/c',
-            'B:/x/y'        : '/B/x/y',
-            'C:/x\\y/z'     : '/C/x/y/z',
-            '//FOO/bar/tans': '//FOO/bar/tans',
-            '//X\\a/b\\c/d' : '//X/a/b/c/d',
-            '\\c:mozilla\\sandbox': '/c/mozilla/sandbox',
-        }
-
-        for val,exp in todo.items():
-            found = path2posix(val)
-            tst = "posix2path(%s): %s != %s)" % (val, exp, found)
-            self.assertEqual(exp, found, "%s: invalid path detected" % (tst))
-
-
-    def test_mkdir(self):
-        """
-        Verify directory creation rules and macros
-        """
-
-        failed = True
-
-        # Exception handling is used to cleanup scratch space on error
-        try:
-            work = tempfile.mkdtemp()
-            checkMkdir(work, self.debug)
-            failed = False
-        finally:
-            if os.path.exists(work):
-                rmtree(work)
-
-        self.assertFalse(failed, "Unit test failure detected")
-
-
-if __name__ == '__main__':
-    banner()
-    opts = parseargs()
-    myopts(opts)
-
-    if opts:
-        if hasattr(opts, 'unittest_args'):
-            sys.argv[1:] = opts.unittest_args
-        else:
-            sys.argv[1:] = []
-
-    mozunit.main()
deleted file mode 100644
--- a/config/tests/makefiles/autodeps/testor.tmpl
+++ /dev/null
@@ -1,64 +0,0 @@
-# -*- makefile -*-
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-
-###########################################################################
-## Intent: Standalone unit tests for makefile rules and target logic
-###########################################################################
-
-deps =$(NULL)
-tgts =$(NULL)
-
-ifdef VERBOSE
-  tgts += show
-endif
-
-# Define macros
-include $(topsrcdir)/config/makefiles/makeutils.mk
-include $(topsrcdir)/config/makefiles/autotargets.mk
-
-##########################
-## Verify threadsafe mkdir
-##########################
-ifdef deps_mkdir_bycall
-  deps += $(call mkdir_deps,deps_mkdir_bycall)
-  tgts += check_mkdir
-endif
-ifdef deps_mkdir_bydep
-  deps += $(foreach dir,$(deps_mkdir_bydep),$(dir)/.mkdir.done)
-  tgts += check_mkdir
-endif
-ifdef deps_mkdir_bygen
-  GENERATED_DIRS += $(deps_mkdir_bygen)
-  tgts += check_mkdir
-endif
-
-###########################
-## Minimal environment load
-###########################
-MKDIR ?= mkdir -p
-TOUCH ?= touch
-
-INCLUDED_CONFIG_MK = 1
-MOZILLA_DIR := $(topsrcdir)
-include $(topsrcdir)/config/rules.mk
-
-##-------------------##
-##---]  TARGETS  [---##
-##-------------------##
-all::
-
-# Quarks:
-#   o Use of 'all' would trigger export target processing
-checkup: $(tgts)
-
-# AUTO_DEPS - verify GENERATED_DIRS
-check_mkdir: $(deps) $(AUTO_DEPS)
-
-show:
-	@echo "tgts=[$(tgts)]"
-	@echo "deps=[$(deps)]"
-	find $(dir $(deps)) -print
--- a/config/tests/python.ini
+++ b/config/tests/python.ini
@@ -1,6 +1,5 @@
 [test_mozbuild_reading.py]
 [unit-expandlibs.py]
 [unit-mozunit.py]
 [unit-nsinstall.py]
 [unit-printprereleasesuffix.py]
-[makefiles/autodeps/check_mkdir.py]
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
@@ -8,16 +8,18 @@ function findBreakpoint(dbg, url, line) 
 }
 
 function setConditionalBreakpoint(dbg, index, condition) {
   return Task.spawn(function* () {
     rightClickElement(dbg, "gutter", index);
     selectMenuItem(dbg, 2);
     yield waitForElement(dbg, ".conditional-breakpoint-panel input");
     findElementWithSelector(dbg, ".conditional-breakpoint-panel input").focus();
+    // Position cursor reliably at the end of the text.
+    pressKey(dbg, "End")
     type(dbg, condition);
     pressKey(dbg, "Enter");
   });
 }
 
 add_task(function* () {
   const dbg = yield initDebugger("doc-scripts.html");
   yield selectSource(dbg, "simple2");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js
@@ -27,16 +27,18 @@ async function addExpression(dbg, input)
   pressKey(dbg, "Enter");
 
   await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
 }
 
 async function editExpression(dbg, input) {
   info("updating the expression");
   dblClickElement(dbg, "expressionNode", 1);
+  // Position cursor reliably at the end of the text.
+  pressKey(dbg, "End")
   type(dbg, input);
   pressKey(dbg, "Enter");
   await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
 }
 
 add_task(function*() {
   const dbg = yield initDebugger("doc-script-switching.html");
 
--- a/devtools/client/debugger/new/test/mochitest/head.js
+++ b/devtools/client/debugger/new/test/mochitest/head.js
@@ -548,23 +548,37 @@ function togglePauseOnExceptions(
 function invokeInTab(fnc) {
   info(`Invoking function ${fnc} in tab`);
   return ContentTask.spawn(gBrowser.selectedBrowser, fnc, function*(fnc) {
     content.wrappedJSObject[fnc](); // eslint-disable-line mozilla/no-cpows-in-tests, max-len
   });
 }
 
 const isLinux = Services.appinfo.OS === "Linux";
+const isMac = Services.appinfo.OS === "Darwin";
 const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true };
+// On Mac, going to beginning/end only works with meta+left/right.  On
+// Windows, it only works with home/end.  On Linux, apparently, either
+// ctrl+left/right or home/end work.
+const endKey = isMac ?
+      { code: "VK_RIGHT", modifiers: cmdOrCtrl } :
+      { code: "VK_END" };
+const startKey = isMac ? 
+      { code: "VK_LEFT", modifiers: cmdOrCtrl } :
+      { code: "VK_HOME" };
 const keyMappings = {
   sourceSearch: { code: "p", modifiers: cmdOrCtrl },
   fileSearch: { code: "f", modifiers: cmdOrCtrl },
   Enter: { code: "VK_RETURN" },
   Up: { code: "VK_UP" },
   Down: { code: "VK_DOWN" },
+  Right: { code: "VK_RIGHT" },
+  Left: { code: "VK_LEFT" },
+  End: endKey,
+  Start: startKey,
   Tab: { code: "VK_TAB" },
   Escape: { code: "VK_ESCAPE" },
   pauseKey: { code: "VK_F8" },
   resumeKey: { code: "VK_F8" },
   stepOverKey: { code: "VK_F10" },
   stepInKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux } },
   stepOutKey: {
     code: "VK_F11",
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -20,43 +20,52 @@ const {gDevTools} = require("./devtools"
 
 // Load target and toolbox lazily as they need gDevTools to be fully initialized
 loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
 loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
 loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browser-menus");
 loader.lazyRequireGetter(this, "findCssSelector", "devtools/shared/inspector/css-logic", true);
+loader.lazyRequireGetter(this, "appendStyleSheet", "devtools/client/shared/stylesheet-utils", true);
 
 loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
 loader.lazyImporter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");
 loader.lazyImporter(this, "LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm");
 
 const {LocalizationHelper} = require("devtools/shared/l10n");
 const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
 
 const TABS_OPEN_PEAK_HISTOGRAM = "DEVTOOLS_TABS_OPEN_PEAK_LINEAR";
 const TABS_OPEN_AVG_HISTOGRAM = "DEVTOOLS_TABS_OPEN_AVERAGE_LINEAR";
 const TABS_PINNED_PEAK_HISTOGRAM = "DEVTOOLS_TABS_PINNED_PEAK_LINEAR";
 const TABS_PINNED_AVG_HISTOGRAM = "DEVTOOLS_TABS_PINNED_AVERAGE_LINEAR";
 
 const COMPACT_LIGHT_ID = "firefox-compact-light@mozilla.org";
 const COMPACT_DARK_ID = "firefox-compact-dark@mozilla.org";
 
+const BROWSER_STYLESHEET_URL = "chrome://devtools/skin/devtools-browser.css";
+
 /**
  * gDevToolsBrowser exposes functions to connect the gDevTools instance with a
  * Firefox instance.
  */
 var gDevToolsBrowser = exports.gDevToolsBrowser = {
   /**
    * A record of the windows whose menus we altered, so we can undo the changes
    * as the window is closed
    */
   _trackedBrowserWindows: new Set(),
 
+  /**
+   * WeakMap keeping track of the devtools-browser stylesheets loaded in the various
+   * tracked windows.
+   */
+  _browserStyleSheets: new WeakMap(),
+
   _telemetry: new Telemetry(),
 
   _tabStats: {
     peakOpen: 0,
     peakPinned: 0,
     histOpen: [],
     histPinned: []
   },
@@ -486,16 +495,35 @@ var gDevToolsBrowser = exports.gDevTools
   },
 
   isWebIDEWidgetInstalled() {
     let widgetWrapper = CustomizableUI.getWidget("webide-button");
     return !!(widgetWrapper && widgetWrapper.provider == CustomizableUI.PROVIDER_API);
   },
 
   /**
+   * Add the devtools-browser stylesheet to browser window's document. Returns a promise.
+   *
+   * @param  {Window} win
+   *         The window on which the stylesheet should be added.
+   * @return {Promise} promise that resolves when the stylesheet is loaded (or rejects
+   *         if it fails to load).
+   */
+  loadBrowserStyleSheet: function (win) {
+    if (this._browserStyleSheets.has(win)) {
+      return Promise.resolve();
+    }
+
+    let doc = win.document;
+    let {styleSheet, loadPromise} = appendStyleSheet(doc, BROWSER_STYLESHEET_URL);
+    this._browserStyleSheets.set(win, styleSheet);
+    return loadPromise;
+  },
+
+  /**
    * The deferred promise will be resolved by WebIDE's UI.init()
    */
   isWebIDEInitialized: defer(),
 
   /**
    * Uninstall WebIDE widget
    */
   uninstallWebIDEWidget() {
@@ -748,16 +776,22 @@ var gDevToolsBrowser = exports.gDevTools
 
     // Destroy toolboxes for closed window
     for (let [target, toolbox] of gDevTools._toolboxes) {
       if (target.tab && target.tab.ownerDocument.defaultView == win) {
         toolbox.destroy();
       }
     }
 
+    let styleSheet = this._browserStyleSheets.get(win);
+    if (styleSheet) {
+      styleSheet.remove();
+      this._browserStyleSheets.delete(win);
+    }
+
     // Destroy the Developer toolbar if it has been accessed
     let desc = Object.getOwnPropertyDescriptor(win, "DeveloperToolbar");
     if (desc && !desc.get) {
       win.DeveloperToolbar.destroy();
     }
 
     let tabContainer = win.gBrowser.tabContainer;
     tabContainer.removeEventListener("TabSelect", this);
--- a/devtools/client/framework/toolbox-hosts.js
+++ b/devtools/client/framework/toolbox-hosts.js
@@ -8,16 +8,17 @@
 
 const EventEmitter = require("devtools/shared/event-emitter");
 const promise = require("promise");
 const defer = require("devtools/shared/defer");
 const Services = require("Services");
 const {DOMHelpers} = require("resource://devtools/client/shared/DOMHelpers.jsm");
 
 loader.lazyRequireGetter(this, "system", "devtools/shared/system");
+loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
 
 /* A host should always allow this much space for the page to be displayed.
  * There is also a min-height on the browser, but we still don't want to set
  * frame.height to be larger than that, since it can cause problems with
  * resizing the toolbox and panel layout. */
 const MIN_PAGE_SIZE = 25;
 
 /**
@@ -48,18 +49,18 @@ function BottomHost(hostTab) {
 BottomHost.prototype = {
   type: "bottom",
 
   heightPref: "devtools.toolbox.footer.height",
 
   /**
    * Create a box at the bottom of the host tab.
    */
-  create: function () {
-    let deferred = defer();
+  create: async function () {
+    await gDevToolsBrowser.loadBrowserStyleSheet(this.hostTab.ownerGlobal);
 
     let gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
     let ownerDocument = gBrowser.ownerDocument;
     this._nbox = gBrowser.getNotificationBox(this.hostTab.linkedBrowser);
 
     this._splitter = ownerDocument.createElement("splitter");
     this._splitter.setAttribute("class", "devtools-horizontal-splitter");
     // Avoid resizing notification containers
@@ -70,32 +71,32 @@ BottomHost.prototype = {
     this.frame.height = Math.min(
       Services.prefs.getIntPref(this.heightPref),
       this._nbox.clientHeight - MIN_PAGE_SIZE
     );
 
     this._nbox.appendChild(this._splitter);
     this._nbox.appendChild(this.frame);
 
-    let frameLoad = () => {
-      this.emit("ready", this.frame);
-      deferred.resolve(this.frame);
-    };
-
     this.frame.tooltip = "aHTMLTooltip";
 
     // we have to load something so we can switch documents if we have to
     this.frame.setAttribute("src", "about:blank");
 
-    let domHelper = new DOMHelpers(this.frame.contentWindow);
-    domHelper.onceDOMReady(frameLoad);
+    let frame = await new Promise(resolve => {
+      let domHelper = new DOMHelpers(this.frame.contentWindow);
+      let frameLoad = () => {
+        this.emit("ready", this.frame);
+        resolve(this.frame);
+      };
+      domHelper.onceDOMReady(frameLoad);
+      focusTab(this.hostTab);
+    });
 
-    focusTab(this.hostTab);
-
-    return deferred.promise;
+    return frame;
   },
 
   /**
    * Raise the host.
    */
   raise: function () {
     focusTab(this.hostTab);
   },
@@ -194,18 +195,18 @@ function SidebarHost(hostTab) {
 SidebarHost.prototype = {
   type: "side",
 
   widthPref: "devtools.toolbox.sidebar.width",
 
   /**
    * Create a box in the sidebar of the host tab.
    */
-  create: function () {
-    let deferred = defer();
+  create: async function () {
+    await gDevToolsBrowser.loadBrowserStyleSheet(this.hostTab.ownerGlobal);
 
     let gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
     let ownerDocument = gBrowser.ownerDocument;
     this._sidebar = gBrowser.getSidebarContainer(this.hostTab.linkedBrowser);
 
     this._splitter = ownerDocument.createElement("splitter");
     this._splitter.setAttribute("class", "devtools-side-splitter");
 
@@ -215,30 +216,30 @@ SidebarHost.prototype = {
     this.frame.width = Math.min(
       Services.prefs.getIntPref(this.widthPref),
       this._sidebar.clientWidth - MIN_PAGE_SIZE
     );
 
     this._sidebar.appendChild(this._splitter);
     this._sidebar.appendChild(this.frame);
 
-    let frameLoad = () => {
-      this.emit("ready", this.frame);
-      deferred.resolve(this.frame);
-    };
-
     this.frame.tooltip = "aHTMLTooltip";
     this.frame.setAttribute("src", "about:blank");
 
-    let domHelper = new DOMHelpers(this.frame.contentWindow);
-    domHelper.onceDOMReady(frameLoad);
+    let frame = await new Promise(resolve => {
+      let domHelper = new DOMHelpers(this.frame.contentWindow);
+      let frameLoad = () => {
+        this.emit("ready", this.frame);
+        resolve(this.frame);
+      };
+      domHelper.onceDOMReady(frameLoad);
+      focusTab(this.hostTab);
+    });
 
-    focusTab(this.hostTab);
-
-    return deferred.promise;
+    return frame;
   },
 
   /**
    * Raise the host.
    */
   raise: function () {
     focusTab(this.hostTab);
   },
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+const SOURCE_MAP_WORKER = "resource://devtools/client/shared/source-map/worker.js";
+
 const MAX_ORDINAL = 99;
 const SPLITCONSOLE_ENABLED_PREF = "devtools.toolbox.splitconsoleEnabled";
 const SPLITCONSOLE_HEIGHT_PREF = "devtools.toolbox.splitconsoleHeight";
 const DISABLE_AUTOHIDE_PREF = "ui.popup.disable_autohide";
 const OS_HISTOGRAM = "DEVTOOLS_OS_ENUMERATED_PER_USER";
 const OS_IS_64_BITS = "DEVTOOLS_OS_IS_64_BITS_PER_USER";
 const HOST_HISTOGRAM = "DEVTOOLS_TOOLBOX_HOST";
 const SCREENSIZE_HISTOGRAM = "DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER";
@@ -541,16 +543,17 @@ Toolbox.prototype = {
       return null;
     }
     if (this._sourceMapService) {
       return this._sourceMapService;
     }
     // Uses browser loader to access the `Worker` global.
     this._sourceMapService =
       this.browserRequire("devtools/client/shared/source-map/index");
+    this._sourceMapService.startSourceMapWorker(SOURCE_MAP_WORKER);
     return this._sourceMapService;
   },
 
   // Return HostType id for telemetry
   _getTelemetryHostId: function () {
     switch (this.hostType) {
       case Toolbox.HostType.BOTTOM: return 0;
       case Toolbox.HostType.SIDE: return 1;
@@ -2292,17 +2295,17 @@ Toolbox.prototype = {
     this._lastFocusedElement = null;
 
     if (this._deprecatedServerSourceMapService) {
       this._deprecatedServerSourceMapService.destroy();
       this._deprecatedServerSourceMapService = null;
     }
 
     if (this._sourceMapService) {
-      this._sourceMapService.destroyWorker();
+      this._sourceMapService.stopSourceMapWorker();
       this._sourceMapService = null;
     }
 
     if (this.webconsolePanel) {
       this._saveSplitConsoleHeight();
       this.webconsolePanel.removeEventListener("resize",
         this._saveSplitConsoleHeight);
       this.webconsolePanel = null;
--- a/devtools/client/locales/en-US/netmonitor.properties
+++ b/devtools/client/locales/en-US/netmonitor.properties
@@ -496,16 +496,20 @@ netmonitor.toolbar.type=Type
 netmonitor.toolbar.cookies=Cookies
 
 # LOCALIZATION NOTE (netmonitor.toolbar.setCookies): This is the label displayed
 # in the network table toolbar, above the "set cookies" column.
 # Set-Cookie is a HTTP response header. This string is the plural form of it.
 # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
 netmonitor.toolbar.setCookies=Set-Cookies
 
+# LOCALIZATION NOTE (netmonitor.toolbar.cookies): This is the label displayed
+# in the network table toolbar, above the "scheme" column.
+netmonitor.toolbar.scheme=Scheme
+
 # LOCALIZATION NOTE (netmonitor.toolbar.transferred): This is the label displayed
 # in the network table toolbar, above the "transferred" column, which is the
 # compressed / encoded size.
 netmonitor.toolbar.transferred=Transferred
 
 # LOCALIZATION NOTE (netmonitor.toolbar.contentSize): This is the label displayed
 # in the network table toolbar, above the "size" column, which is the
 # uncompressed / decoded size.
--- a/devtools/client/netmonitor/index.js
+++ b/devtools/client/netmonitor/index.js
@@ -19,17 +19,17 @@ const { configureStore } = require("./sr
 
 require("./src/assets/styles/netmonitor.css");
 
 EventEmitter.decorate(window);
 
 pref("devtools.netmonitor.enabled", true);
 pref("devtools.netmonitor.filters", "[\"all\"]");
 pref("devtools.netmonitor.hiddenColumns",
-     "[\"cookies\",\"protocol\",\"remoteip\",\"setCookies\"]");
+     "[\"cookies\",\"protocol\",\"remoteip\",\"scheme\",\"setCookies\"]");
 pref("devtools.netmonitor.panes-network-details-width", 550);
 pref("devtools.netmonitor.panes-network-details-height", 450);
 pref("devtools.netmonitor.har.defaultLogDir", "");
 pref("devtools.netmonitor.har.defaultFileName", "Archive %date");
 pref("devtools.netmonitor.har.jsonp", false);
 pref("devtools.netmonitor.har.jsonpCallback", "");
 pref("devtools.netmonitor.har.includeResponseBodies", true);
 pref("devtools.netmonitor.har.compress", false);
--- a/devtools/client/netmonitor/src/assets/styles/netmonitor.css
+++ b/devtools/client/netmonitor/src/assets/styles/netmonitor.css
@@ -442,16 +442,22 @@ body,
 }
 
 /* Set Cookies column */
 
 .requests-list-set-cookies {
   width: 8%;
 }
 
+/* Scheme column */
+
+.requests-list-scheme {
+  width: 8%;
+}
+
 /* Domain column */
 
 .requests-list-domain {
   width: 13%;
 }
 
 .requests-list-domain.requests-list-column {
   text-align: start;
--- a/devtools/client/netmonitor/src/components/moz.build
+++ b/devtools/client/netmonitor/src/components/moz.build
@@ -15,16 +15,17 @@ DevToolsModules(
     'request-list-column-cause.js',
     'request-list-column-content-size.js',
     'request-list-column-cookies.js',
     'request-list-column-domain.js',
     'request-list-column-file.js',
     'request-list-column-method.js',
     'request-list-column-protocol.js',
     'request-list-column-remote-ip.js',
+    'request-list-column-scheme.js',
     'request-list-column-set-cookies.js',
     'request-list-column-status.js',
     'request-list-column-transferred-size.js',
     'request-list-column-type.js',
     'request-list-column-waterfall.js',
     'request-list-content.js',
     'request-list-empty-notice.js',
     'request-list-header.js',
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-scheme.js
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+
+const { div } = DOM;
+
+const RequestListColumnScheme = createClass({
+  displayName: "RequestListColumnScheme",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.item.urlDetails.scheme !== nextProps.item.urlDetails.scheme;
+  },
+
+  render() {
+    const { urlDetails } = this.props.item;
+    return (
+      div({
+        className: "requests-list-column requests-list-scheme",
+        title: urlDetails.scheme
+      },
+        urlDetails.scheme
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnScheme;
--- a/devtools/client/netmonitor/src/components/request-list-item.js
+++ b/devtools/client/netmonitor/src/components/request-list-item.js
@@ -17,16 +17,17 @@ const { propertiesEqual } = require("../
 const RequestListColumnCause = createFactory(require("./request-list-column-cause"));
 const RequestListColumnContentSize = createFactory(require("./request-list-column-content-size"));
 const RequestListColumnCookies = createFactory(require("./request-list-column-cookies"));
 const RequestListColumnDomain = createFactory(require("./request-list-column-domain"));
 const RequestListColumnFile = createFactory(require("./request-list-column-file"));
 const RequestListColumnMethod = createFactory(require("./request-list-column-method"));
 const RequestListColumnProtocol = createFactory(require("./request-list-column-protocol"));
 const RequestListColumnRemoteIP = createFactory(require("./request-list-column-remote-ip"));
+const RequestListColumnScheme = createFactory(require("./request-list-column-scheme"));
 const RequestListColumnSetCookies = createFactory(require("./request-list-column-set-cookies"));
 const RequestListColumnStatus = createFactory(require("./request-list-column-status"));
 const RequestListColumnTransferredSize = createFactory(require("./request-list-column-transferred-size"));
 const RequestListColumnType = createFactory(require("./request-list-column-type"));
 const RequestListColumnWaterfall = createFactory(require("./request-list-column-waterfall"));
 
 const { div } = DOM;
 
@@ -130,16 +131,17 @@ const RequestListItem = createClass({
         tabIndex: 0,
         onContextMenu,
         onMouseDown,
       },
         columns.get("status") && RequestListColumnStatus({ item }),
         columns.get("method") && RequestListColumnMethod({ item }),
         columns.get("file") && RequestListColumnFile({ item }),
         columns.get("protocol") && RequestListColumnProtocol({ item }),
+        columns.get("scheme") && RequestListColumnScheme({ item }),
         columns.get("domain") && RequestListColumnDomain({ item, onSecurityIconClick }),
         columns.get("remoteip") && RequestListColumnRemoteIP({ item }),
         columns.get("cause") && RequestListColumnCause({ item, onCauseBadgeClick }),
         columns.get("type") && RequestListColumnType({ item }),
         columns.get("cookies") && RequestListColumnCookies({ item }),
         columns.get("setCookies") && RequestListColumnSetCookies({ item }),
         columns.get("transferred") && RequestListColumnTransferredSize({ item }),
         columns.get("contentSize") && RequestListColumnContentSize({ item }),
--- a/devtools/client/netmonitor/src/constants.js
+++ b/devtools/client/netmonitor/src/constants.js
@@ -113,16 +113,20 @@ const HEADERS = [
     name: "file",
     canFilter: false,
   },
   {
     name: "protocol",
     canFilter: true,
   },
   {
+    name: "scheme",
+    canFilter: true,
+  },
+  {
     name: "domain",
     canFilter: true,
   },
   {
     name: "remoteip",
     canFilter: true,
     filterKey: "remote-ip",
   },
--- a/devtools/client/netmonitor/src/reducers/ui.js
+++ b/devtools/client/netmonitor/src/reducers/ui.js
@@ -18,16 +18,17 @@ const {
   WATERFALL_RESIZE,
 } = require("../constants");
 
 const Columns = I.Record({
   status: true,
   method: true,
   file: true,
   protocol: false,
+  scheme: false,
   domain: true,
   remoteip: false,
   cause: true,
   type: true,
   cookies: false,
   setCookies: false,
   transferred: true,
   contentSize: true,
--- a/devtools/client/netmonitor/src/utils/filter-text-utils.js
+++ b/devtools/client/netmonitor/src/utils/filter-text-utils.js
@@ -33,17 +33,16 @@
 const { HEADERS } = require("../constants");
 const { getFormattedIPAndPort } = require("./format-utils");
 const HEADER_FILTERS = HEADERS
   .filter(h => h.canFilter)
   .map(h => h.filterKey || h.name);
 
 const FILTER_FLAGS = [
   ...HEADER_FILTERS,
-  "scheme",
   "set-cookie-domain",
   "set-cookie-name",
   "set-cookie-value",
   "mime-type",
   "larger-than",
   "is",
   "has-response-header",
   "regexp",
@@ -177,18 +176,17 @@ function isFlagFilterMatch(item, { type,
       if (value === "from-cache" ||
           value === "cached") {
         match = item.fromCache || item.status === "304";
       } else if (value === "running") {
         match = !item.status;
       }
       break;
     case "scheme":
-      let scheme = new URL(item.url).protocol.replace(":", "").toLowerCase();
-      match = scheme === value;
+      match = item.urlDetails.scheme === value;
       break;
     case "regexp":
       try {
         let pattern = new RegExp(value);
         match = pattern.test(item.url);
       } catch (e) {
         match = false;
       }
--- a/devtools/client/netmonitor/src/utils/request-utils.js
+++ b/devtools/client/netmonitor/src/utils/request-utils.js
@@ -172,23 +172,35 @@ function getUrlHostName(url) {
  * @param {string} url - url string
  * @return {string} unicode host of a url
  */
 function getUrlHost(url) {
   return decodeUnicodeUrl((new URL(url)).host);
 }
 
 /**
+ * Helpers for getting the shceme portion of a url.
+ * For example helper returns "http" from http://domain.com/path/basename
+ *
+ * @param {string} url - url string
+ * @return {string} string scheme of a url
+ */
+function getUrlScheme(url) {
+  return (new URL(url)).protocol.replace(":", "").toLowerCase();
+}
+
+/**
  * Extract several details fields from a URL at once.
  */
 function getUrlDetails(url) {
   let baseNameWithQuery = getUrlBaseNameWithQuery(url);
   let host = getUrlHost(url);
   let hostname = getUrlHostName(url);
   let unicodeUrl = decodeUnicodeUrl(url);
+  let scheme = getUrlScheme(url);
 
   // Mark local hosts specially, where "local" is  as defined in the W3C
   // spec for secure contexts.
   // http://www.w3.org/TR/powerful-features/
   //
   //  * If the name falls under 'localhost'
   //  * If the name is an IPv4 address within 127.0.0.0/8
   //  * If the name is an IPv6 address within ::1/128
@@ -197,16 +209,17 @@ function getUrlDetails(url) {
   // been validated before it gets here.
   let isLocal = hostname.match(/(.+\.)?localhost$/) ||
                 hostname.match(/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}/) ||
                 hostname.match(/\[[0:]+1\]/);
 
   return {
     baseNameWithQuery,
     host,
+    scheme,
     unicodeUrl,
     isLocal
   };
 }
 
 /**
  * Parse a url's query string into its components
  *
@@ -291,18 +304,19 @@ function propertiesEqual(props, item1, i
 module.exports = {
   getFormDataSections,
   fetchHeaders,
   formDataURI,
   writeHeaderText,
   decodeUnicodeUrl,
   getAbbreviatedMimeType,
   getUrlBaseName,
-  getUrlQuery,
   getUrlBaseNameWithQuery,
+  getUrlDetails,
+  getUrlHost,
   getUrlHostName,
-  getUrlHost,
-  getUrlDetails,
+  getUrlQuery,
+  getUrlScheme,
   parseQueryString,
   parseFormData,
   propertiesEqual,
   ipToLong,
 };
--- a/devtools/client/netmonitor/src/utils/sort-predicates.js
+++ b/devtools/client/netmonitor/src/utils/sort-predicates.js
@@ -51,16 +51,21 @@ function file(first, second) {
   return result || waterfall(first, second);
 }
 
 function protocol(first, second) {
   const result = compareValues(first.httpVersion, second.httpVersion);
   return result || waterfall(first, second);
 }
 
+function scheme(first, second) {
+  const result = compareValues(first.urlDetails.scheme, second.urlDetails.scheme);
+  return result || waterfall(first, second);
+}
+
 function domain(first, second) {
   const firstDomain = first.urlDetails.host.toLowerCase();
   const secondDomain = second.urlDetails.host.toLowerCase();
   const result = compareValues(firstDomain, secondDomain);
   return result || waterfall(first, second);
 }
 
 function remoteip(first, second) {
@@ -114,16 +119,17 @@ function contentSize(first, second) {
   return result || waterfall(first, second);
 }
 
 exports.Sorters = {
   status,
   method,
   file,
   protocol,
+  scheme,
   cookies,
   setCookies,
   domain,
   remoteip,
   cause,
   type,
   transferred,
   contentSize,
--- a/devtools/client/netmonitor/test/head.js
+++ b/devtools/client/netmonitor/test/head.js
@@ -15,18 +15,19 @@ Services.scriptloader.loadSubScript(
 
 const { EVENTS } = require("devtools/client/netmonitor/src/constants");
 const {
   getFormattedIPAndPort
 } = require("devtools/client/netmonitor/src/utils/format-utils");
 const {
   decodeUnicodeUrl,
   getUrlBaseName,
+  getUrlHost,
   getUrlQuery,
-  getUrlHost,
+  getUrlScheme,
 } = require("devtools/client/netmonitor/src/utils/request-utils");
 
 /* eslint-disable no-unused-vars, max-len */
 const EXAMPLE_URL = "http://example.com/browser/devtools/client/netmonitor/test/";
 const HTTPS_EXAMPLE_URL = "https://example.com/browser/devtools/client/netmonitor/test/";
 
 const API_CALLS_URL = EXAMPLE_URL + "html_api-calls-test-page.html";
 const SIMPLE_URL = EXAMPLE_URL + "html_simple-test-page.html";
@@ -375,16 +376,17 @@ function verifyRequestItemTarget(documen
   let { fuzzyUrl, status, statusText, cause, type, fullMimeType,
         transferred, size, time, displayedStatus } = data;
 
   let target = document.querySelectorAll(".request-list-item")[visibleIndex];
   let unicodeUrl = decodeUnicodeUrl(url);
   let name = getUrlBaseName(url);
   let query = getUrlQuery(url);
   let host = getUrlHost(url);
+  let scheme = getUrlScheme(url);
   let { httpVersion = "", remoteAddress, remotePort } = requestItem;
   let formattedIPPort = getFormattedIPAndPort(remoteAddress, remotePort);
   let remoteIP = remoteAddress ? `${formattedIPPort}` : "unknown";
 
   if (fuzzyUrl) {
     ok(requestItem.method.startsWith(method), "The attached method is correct.");
     ok(requestItem.url.startsWith(url), "The attached url is correct.");
   } else {
@@ -422,16 +424,22 @@ function verifyRequestItemTarget(documen
     domainTooltip, "The tooltip domain is correct.");
 
   is(target.querySelector(".requests-list-remoteip").textContent,
     remoteIP, "The displayed remote IP is correct.");
 
   is(target.querySelector(".requests-list-remoteip").getAttribute("title"),
     remoteIP, "The tooltip remote IP is correct.");
 
+  is(target.querySelector(".requests-list-scheme").textContent,
+    scheme, "The displayed scheme is correct.");
+
+  is(target.querySelector(".requests-list-scheme").getAttribute("title"),
+    scheme, "The tooltip scheme is correct.");
+
   if (status !== undefined) {
     let value = target.querySelector(".requests-list-status-icon")
                       .getAttribute("data-code");
     let codeValue = target.querySelector(".requests-list-status-code").textContent;
     let tooltip = target.querySelector(".requests-list-status").getAttribute("title");
     info("Displayed status: " + value);
     info("Displayed code: " + codeValue);
     info("Tooltip status: " + tooltip);
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -145,17 +145,18 @@ pref("devtools.serviceWorkers.testing.en
 
 // Enable the Network Monitor
 pref("devtools.netmonitor.enabled", true);
 
 // The default Network Monitor UI settings
 pref("devtools.netmonitor.panes-network-details-width", 550);
 pref("devtools.netmonitor.panes-network-details-height", 450);
 pref("devtools.netmonitor.filters", "[\"all\"]");
-pref("devtools.netmonitor.hiddenColumns", "[\"cookies\",\"protocol\",\"remoteip\",\"setCookies\"]");
+pref("devtools.netmonitor.hiddenColumns",
+  "[\"cookies\",\"protocol\",\"remoteip\",\"scheme\",\"setCookies\"]");
 
 // The default Network monitor HAR export setting
 pref("devtools.netmonitor.har.defaultLogDir", "");
 pref("devtools.netmonitor.har.defaultFileName", "Archive %date");
 pref("devtools.netmonitor.har.jsonp", false);
 pref("devtools.netmonitor.har.jsonpCallback", "");
 pref("devtools.netmonitor.har.includeResponseBodies", true);
 pref("devtools.netmonitor.har.compress", false);
--- a/devtools/client/responsivedesign/responsivedesign.jsm
+++ b/devtools/client/responsivedesign/responsivedesign.jsm
@@ -14,16 +14,18 @@ const EventEmitter = require("devtools/s
 
 loader.lazyImporter(this, "SystemAppProxy",
                     "resource://gre/modules/SystemAppProxy.jsm");
 loader.lazyImporter(this, "BrowserUtils",
                     "resource://gre/modules/BrowserUtils.jsm");
 loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
 loader.lazyRequireGetter(this, "showDoorhanger",
                          "devtools/client/shared/doorhanger", true);
+loader.lazyRequireGetter(this, "gDevToolsBrowser",
+                         "devtools/client/framework/devtools-browser", true);
 loader.lazyRequireGetter(this, "TouchEventSimulator",
                          "devtools/shared/touch/simulator", true);
 loader.lazyRequireGetter(this, "flags",
                          "devtools/shared/flags");
 loader.lazyRequireGetter(this, "EmulationFront",
                          "devtools/shared/fronts/emulation", true);
 loader.lazyRequireGetter(this, "DebuggerClient",
                          "devtools/shared/client/main", true);
@@ -222,16 +224,18 @@ ResponsiveUI.prototype = {
   },
 
   init: Task.async(function* () {
     debug("INIT BEGINS");
     let ready = this.waitForMessage("ResponsiveMode:ChildScriptReady");
     this.mm.loadFrameScript("resource://devtools/client/responsivedesign/responsivedesign-child.js", true);
     yield ready;
 
+    yield gDevToolsBrowser.loadBrowserStyleSheet(this.mainWindow);
+
     let requiresFloatingScrollbars =
       !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
     let started = this.waitForMessage("ResponsiveMode:Start:Done");
     debug("SEND START");
     this.mm.sendAsyncMessage("ResponsiveMode:Start", {
       requiresFloatingScrollbars,
       // Tests expect events on resize to yield on various size changes
       notifyOnResize: flags.testing,
--- a/devtools/client/shared/developer-toolbar.js
+++ b/devtools/client/shared/developer-toolbar.js
@@ -373,16 +373,19 @@ DeveloperToolbar.prototype.show = functi
 
   this._showPromise = Task.spawn((function* () {
     // hide() is async, so ensure we don't need to wait for hide() to
     // finish.  We unconditionally yield here, even if _hidePromise is
     // null, so that the spawn call returns a promise before starting
     // to do any real work.
     yield this._hidePromise;
 
+    // Append the browser-level stylesheet to the browser document.
+    yield gDevToolsBrowser.loadBrowserStyleSheet(this._chromeWindow);
+
     this.createToolbar();
 
     Services.prefs.setBoolPref("devtools.toolbar.visible", true);
 
     this._telemetry.toolOpened("developertoolbar");
 
     this._notify(NOTIFICATIONS.LOAD);
 
--- a/devtools/client/shared/moz.build
+++ b/devtools/client/shared/moz.build
@@ -44,16 +44,17 @@ DevToolsModules(
     'options-view.js',
     'output-parser.js',
     'poller.js',
     'prefs.js',
     'react-utils.js',
     'scroll.js',
     'source-utils.js',
     'SplitView.jsm',
+    'stylesheet-utils.js',
     'suggestion-picker.js',
     'telemetry.js',
     'theme.js',
     'undo.js',
     'view-source.js',
     'webgl-utils.js',
     'zoom-keys.js',
 )
--- a/devtools/client/shared/source-map/index.js
+++ b/devtools/client/shared/source-map/index.js
@@ -1,18 +1,18 @@
 (function webpackUniversalModuleDefinition(root, factory) {
 	if(typeof exports === 'object' && typeof module === 'object')
-		module.exports = factory(require("Services"), require("devtools/client/shared/vendor/react"), require("devtools/client/shared/vendor/react-dom"), require("devtools/shared/flags"));
+		module.exports = factory();
 	else if(typeof define === 'function' && define.amd)
-		define(["Services", "devtools/client/shared/vendor/react", "devtools/client/shared/vendor/react-dom", "devtools/shared/flags"], factory);
+		define([], factory);
 	else {
-		var a = typeof exports === 'object' ? factory(require("Services"), require("devtools/client/shared/vendor/react"), require("devtools/client/shared/vendor/react-dom"), require("devtools/shared/flags")) : factory(root["Services"], root["devtools/client/shared/vendor/react"], root["devtools/client/shared/vendor/react-dom"], root["devtools/shared/flags"]);
+		var a = factory();
 		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
 	}
-})(this, function(__WEBPACK_EXTERNAL_MODULE_7__, __WEBPACK_EXTERNAL_MODULE_9__, __WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_83__) {
+})(this, function() {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
 
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 
 /******/ 		// Check if module is in cache
@@ -49,90 +49,49 @@ return /******/ (function(modules) { // 
 /******/ 	// Load entry module and return exports
 /******/ 	return __webpack_require__(0);
 /******/ })
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ function(module, exports, __webpack_require__) {
 
-	let hasMappedSource = (() => {
-	  var _ref = _asyncToGenerator(function* (location) {
-	    if (isOriginalId(location.sourceId)) {
-	      return true;
-	    }
-
-	    const loc = yield getOriginalLocation(location);
-	    return loc.sourceId !== location.sourceId;
-	  });
-
-	  return function hasMappedSource(_x) {
-	    return _ref.apply(this, arguments);
-	  };
-	})();
-
-	function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
-
-	/* global DebuggerConfig */
-
 	const {
 	  originalToGeneratedId,
 	  generatedToOriginalId,
 	  isGeneratedId,
 	  isOriginalId
 	} = __webpack_require__(1);
 
-	const { workerUtils: { workerTask } } = __webpack_require__(6);
-	const { setConfig, getValue } = __webpack_require__(20);
+	const { workerUtils: { WorkerDispatcher } } = __webpack_require__(6);
 
-	// TODO: Rename this to something not specific to debugger (#265)
-	// $FlowIgnore: global DebuggerConfig
-	setConfig(({"workers":{"sourceMapURL":"resource://devtools/client/shared/source-map/worker.js"}}));
-
-	let sourceMapWorker;
-	function restartWorker() {
-	  if (sourceMapWorker) {
-	    sourceMapWorker.terminate();
-	  }
+	const dispatcher = new WorkerDispatcher();
 
-	  sourceMapWorker = new Worker(getValue("workers.sourceMapURL"));
-	  sourceMapWorker.onerror = () => {
-	    console.error("Error in source map worker");
-	  };
-	}
-
-	restartWorker();
-
-	function destroyWorker() {
-	  if (sourceMapWorker) {
-	    sourceMapWorker.terminate();
-	    sourceMapWorker = null;
-	  }
-	}
-
-	const getOriginalURLs = workerTask(sourceMapWorker, "getOriginalURLs");
-	const getGeneratedLocation = workerTask(sourceMapWorker, "getGeneratedLocation");
-	const getOriginalLocation = workerTask(sourceMapWorker, "getOriginalLocation");
-	const getOriginalSourceText = workerTask(sourceMapWorker, "getOriginalSourceText");
-	const applySourceMap = workerTask(sourceMapWorker, "applySourceMap");
-	const clearSourceMaps = workerTask(sourceMapWorker, "clearSourceMaps");
+	const getOriginalURLs = dispatcher.task("getOriginalURLs");
+	const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
+	const getOriginalLocation = dispatcher.task("getOriginalLocation");
+	const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
+	const applySourceMap = dispatcher.task("applySourceMap");
+	const clearSourceMaps = dispatcher.task("clearSourceMaps");
+	const hasMappedSource = dispatcher.task("hasMappedSource");
 
 	module.exports = {
 	  originalToGeneratedId,
 	  generatedToOriginalId,
 	  isGeneratedId,
 	  isOriginalId,
 	  hasMappedSource,
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
 	  getOriginalSourceText,
 	  applySourceMap,
 	  clearSourceMaps,
-	  destroyWorker
+	  startSourceMapWorker: dispatcher.start.bind(dispatcher),
+	  stopSourceMapWorker: dispatcher.stop.bind(dispatcher)
 	};
 
 /***/ },
 /* 1 */
 /***/ function(module, exports, __webpack_require__) {
 
 	const md5 = __webpack_require__(2);
 
@@ -161,231 +120,220 @@ return /******/ (function(modules) { // 
 	  let q1 = url.indexOf("?");
 	  let q2 = url.indexOf("&");
 	  let q3 = url.indexOf("#");
 	  let q = Math.min(q1 != -1 ? q1 : length, q2 != -1 ? q2 : length, q3 != -1 ? q3 : length);
 
 	  return url.slice(0, q);
 	}
 
-	/**
-	 * Returns true if the specified URL and/or content type are specific to
-	 * JavaScript files.
-	 *
-	 * @return boolean
-	 *         True if the source is likely JavaScript.
-	 */
-	function isJavaScript(url, contentType = "") {
-	  return url && /\.(jsm|js)?$/.test(trimUrlQuery(url)) || contentType.includes("javascript");
-	}
-
-	function getContentType(url) {
-	  if (isJavaScript(url)) {
-	    return "text/javascript";
-	  }
-
-	  if (url.match(/ts$/)) {
-	    return "text/typescript";
-	  }
+	// Map suffix to content type.
+	const contentMap = {
+	  "js": "text/javascript",
+	  "jsm": "text/javascript",
+	  "ts": "text/typescript",
+	  "tsx": "text/typescript-jsx",
+	  "jsx": "text/jsx",
+	  "coffee": "text/coffeescript",
+	  "elm": "text/elm",
+	  "cljs": "text/x-clojure"
+	};
 
-	  if (url.match(/tsx$/)) {
-	    return "text/typescript-jsx";
-	  }
-
-	  if (url.match(/jsx$/)) {
-	    return "text/jsx";
+	/**
+	 * Returns the content type for the specified URL.  If no specific
+	 * content type can be determined, "text/plain" is returned.
+	 *
+	 * @return String
+	 *         The content type.
+	 */
+	function getContentType(url) {
+	  url = trimUrlQuery(url);
+	  let dot = url.lastIndexOf(".");
+	  if (dot >= 0) {
+	    let name = url.substring(dot + 1);
+	    if (name in contentMap) {
+	      return contentMap[name];
+	    }
 	  }
-
-	  if (url.match(/coffee$/)) {
-	    return "text/coffeescript";
-	  }
-
-	  if (url.match(/elm$/)) {
-	    return "text/elm";
-	  }
-
-	  if (url.match(/cljs$/)) {
-	    return "text/x-clojure";
-	  }
-
 	  return "text/plain";
 	}
 
 	module.exports = {
 	  originalToGeneratedId,
 	  generatedToOriginalId,
 	  isOriginalId,
 	  isGeneratedId,
-	  getContentType
+	  getContentType,
+	  contentMapForTesting: contentMap
 	};
 
 /***/ },
 /* 2 */
 /***/ function(module, exports, __webpack_require__) {
 
-	(function(){
-	  var crypt = __webpack_require__(3),
-	      utf8 = __webpack_require__(4).utf8,
-	      isBuffer = __webpack_require__(5),
-	      bin = __webpack_require__(4).bin,
-
-	  // The core
-	  md5 = function (message, options) {
-	    // Convert to byte array
-	    if (message.constructor == String)
-	      if (options && options.encoding === 'binary')
-	        message = bin.stringToBytes(message);
-	      else
-	        message = utf8.stringToBytes(message);
-	    else if (isBuffer(message))
-	      message = Array.prototype.slice.call(message, 0);
-	    else if (!Array.isArray(message))
-	      message = message.toString();
-	    // else, assume byte array already
-
-	    var m = crypt.bytesToWords(message),
-	        l = message.length * 8,
-	        a =  1732584193,
-	        b = -271733879,
-	        c = -1732584194,
-	        d =  271733878;
-
-	    // Swap endian
-	    for (var i = 0; i < m.length; i++) {
-	      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
-	             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
-	    }
-
-	    // Padding
-	    m[l >>> 5] |= 0x80 << (l % 32);
-	    m[(((l + 64) >>> 9) << 4) + 14] = l;
-
-	    // Method shortcuts
-	    var FF = md5._ff,
-	        GG = md5._gg,
-	        HH = md5._hh,
-	        II = md5._ii;
-
-	    for (var i = 0; i < m.length; i += 16) {
-
-	      var aa = a,
-	          bb = b,
-	          cc = c,
-	          dd = d;
-
-	      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
-	      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
-	      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
-	      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
-	      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
-	      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
-	      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
-	      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
-	      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
-	      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
-	      c = FF(c, d, a, b, m[i+10], 17, -42063);
-	      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
-	      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
-	      d = FF(d, a, b, c, m[i+13], 12, -40341101);
-	      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
-	      b = FF(b, c, d, a, m[i+15], 22,  1236535329);
-
-	      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
-	      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
-	      c = GG(c, d, a, b, m[i+11], 14,  643717713);
-	      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
-	      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
-	      d = GG(d, a, b, c, m[i+10],  9,  38016083);
-	      c = GG(c, d, a, b, m[i+15], 14, -660478335);
-	      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
-	      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
-	      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
-	      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
-	      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
-	      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
-	      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
-	      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
-	      b = GG(b, c, d, a, m[i+12], 20, -1926607734);
-
-	      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
-	      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
-	      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
-	      b = HH(b, c, d, a, m[i+14], 23, -35309556);
-	      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
-	      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
-	      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
-	      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
-	      a = HH(a, b, c, d, m[i+13],  4,  681279174);
-	      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
-	      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
-	      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
-	      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
-	      d = HH(d, a, b, c, m[i+12], 11, -421815835);
-	      c = HH(c, d, a, b, m[i+15], 16,  530742520);
-	      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
-
-	      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
-	      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
-	      c = II(c, d, a, b, m[i+14], 15, -1416354905);
-	      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
-	      a = II(a, b, c, d, m[i+12],  6,  1700485571);
-	      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
-	      c = II(c, d, a, b, m[i+10], 15, -1051523);
-	      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
-	      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
-	      d = II(d, a, b, c, m[i+15], 10, -30611744);
-	      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
-	      b = II(b, c, d, a, m[i+13], 21,  1309151649);
-	      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
-	      d = II(d, a, b, c, m[i+11], 10, -1120210379);
-	      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
-	      b = II(b, c, d, a, m[i+ 9], 21, -343485551);
-
-	      a = (a + aa) >>> 0;
-	      b = (b + bb) >>> 0;
-	      c = (c + cc) >>> 0;
-	      d = (d + dd) >>> 0;
-	    }
-
-	    return crypt.endian([a, b, c, d]);
-	  };
-
-	  // Auxiliary functions
-	  md5._ff  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._gg  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._hh  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._ii  = function (a, b, c, d, x, s, t) {
-	    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-
-	  // Package private blocksize
-	  md5._blocksize = 16;
-	  md5._digestsize = 16;
-
-	  module.exports = function (message, options) {
-	    if (message === undefined || message === null)
-	      throw new Error('Illegal argument ' + message);
-
-	    var digestbytes = crypt.wordsToBytes(md5(message, options));
-	    return options && options.asBytes ? digestbytes :
-	        options && options.asString ? bin.bytesToString(digestbytes) :
-	        crypt.bytesToHex(digestbytes);
-	  };
-
-	})();
+	(function(){
+	  var crypt = __webpack_require__(3),
+	      utf8 = __webpack_require__(4).utf8,
+	      isBuffer = __webpack_require__(5),
+	      bin = __webpack_require__(4).bin,
+
+	  // The core
+	  md5 = function (message, options) {
+	    // Convert to byte array
+	    if (message.constructor == String)
+	      if (options && options.encoding === 'binary')
+	        message = bin.stringToBytes(message);
+	      else
+	        message = utf8.stringToBytes(message);
+	    else if (isBuffer(message))
+	      message = Array.prototype.slice.call(message, 0);
+	    else if (!Array.isArray(message))
+	      message = message.toString();
+	    // else, assume byte array already
+
+	    var m = crypt.bytesToWords(message),
+	        l = message.length * 8,
+	        a =  1732584193,
+	        b = -271733879,
+	        c = -1732584194,
+	        d =  271733878;
+
+	    // Swap endian
+	    for (var i = 0; i < m.length; i++) {
+	      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
+	             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
+	    }
+
+	    // Padding
+	    m[l >>> 5] |= 0x80 << (l % 32);
+	    m[(((l + 64) >>> 9) << 4) + 14] = l;
+
+	    // Method shortcuts
+	    var FF = md5._ff,
+	        GG = md5._gg,
+	        HH = md5._hh,
+	        II = md5._ii;
+
+	    for (var i = 0; i < m.length; i += 16) {
+
+	      var aa = a,
+	          bb = b,
+	          cc = c,
+	          dd = d;
+
+	      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
+	      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
+	      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
+	      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
+	      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
+	      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
+	      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
+	      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
+	      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
+	      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
+	      c = FF(c, d, a, b, m[i+10], 17, -42063);
+	      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
+	      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
+	      d = FF(d, a, b, c, m[i+13], 12, -40341101);
+	      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
+	      b = FF(b, c, d, a, m[i+15], 22,  1236535329);
+
+	      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
+	      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
+	      c = GG(c, d, a, b, m[i+11], 14,  643717713);
+	      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
+	      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
+	      d = GG(d, a, b, c, m[i+10],  9,  38016083);
+	      c = GG(c, d, a, b, m[i+15], 14, -660478335);
+	      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
+	      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
+	      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
+	      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
+	      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
+	      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
+	      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
+	      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
+	      b = GG(b, c, d, a, m[i+12], 20, -1926607734);
+
+	      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
+	      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
+	      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
+	      b = HH(b, c, d, a, m[i+14], 23, -35309556);
+	      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
+	      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
+	      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
+	      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
+	      a = HH(a, b, c, d, m[i+13],  4,  681279174);
+	      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
+	      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
+	      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
+	      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
+	      d = HH(d, a, b, c, m[i+12], 11, -421815835);
+	      c = HH(c, d, a, b, m[i+15], 16,  530742520);
+	      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
+
+	      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
+	      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
+	      c = II(c, d, a, b, m[i+14], 15, -1416354905);
+	      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
+	      a = II(a, b, c, d, m[i+12],  6,  1700485571);
+	      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
+	      c = II(c, d, a, b, m[i+10], 15, -1051523);
+	      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
+	      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
+	      d = II(d, a, b, c, m[i+15], 10, -30611744);
+	      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
+	      b = II(b, c, d, a, m[i+13], 21,  1309151649);
+	      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
+	      d = II(d, a, b, c, m[i+11], 10, -1120210379);
+	      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
+	      b = II(b, c, d, a, m[i+ 9], 21, -343485551);
+
+	      a = (a + aa) >>> 0;
+	      b = (b + bb) >>> 0;
+	      c = (c + cc) >>> 0;
+	      d = (d + dd) >>> 0;
+	    }
+
+	    return crypt.endian([a, b, c, d]);
+	  };
+
+	  // Auxiliary functions
+	  md5._ff  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._gg  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._hh  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._ii  = function (a, b, c, d, x, s, t) {
+	    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+
+	  // Package private blocksize
+	  md5._blocksize = 16;
+	  md5._digestsize = 16;
+
+	  module.exports = function (message, options) {
+	    if (message === undefined || message === null)
+	      throw new Error('Illegal argument ' + message);
+
+	    var digestbytes = crypt.wordsToBytes(md5(message, options));
+	    return options && options.asBytes ? digestbytes :
+	        options && options.asString ? bin.bytesToString(digestbytes) :
+	        crypt.bytesToHex(digestbytes);
+	  };
+
+	})();
 
 
 /***/ },
 /* 3 */
 /***/ function(module, exports) {
 
 	(function() {
 	  var base64map
@@ -550,2936 +498,124 @@ return /******/ (function(modules) { // 
 	  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
 	}
 
 
 /***/ },
 /* 6 */
 /***/ function(module, exports, __webpack_require__) {
 
-	const Services = __webpack_require__(7);
-	const SplitBox = __webpack_require__(8);
-	// const SplitBoxCSS = require("./client/shared/components/splitter/SplitBox.css")
-	const sprintf = __webpack_require__(12).sprintf;
-	const workerUtils = __webpack_require__(19);
+	const networkRequest = __webpack_require__(7);
+	const workerUtils = __webpack_require__(8);
 
 	module.exports = {
-	  Services,
-	  SplitBox,
-	  // SplitBoxCSS,
-	  sprintf,
+	  networkRequest,
 	  workerUtils
 	};
 
 /***/ },
 /* 7 */
 /***/ function(module, exports) {
 
-	module.exports = __WEBPACK_EXTERNAL_MODULE_7__;
+	function networkRequest(url, opts) {
+	  return new Promise((resolve, reject) => {
+	    const req = new XMLHttpRequest();
+
+	    req.addEventListener("readystatechange", () => {
+	      if (req.readyState === XMLHttpRequest.DONE) {
+	        if (req.status === 200) {
+	          resolve({ content: req.responseText });
+	        } else {
+	          resolve(req.statusText);
+	        }
+	      }
+	    });
+
+	    // Not working yet.
+	    // if (!opts.loadFromCache) {
+	    //   req.channel.loadFlags = (
+	    //     Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE |
+	    //       Components.interfaces.nsIRequest.INHIBIT_CACHING |
+	    //       Components.interfaces.nsIRequest.LOAD_ANONYMOUS
+	    //   );
+	    // }
+
+	    req.open("GET", url);
+	    req.send();
+	  });
+	}
+
+	module.exports = networkRequest;
 
 /***/ },
 /* 8 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ function(module, exports) {
 
-	const React = __webpack_require__(9);
-	const ReactDOM = __webpack_require__(10);
-	const Draggable = React.createFactory(__webpack_require__(11));
-	const { DOM: dom, PropTypes } = React;
-
-	/**
-	 * This component represents a Splitter. The splitter supports vertical
-	 * as well as horizontal mode.
-	 */
-	const SplitBox = React.createClass({
+	
 
-	  propTypes: {
-	    // Custom class name. You can use more names separated by a space.
-	    className: PropTypes.string,
-	    // Initial size of controlled panel.
-	    initialSize: PropTypes.any,
-	    // Optional initial width of controlled panel.
-	    initialWidth: PropTypes.number,
-	    // Optional initial height of controlled panel.
-	    initialHeight: PropTypes.number,
-	    // Left/top panel
-	    startPanel: PropTypes.any,
-	    // Left/top panel collapse state.
-	    startPanelCollapsed: PropTypes.bool,
-	    // Min panel size.
-	    minSize: PropTypes.any,
-	    // Max panel size.
-	    maxSize: PropTypes.any,
-	    // Right/bottom panel
-	    endPanel: PropTypes.any,
-	    // Right/bottom panel collapse state.
-	    endPanelCollapsed: PropTypes.bool,
-	    // True if the right/bottom panel should be controlled.
-	    endPanelControl: PropTypes.bool,
-	    // Size of the splitter handle bar.
-	    splitterSize: PropTypes.number,
-	    // True if the splitter bar is vertical (default is vertical).
-	    vert: PropTypes.bool,
-	    // Optional style properties passed into the splitbox
-	    style: PropTypes.object
-	  },
+	function WorkerDispatcher() {
+	  this.msgId = 1;
+	  this.worker = null;
+	}
 
-	  displayName: "SplitBox",
-
-	  getDefaultProps() {
-	    return {
-	      splitterSize: 5,
-	      vert: true,
-	      endPanelControl: false,
-	      endPanelCollapsed: false,
-	      startPanelCollapsed: false
-	    };
-	  },
-
-	  /**
-	   * The state stores the current orientation (vertical or horizontal)
-	   * and the current size (width/height). All these values can change
-	   * during the component's life time.
-	   */
-	  getInitialState() {
-	    return {
-	      vert: this.props.vert,
-	      // We use integers for these properties
-	      width: parseInt(this.props.initialWidth || this.props.initialSize),
-	      height: parseInt(this.props.initialHeight || this.props.initialSize)
+	WorkerDispatcher.prototype = {
+	  start(url) {
+	    this.worker = new Worker(url);
+	    this.worker.onerror = () => {
+	      console.error(`Error in worker ${url}`);
 	    };
 	  },
 
-	  componentWillReceiveProps(nextProps) {
-	    if (this.props.vert !== nextProps.vert) {
-	      this.setState({ vert: nextProps.vert });
-	    }
-	  },
-
-	  // Dragging Events
-
-	  /**
-	   * Set 'resizing' cursor on entire document during splitter dragging.
-	   * This avoids cursor-flickering that happens when the mouse leaves
-	   * the splitter bar area (happens frequently).
-	   */
-	  onStartMove() {
-	    const splitBox = ReactDOM.findDOMNode(this);
-	    const doc = splitBox.ownerDocument;
-	    let defaultCursor = doc.documentElement.style.cursor;
-	    doc.documentElement.style.cursor = this.state.vert ? "ew-resize" : "ns-resize";
-
-	    splitBox.classList.add("dragging");
-
-	    this.setState({
-	      defaultCursor: defaultCursor
-	    });
-	  },
-
-	  onStopMove() {
-	    const splitBox = ReactDOM.findDOMNode(this);
-	    const doc = splitBox.ownerDocument;
-	    doc.documentElement.style.cursor = this.state.defaultCursor;
-
-	    splitBox.classList.remove("dragging");
-	  },
-
-	  /**
-	   * Adjust size of the controlled panel. Depending on the current
-	   * orientation we either remember the width or height of
-	   * the splitter box.
-	   */
-	  onMove({ movementX, movementY }) {
-	    const node = ReactDOM.findDOMNode(this);
-	    const doc = node.ownerDocument;
-
-	    if (this.props.endPanelControl) {
-	      // For the end panel we need to increase the width/height when the
-	      // movement is towards the left/top.
-	      movementX = -movementX;
-	      movementY = -movementY;
+	  stop() {
+	    if (!this.worker) {
+	      return;
 	    }
 
-	    if (this.state.vert) {
-	      const isRtl = doc.dir === "rtl";
-	      if (isRtl) {
-	        // In RTL we need to reverse the movement again -- but only for vertical
-	        // splitters
-	        movementX = -movementX;
-	      }
-
-	      this.setState((state, props) => ({
-	        width: state.width + movementX
-	      }));
-	    } else {
-	      this.setState((state, props) => ({
-	        height: state.height + movementY
-	      }));
-	    }
-	  },
-
-	  // Rendering
-	  preparePanelStyles() {
-	    const vert = this.state.vert;
-	    const {
-	      minSize, maxSize, startPanelCollapsed, endPanelControl,
-	      endPanelCollapsed } = this.props;
-	    let leftPanelStyle, rightPanelStyle;
-
-	    // Set proper size for panels depending on the current state.
-	    if (vert) {
-	      let startWidth = endPanelControl ? null : this.state.width,
-	          endWidth = endPanelControl ? this.state.width : null;
-
-	      leftPanelStyle = {
-	        maxWidth: endPanelControl ? null : maxSize,
-	        minWidth: endPanelControl ? null : minSize,
-	        width: startPanelCollapsed ? 0 : startWidth
-	      };
-	      rightPanelStyle = {
-	        maxWidth: endPanelControl ? maxSize : null,
-	        minWidth: endPanelControl ? minSize : null,
-	        width: endPanelCollapsed ? 0 : endWidth
-	      };
-	    } else {
-	      let startHeight = endPanelControl ? null : this.state.height,
-	          endHeight = endPanelControl ? this.state.height : null;
-
-	      leftPanelStyle = {
-	        maxHeight: endPanelControl ? null : maxSize,
-	        minHeight: endPanelControl ? null : minSize,
-	        height: endPanelCollapsed ? maxSize : startHeight
-	      };
-	      rightPanelStyle = {
-	        maxHeight: endPanelControl ? maxSize : null,
-	        minHeight: endPanelControl ? minSize : null,
-	        height: startPanelCollapsed ? maxSize : endHeight
-	      };
-	    }
-
-	    return { leftPanelStyle, rightPanelStyle };
-	  },
-
-	  render() {
-	    const vert = this.state.vert;
-	    const {
-	      startPanelCollapsed,
-	      startPanel,
-	      endPanel,
-	      endPanelControl,
-	      splitterSize,
-	      endPanelCollapsed
-	    } = this.props;
-
-	    let style = Object.assign({}, this.props.style);
-
-	    // Calculate class names list.
-	    let classNames = ["split-box"];
-	    classNames.push(vert ? "vert" : "horz");
-	    if (this.props.className) {
-	      classNames = classNames.concat(this.props.className.split(" "));
-	    }
-
-	    const { leftPanelStyle, rightPanelStyle } = this.preparePanelStyles();
-
-	    // Calculate splitter size
-	    let splitterStyle = {
-	      flex: `0 0 ${splitterSize}px`
-	    };
-
-	    return dom.div({
-	      className: classNames.join(" "),
-	      style: style }, !startPanelCollapsed ? dom.div({
-	      className: endPanelControl ? "uncontrolled" : "controlled",
-	      style: leftPanelStyle }, startPanel) : null, Draggable({
-	      className: "splitter",
-	      style: splitterStyle,
-	      onStart: this.onStartMove,
-	      onStop: this.onStopMove,
-	      onMove: this.onMove
-	    }), !endPanelCollapsed ? dom.div({
-	      className: endPanelControl ? "controlled" : "uncontrolled",
-	      style: rightPanelStyle }, endPanel) : null);
-	  }
-	});
-
-	module.exports = SplitBox;
-
-/***/ },
-/* 9 */
-/***/ function(module, exports) {
-
-	module.exports = __WEBPACK_EXTERNAL_MODULE_9__;
-
-/***/ },
-/* 10 */
-/***/ function(module, exports) {
-
-	module.exports = __WEBPACK_EXTERNAL_MODULE_10__;
-
-/***/ },
-/* 11 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/* This Source Code Form is subject to the terms of the Mozilla Public
-	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
-	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-	const React = __webpack_require__(9);
-	const ReactDOM = __webpack_require__(10);
-	const { DOM: dom, PropTypes } = React;
-
-	const Draggable = React.createClass({
-	  displayName: "Draggable",
-
-	  propTypes: {
-	    onMove: PropTypes.func.isRequired,
-	    onStart: PropTypes.func,
-	    onStop: PropTypes.func,
-	    style: PropTypes.object,
-	    className: PropTypes.string
-	  },
-
-	  startDragging(ev) {
-	    ev.preventDefault();
-	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-	    doc.addEventListener("mousemove", this.onMove);
-	    doc.addEventListener("mouseup", this.onUp);
-	    this.props.onStart && this.props.onStart();
-	  },
-
-	  onMove(ev) {
-	    ev.preventDefault();
-	    // We pass the whole event because we don't know which properties
-	    // the callee needs.
-	    this.props.onMove(ev);
-	  },
-
-	  onUp(ev) {
-	    ev.preventDefault();
-	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-	    doc.removeEventListener("mousemove", this.onMove);
-	    doc.removeEventListener("mouseup", this.onUp);
-	    this.props.onStop && this.props.onStop();
+	    this.worker.terminate();
+	    this.worker = null;
 	  },
 
-	  render() {
-	    return dom.div({
-	      style: this.props.style,
-	      className: this.props.className,
-	      onMouseDown: this.startDragging
-	    });
-	  }
-	});
-
-	module.exports = Draggable;
-
-/***/ },
-/* 12 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/**
-	 * Copyright (c) 2007-2016, Alexandru Marasteanu <hello [at) alexei (dot] ro>
-	 * All rights reserved.
-	 *
-	 * Redistribution and use in source and binary forms, with or without
-	 * modification, are permitted provided that the following conditions are met:
-	 * * Redistributions of source code must retain the above copyright
-	 *   notice, this list of conditions and the following disclaimer.
-	 * * Redistributions in binary form must reproduce the above copyright
-	 *   notice, this list of conditions and the following disclaimer in the
-	 *   documentation and/or other materials provided with the distribution.
-	 * * Neither the name of this software nor the names of its contributors may be
-	 *   used to endorse or promote products derived from this software without
-	 *   specific prior written permission.
-	 *
-	 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-	 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-	 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-	 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
-	 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-	 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-	 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-	 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-	 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-	 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-	 *
-	 */
-
-	/* globals window, exports, define */
-
-	(function (window) {
-	    'use strict';
+	  task(method) {
+	    return (...args) => {
+	      return new Promise((resolve, reject) => {
+	        const id = this.msgId++;
+	        this.worker.postMessage({ id, method, args });
 
-	    var re = {
-	        not_string: /[^s]/,
-	        not_bool: /[^t]/,
-	        not_type: /[^T]/,
-	        not_primitive: /[^v]/,
-	        number: /[diefg]/,
-	        numeric_arg: /bcdiefguxX/,
-	        json: /[j]/,
-	        not_json: /[^j]/,
-	        text: /^[^\x25]+/,
-	        modulo: /^\x25{2}/,
-	        placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosStTuvxX])/,
-	        key: /^([a-z_][a-z_\d]*)/i,
-	        key_access: /^\.([a-z_][a-z_\d]*)/i,
-	        index_access: /^\[(\d+)\]/,
-	        sign: /^[\+\-]/
-	    };
-
-	    function sprintf() {
-	        var key = arguments[0],
-	            cache = sprintf.cache;
-	        if (!(cache[key] && cache.hasOwnProperty(key))) {
-	            cache[key] = sprintf.parse(key);
-	        }
-	        return sprintf.format.call(null, cache[key], arguments);
-	    }
-
-	    sprintf.format = function (parse_tree, argv) {
-	        var cursor = 1,
-	            tree_length = parse_tree.length,
-	            node_type = '',
-	            arg,
-	            output = [],
-	            i,
-	            k,
-	            match,
-	            pad,
-	            pad_character,
-	            pad_length,
-	            is_positive = true,
-	            sign = '';
-	        for (i = 0; i < tree_length; i++) {
-	            node_type = get_type(parse_tree[i]);
-	            if (node_type === 'string') {
-	                output[output.length] = parse_tree[i];
-	            } else if (node_type === 'array') {
-	                match = parse_tree[i]; // convenience purposes only
-	                if (match[2]) {
-	                    // keyword argument
-	                    arg = argv[cursor];
-	                    for (k = 0; k < match[2].length; k++) {
-	                        if (!arg.hasOwnProperty(match[2][k])) {
-	                            throw new Error(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
-	                        }
-	                        arg = arg[match[2][k]];
-	                    }
-	                } else if (match[1]) {
-	                    // positional argument (explicit)
-	                    arg = argv[match[1]];
-	                } else {
-	                    // positional argument (implicit)
-	                    arg = argv[cursor++];
-	                }
-
-	                if (re.not_type.test(match[8]) && re.not_primitive.test(match[8]) && get_type(arg) == 'function') {
-	                    arg = arg();
-	                }
-
-	                if (re.numeric_arg.test(match[8]) && get_type(arg) != 'number' && isNaN(arg)) {
-	                    throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg)));
-	                }
-
-	                if (re.number.test(match[8])) {
-	                    is_positive = arg >= 0;
-	                }
+	        const listener = ({ data: result }) => {
+	          if (result.id !== id) {
+	            return;
+	          }
 
-	                switch (match[8]) {
-	                    case 'b':
-	                        arg = parseInt(arg, 10).toString(2);
-	                        break;
-	                    case 'c':
-	                        arg = String.fromCharCode(parseInt(arg, 10));
-	                        break;
-	                    case 'd':
-	                    case 'i':
-	                        arg = parseInt(arg, 10);
-	                        break;
-	                    case 'j':
-	                        arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0);
-	                        break;
-	                    case 'e':
-	                        arg = match[7] ? parseFloat(arg).toExponential(match[7]) : parseFloat(arg).toExponential();
-	                        break;
-	                    case 'f':
-	                        arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg);
-	                        break;
-	                    case 'g':
-	                        arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg);
-	                        break;
-	                    case 'o':
-	                        arg = arg.toString(8);
-	                        break;
-	                    case 's':
-	                    case 'S':
-	                        arg = String(arg);
-	                        arg = match[7] ? arg.substring(0, match[7]) : arg;
-	                        break;
-	                    case 't':
-	                        arg = String(!!arg);
-	                        arg = match[7] ? arg.substring(0, match[7]) : arg;
-	                        break;
-	                    case 'T':
-	                        arg = get_type(arg);
-	                        arg = match[7] ? arg.substring(0, match[7]) : arg;
-	                        break;
-	                    case 'u':
-	                        arg = parseInt(arg, 10) >>> 0;
-	                        break;
-	                    case 'v':
-	                        arg = arg.valueOf();
-	                        arg = match[7] ? arg.substring(0, match[7]) : arg;
-	                        break;
-	                    case 'x':
-	                        arg = parseInt(arg, 10).toString(16);
-	                        break;
-	                    case 'X':
-	                        arg = parseInt(arg, 10).toString(16).toUpperCase();
-	                        break;
-	                }
-	                if (re.json.test(match[8])) {
-	                    output[output.length] = arg;
-	                } else {
-	                    if (re.number.test(match[8]) && (!is_positive || match[3])) {
-	                        sign = is_positive ? '+' : '-';
-	                        arg = arg.toString().replace(re.sign, '');
-	                    } else {
-	                        sign = '';
-	                    }
-	                    pad_character = match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' ';
-	                    pad_length = match[6] - (sign + arg).length;
-	                    pad = match[6] ? pad_length > 0 ? str_repeat(pad_character, pad_length) : '' : '';
-	                    output[output.length] = match[5] ? sign + arg + pad : pad_character === '0' ? sign + pad + arg : pad + sign + arg;
-	                }
-	            }
-	        }
-	        return output.join('');
-	    };
-
-	    sprintf.cache = {};
+	          this.worker.removeEventListener("message", listener);
+	          if (result.error) {
+	            reject(result.error);
+	          } else {
+	            resolve(result.response);
+	          }
+	        };
 
-	    sprintf.parse = function (fmt) {
-	        var _fmt = fmt,
-	            match = [],
-	            parse_tree = [],
-	            arg_names = 0;
-	        while (_fmt) {
-	            if ((match = re.text.exec(_fmt)) !== null) {
-	                parse_tree[parse_tree.length] = match[0];
-	            } else if ((match = re.modulo.exec(_fmt)) !== null) {
-	                parse_tree[parse_tree.length] = '%';
-	            } else if ((match = re.placeholder.exec(_fmt)) !== null) {
-	                if (match[2]) {
-	                    arg_names |= 1;
-	                    var field_list = [],
-	                        replacement_field = match[2],
-	                        field_match = [];
-	                    if ((field_match = re.key.exec(replacement_field)) !== null) {
-	                        field_list[field_list.length] = field_match[1];
-	                        while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
-	                            if ((field_match = re.key_access.exec(replacement_field)) !== null) {
-	                                field_list[field_list.length] = field_match[1];
-	                            } else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
-	                                field_list[field_list.length] = field_match[1];
-	                            } else {
-	                                throw new SyntaxError("[sprintf] failed to parse named argument key");
-	                            }
-	                        }
-	                    } else {
-	                        throw new SyntaxError("[sprintf] failed to parse named argument key");
-	                    }
-	                    match[2] = field_list;
-	                } else {
-	                    arg_names |= 2;
-	                }
-	                if (arg_names === 3) {
-	                    throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");
-	                }
-	                parse_tree[parse_tree.length] = match;
-	            } else {
-	                throw new SyntaxError("[sprintf] unexpected placeholder");
-	            }
-	            _fmt = _fmt.substring(match[0].length);
-	        }
-	        return parse_tree;
+	        this.worker.addEventListener("message", listener);
+	      });
 	    };
-
-	    var vsprintf = function (fmt, argv, _argv) {
-	        _argv = (argv || []).slice(0);
-	        _argv.splice(0, 0, fmt);
-	        return sprintf.apply(null, _argv);
-	    };
-
-	    /**
-	     * helpers
-	     */
-	    function get_type(variable) {
-	        if (typeof variable === 'number') {
-	            return 'number';
-	        } else if (typeof variable === 'string') {
-	            return 'string';
-	        } else {
-	            return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
-	        }
-	    }
+	  }
+	};
 
-	    var preformattedPadding = {
-	        '0': ['', '0', '00', '000', '0000', '00000', '000000', '0000000'],
-	        ' ': ['', ' ', '  ', '   ', '    ', '     ', '      ', '       '],
-	        '_': ['', '_', '__', '___', '____', '_____', '______', '_______']
-	    };
-	    function str_repeat(input, multiplier) {
-	        if (multiplier >= 0 && multiplier <= 7 && preformattedPadding[input]) {
-	            return preformattedPadding[input][multiplier];
-	        }
-	        return Array(multiplier + 1).join(input);
-	    }
-
-	    /**
-	     * export to either browser or node.js
-	     */
-	    if (true) {
-	        exports.sprintf = sprintf;
-	        exports.vsprintf = vsprintf;
+	function workerHandler(publicInterface) {
+	  return function workerHandler(msg) {
+	    const { id, method, args } = msg.data;
+	    const response = publicInterface[method].apply(undefined, args);
+	    if (response instanceof Promise) {
+	      response.then(val => self.postMessage({ id, response: val }), err => self.postMessage({ id, error: err }));
 	    } else {
-	        window.sprintf = sprintf;
-	        window.vsprintf = vsprintf;
-
-	        if (typeof define === 'function' && define.amd) {
-	            define(function () {
-	                return {
-	                    sprintf: sprintf,
-	                    vsprintf: vsprintf
-	                };
-	            });
-	        }
+	      self.postMessage({ id, response });
 	    }
-	})(typeof window === 'undefined' ? this : window);
-
-/***/ },
-/* 13 */,
-/* 14 */,
-/* 15 */,
-/* 16 */,
-/* 17 */,
-/* 18 */,
-/* 19 */
-/***/ function(module, exports) {
-
-	let msgId = 1;
-	function workerTask(worker, method) {
-	  return function (...args) {
-	    return new Promise((resolve, reject) => {
-	      const id = msgId++;
-	      worker.postMessage({ id, method, args });
-
-	      const listener = ({ data: result }) => {
-	        if (result.id !== id) {
-	          return;
-	        }
-
-	        worker.removeEventListener("message", listener);
-	        if (result.error) {
-	          reject(result.error);
-	        } else {
-	          resolve(result.response);
-	        }
-	      };
-
-	      worker.addEventListener("message", listener);
-	    });
 	  };
 	}
 
 	module.exports = {
-	  workerTask
-	};
-
-/***/ },
-/* 20 */
-/***/ function(module, exports, __webpack_require__) {
-
-	const feature = __webpack_require__(21);
-
-	module.exports = feature;
-
-/***/ },
-/* 21 */
-/***/ function(module, exports, __webpack_require__) {
-
-	const pick = __webpack_require__(22);
-	const put = __webpack_require__(74);
-	const fs = __webpack_require__(80);
-	const path = __webpack_require__(81);
-
-	let config;
-
-	const flag = __webpack_require__(83);
-
-	/**
-	 * Gets a config value for a given key
-	 * e.g "chrome.webSocketPort"
-	 */
-	function getValue(key) {
-	  return pick(config, key);
-	}
-
-	function setValue(key, value) {
-	  return put(config, key, value);
-	}
-
-	function isEnabled(key) {
-	  return config.features && typeof config.features[key] == "object" ? config.features[key].enabled : config.features[key];
-	}
-
-	function isDevelopment() {
-	  if (isFirefoxPanel()) {
-	    // Default to production if compiling for the Firefox panel
-	    return ("production") === "development";
-	  }
-	  return ("production") !== "production";
-	}
-
-	function isTesting() {
-	  return flag.testing;
-	}
-
-	function isFirefoxPanel() {
-	  return ("firefox-panel") == "firefox-panel";
-	}
-
-	function isApplication() {
-	  return ("firefox-panel") == "application";
-	}
-
-	function isFirefox() {
-	  return (/firefox/i.test(navigator.userAgent)
-	  );
-	}
-
-	function setConfig(value) {
-	  config = value;
-	}
-
-	function getConfig() {
-	  return config;
-	}
-
-	function updateLocalConfig(relativePath) {
-	  const localConfigPath = path.resolve(relativePath, "../configs/local.json");
-	  const output = JSON.stringify(config, null, 2);
-	  fs.writeFileSync(localConfigPath, output, { flag: 'w' });
-	  return output;
-	}
-
-	module.exports = {
-	  isEnabled,
-	  getValue,
-	  setValue,
-	  isDevelopment,
-	  isTesting,
-	  isFirefoxPanel,
-	  isApplication,
-	  isFirefox,
-	  getConfig,
-	  setConfig,
-	  updateLocalConfig
+	  WorkerDispatcher,
+	  workerHandler
 	};
 
-/***/ },
-/* 22 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var baseGet = __webpack_require__(23);
-
-	/**
-	 * Gets the value at `path` of `object`. If the resolved value is
-	 * `undefined`, the `defaultValue` is returned in its place.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 3.7.0
-	 * @category Object
-	 * @param {Object} object The object to query.
-	 * @param {Array|string} path The path of the property to get.
-	 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
-	 * @returns {*} Returns the resolved value.
-	 * @example
-	 *
-	 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
-	 *
-	 * _.get(object, 'a[0].b.c');
-	 * // => 3
-	 *
-	 * _.get(object, ['a', '0', 'b', 'c']);
-	 * // => 3
-	 *
-	 * _.get(object, 'a.b.c', 'default');
-	 * // => 'default'
-	 */
-	function get(object, path, defaultValue) {
-	  var result = object == null ? undefined : baseGet(object, path);
-	  return result === undefined ? defaultValue : result;
-	}
-
-	module.exports = get;
-
-
-/***/ },
-/* 23 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var castPath = __webpack_require__(24),
-	    toKey = __webpack_require__(73);
-
-	/**
-	 * The base implementation of `_.get` without support for default values.
-	 *
-	 * @private
-	 * @param {Object} object The object to query.
-	 * @param {Array|string} path The path of the property to get.
-	 * @returns {*} Returns the resolved value.
-	 */
-	function baseGet(object, path) {
-	  path = castPath(path, object);
-
-	  var index = 0,
-	      length = path.length;
-
-	  while (object != null && index < length) {
-	    object = object[toKey(path[index++])];
-	  }
-	  return (index && index == length) ? object : undefined;
-	}
-
-	module.exports = baseGet;
-
-
-/***/ },
-/* 24 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isArray = __webpack_require__(25),
-	    isKey = __webpack_require__(26),
-	    stringToPath = __webpack_require__(35),
-	    toString = __webpack_require__(70);
-
-	/**
-	 * Casts `value` to a path array if it's not one.
-	 *
-	 * @private
-	 * @param {*} value The value to inspect.
-	 * @param {Object} [object] The object to query keys on.
-	 * @returns {Array} Returns the cast property path array.
-	 */
-	function castPath(value, object) {
-	  if (isArray(value)) {
-	    return value;
-	  }
-	  return isKey(value, object) ? [value] : stringToPath(toString(value));
-	}
-
-	module.exports = castPath;
-
-
-/***/ },
-/* 25 */
-/***/ function(module, exports) {
-
-	/**
-	 * Checks if `value` is classified as an `Array` object.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 0.1.0
-	 * @category Lang
-	 * @param {*} value The value to check.
-	 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
-	 * @example
-	 *
-	 * _.isArray([1, 2, 3]);
-	 * // => true
-	 *
-	 * _.isArray(document.body.children);
-	 * // => false
-	 *
-	 * _.isArray('abc');
-	 * // => false
-	 *
-	 * _.isArray(_.noop);
-	 * // => false
-	 */
-	var isArray = Array.isArray;
-
-	module.exports = isArray;
-
-
-/***/ },
-/* 26 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isArray = __webpack_require__(25),
-	    isSymbol = __webpack_require__(27);
-
-	/** Used to match property names within property paths. */
-	var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
-	    reIsPlainProp = /^\w*$/;
-
-	/**
-	 * Checks if `value` is a property name and not a property path.
-	 *
-	 * @private
-	 * @param {*} value The value to check.
-	 * @param {Object} [object] The object to query keys on.
-	 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
-	 */
-	function isKey(value, object) {
-	  if (isArray(value)) {
-	    return false;
-	  }
-	  var type = typeof value;
-	  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
-	      value == null || isSymbol(value)) {
-	    return true;
-	  }
-	  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
-	    (object != null && value in Object(object));
-	}
-
-	module.exports = isKey;
-
-
-/***/ },
-/* 27 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var baseGetTag = __webpack_require__(28),
-	    isObjectLike = __webpack_require__(34);
-
-	/** `Object#toString` result references. */
-	var symbolTag = '[object Symbol]';
-
-	/**
-	 * Checks if `value` is classified as a `Symbol` primitive or object.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 4.0.0
-	 * @category Lang
-	 * @param {*} value The value to check.
-	 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
-	 * @example
-	 *
-	 * _.isSymbol(Symbol.iterator);
-	 * // => true
-	 *
-	 * _.isSymbol('abc');
-	 * // => false
-	 */
-	function isSymbol(value) {
-	  return typeof value == 'symbol' ||
-	    (isObjectLike(value) && baseGetTag(value) == symbolTag);
-	}
-
-	module.exports = isSymbol;
-
-
-/***/ },
-/* 28 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var Symbol = __webpack_require__(29),
-	    getRawTag = __webpack_require__(32),
-	    objectToString = __webpack_require__(33);
-
-	/** `Object#toString` result references. */
-	var nullTag = '[object Null]',
-	    undefinedTag = '[object Undefined]';
-
-	/** Built-in value references. */
-	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
-
-	/**
-	 * The base implementation of `getTag` without fallbacks for buggy environments.
-	 *
-	 * @private
-	 * @param {*} value The value to query.
-	 * @returns {string} Returns the `toStringTag`.
-	 */
-	function baseGetTag(value) {
-	  if (value == null) {
-	    return value === undefined ? undefinedTag : nullTag;
-	  }
-	  return (symToStringTag && symToStringTag in Object(value))
-	    ? getRawTag(value)
-	    : objectToString(value);
-	}
-
-	module.exports = baseGetTag;
-
-
-/***/ },
-/* 29 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var root = __webpack_require__(30);
-
-	/** Built-in value references. */
-	var Symbol = root.Symbol;
-
-	module.exports = Symbol;
-
-
-/***/ },
-/* 30 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var freeGlobal = __webpack_require__(31);
-
-	/** Detect free variable `self`. */
-	var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
-
-	/** Used as a reference to the global object. */
-	var root = freeGlobal || freeSelf || Function('return this')();
-
-	module.exports = root;
-
-
-/***/ },
-/* 31 */
-/***/ function(module, exports) {
-
-	/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */
-	var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
-
-	module.exports = freeGlobal;
-
-	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 32 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var Symbol = __webpack_require__(29);
-
-	/** Used for built-in method references. */
-	var objectProto = Object.prototype;
-
-	/** Used to check objects for own properties. */
-	var hasOwnProperty = objectProto.hasOwnProperty;
-
-	/**
-	 * Used to resolve the
-	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
-	 * of values.
-	 */
-	var nativeObjectToString = objectProto.toString;
-
-	/** Built-in value references. */
-	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
-
-	/**
-	 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
-	 *
-	 * @private
-	 * @param {*} value The value to query.
-	 * @returns {string} Returns the raw `toStringTag`.
-	 */
-	function getRawTag(value) {
-	  var isOwn = hasOwnProperty.call(value, symToStringTag),
-	      tag = value[symToStringTag];
-
-	  try {
-	    value[symToStringTag] = undefined;
-	    var unmasked = true;
-	  } catch (e) {}
-
-	  var result = nativeObjectToString.call(value);
-	  if (unmasked) {
-	    if (isOwn) {
-	      value[symToStringTag] = tag;
-	    } else {
-	      delete value[symToStringTag];
-	    }
-	  }
-	  return result;
-	}
-
-	module.exports = getRawTag;
-
-
-/***/ },
-/* 33 */
-/***/ function(module, exports) {
-
-	/** Used for built-in method references. */
-	var objectProto = Object.prototype;
-
-	/**
-	 * Used to resolve the
-	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
-	 * of values.
-	 */
-	var nativeObjectToString = objectProto.toString;
-
-	/**
-	 * Converts `value` to a string using `Object.prototype.toString`.
-	 *
-	 * @private
-	 * @param {*} value The value to convert.
-	 * @returns {string} Returns the converted string.
-	 */
-	function objectToString(value) {
-	  return nativeObjectToString.call(value);
-	}
-
-	module.exports = objectToString;
-
-
-/***/ },
-/* 34 */
-/***/ function(module, exports) {
-
-	/**
-	 * Checks if `value` is object-like. A value is object-like if it's not `null`
-	 * and has a `typeof` result of "object".
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 4.0.0
-	 * @category Lang
-	 * @param {*} value The value to check.
-	 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
-	 * @example
-	 *
-	 * _.isObjectLike({});
-	 * // => true
-	 *
-	 * _.isObjectLike([1, 2, 3]);
-	 * // => true
-	 *
-	 * _.isObjectLike(_.noop);
-	 * // => false
-	 *
-	 * _.isObjectLike(null);
-	 * // => false
-	 */
-	function isObjectLike(value) {
-	  return value != null && typeof value == 'object';
-	}
-
-	module.exports = isObjectLike;
-
-
-/***/ },
-/* 35 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var memoizeCapped = __webpack_require__(36);
-
-	/** Used to match property names within property paths. */
-	var reLeadingDot = /^\./,
-	    rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
-
-	/** Used to match backslashes in property paths. */
-	var reEscapeChar = /\\(\\)?/g;
-
-	/**
-	 * Converts `string` to a property path array.
-	 *
-	 * @private
-	 * @param {string} string The string to convert.
-	 * @returns {Array} Returns the property path array.
-	 */
-	var stringToPath = memoizeCapped(function(string) {
-	  var result = [];
-	  if (reLeadingDot.test(string)) {
-	    result.push('');
-	  }
-	  string.replace(rePropName, function(match, number, quote, string) {
-	    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
-	  });
-	  return result;
-	});
-
-	module.exports = stringToPath;
-
-
-/***/ },
-/* 36 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var memoize = __webpack_require__(37);
-
-	/** Used as the maximum memoize cache size. */
-	var MAX_MEMOIZE_SIZE = 500;
-
-	/**
-	 * A specialized version of `_.memoize` which clears the memoized function's
-	 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
-	 *
-	 * @private
-	 * @param {Function} func The function to have its output memoized.
-	 * @returns {Function} Returns the new memoized function.
-	 */
-	function memoizeCapped(func) {
-	  var result = memoize(func, function(key) {
-	    if (cache.size === MAX_MEMOIZE_SIZE) {
-	      cache.clear();
-	    }
-	    return key;
-	  });
-
-	  var cache = result.cache;
-	  return result;
-	}
-
-	module.exports = memoizeCapped;
-
-
-/***/ },
-/* 37 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var MapCache = __webpack_require__(38);
-
-	/** Error message constants. */
-	var FUNC_ERROR_TEXT = 'Expected a function';
-
-	/**
-	 * Creates a function that memoizes the result of `func`. If `resolver` is
-	 * provided, it determines the cache key for storing the result based on the
-	 * arguments provided to the memoized function. By default, the first argument
-	 * provided to the memoized function is used as the map cache key. The `func`
-	 * is invoked with the `this` binding of the memoized function.
-	 *
-	 * **Note:** The cache is exposed as the `cache` property on the memoized
-	 * function. Its creation may be customized by replacing the `_.memoize.Cache`
-	 * constructor with one whose instances implement the
-	 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
-	 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 0.1.0
-	 * @category Function
-	 * @param {Function} func The function to have its output memoized.
-	 * @param {Function} [resolver] The function to resolve the cache key.
-	 * @returns {Function} Returns the new memoized function.
-	 * @example
-	 *
-	 * var object = { 'a': 1, 'b': 2 };
-	 * var other = { 'c': 3, 'd': 4 };
-	 *
-	 * var values = _.memoize(_.values);
-	 * values(object);
-	 * // => [1, 2]
-	 *
-	 * values(other);
-	 * // => [3, 4]
-	 *
-	 * object.a = 2;
-	 * values(object);
-	 * // => [1, 2]
-	 *
-	 * // Modify the result cache.
-	 * values.cache.set(object, ['a', 'b']);
-	 * values(object);
-	 * // => ['a', 'b']
-	 *
-	 * // Replace `_.memoize.Cache`.
-	 * _.memoize.Cache = WeakMap;
-	 */
-	function memoize(func, resolver) {
-	  if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
-	    throw new TypeError(FUNC_ERROR_TEXT);
-	  }
-	  var memoized = function() {
-	    var args = arguments,
-	        key = resolver ? resolver.apply(this, args) : args[0],
-	        cache = memoized.cache;
-
-	    if (cache.has(key)) {
-	      return cache.get(key);
-	    }
-	    var result = func.apply(this, args);
-	    memoized.cache = cache.set(key, result) || cache;
-	    return result;
-	  };
-	  memoized.cache = new (memoize.Cache || MapCache);
-	  return memoized;
-	}
-
-	// Expose `MapCache`.
-	memoize.Cache = MapCache;
-
-	module.exports = memoize;
-
-
-/***/ },
-/* 38 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var mapCacheClear = __webpack_require__(39),
-	    mapCacheDelete = __webpack_require__(64),
-	    mapCacheGet = __webpack_require__(67),
-	    mapCacheHas = __webpack_require__(68),
-	    mapCacheSet = __webpack_require__(69);
-
-	/**
-	 * Creates a map cache object to store key-value pairs.
-	 *
-	 * @private
-	 * @constructor
-	 * @param {Array} [entries] The key-value pairs to cache.
-	 */
-	function MapCache(entries) {
-	  var index = -1,
-	      length = entries == null ? 0 : entries.length;
-
-	  this.clear();
-	  while (++index < length) {
-	    var entry = entries[index];
-	    this.set(entry[0], entry[1]);
-	  }
-	}
-
-	// Add methods to `MapCache`.
-	MapCache.prototype.clear = mapCacheClear;
-	MapCache.prototype['delete'] = mapCacheDelete;
-	MapCache.prototype.get = mapCacheGet;
-	MapCache.prototype.has = mapCacheHas;
-	MapCache.prototype.set = mapCacheSet;
-
-	module.exports = MapCache;
-
-
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var Hash = __webpack_require__(40),
-	    ListCache = __webpack_require__(55),
-	    Map = __webpack_require__(63);
-
-	/**
-	 * Removes all key-value entries from the map.
-	 *
-	 * @private
-	 * @name clear
-	 * @memberOf MapCache
-	 */
-	function mapCacheClear() {
-	  this.size = 0;
-	  this.__data__ = {
-	    'hash': new Hash,
-	    'map': new (Map || ListCache),
-	    'string': new Hash
-	  };
-	}
-
-	module.exports = mapCacheClear;
-
-
-/***/ },
-/* 40 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var hashClear = __webpack_require__(41),
-	    hashDelete = __webpack_require__(51),
-	    hashGet = __webpack_require__(52),
-	    hashHas = __webpack_require__(53),
-	    hashSet = __webpack_require__(54);
-
-	/**
-	 * Creates a hash object.
-	 *
-	 * @private
-	 * @constructor
-	 * @param {Array} [entries] The key-value pairs to cache.
-	 */
-	function Hash(entries) {
-	  var index = -1,
-	      length = entries == null ? 0 : entries.length;
-
-	  this.clear();
-	  while (++index < length) {
-	    var entry = entries[index];
-	    this.set(entry[0], entry[1]);
-	  }
-	}
-
-	// Add methods to `Hash`.
-	Hash.prototype.clear = hashClear;
-	Hash.prototype['delete'] = hashDelete;
-	Hash.prototype.get = hashGet;
-	Hash.prototype.has = hashHas;
-	Hash.prototype.set = hashSet;
-
-	module.exports = Hash;
-
-
-/***/ },
-/* 41 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var nativeCreate = __webpack_require__(42);
-
-	/**
-	 * Removes all key-value entries from the hash.
-	 *
-	 * @private
-	 * @name clear
-	 * @memberOf Hash
-	 */
-	function hashClear() {
-	  this.__data__ = nativeCreate ? nativeCreate(null) : {};
-	  this.size = 0;
-	}
-
-	module.exports = hashClear;
-
-
-/***/ },
-/* 42 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var getNative = __webpack_require__(43);
-
-	/* Built-in method references that are verified to be native. */
-	var nativeCreate = getNative(Object, 'create');
-
-	module.exports = nativeCreate;
-
-
-/***/ },
-/* 43 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var baseIsNative = __webpack_require__(44),
-	    getValue = __webpack_require__(50);
-
-	/**
-	 * Gets the native function at `key` of `object`.
-	 *
-	 * @private
-	 * @param {Object} object The object to query.
-	 * @param {string} key The key of the method to get.
-	 * @returns {*} Returns the function if it's native, else `undefined`.
-	 */
-	function getNative(object, key) {
-	  var value = getValue(object, key);
-	  return baseIsNative(value) ? value : undefined;
-	}
-
-	module.exports = getNative;
-
-
-/***/ },
-/* 44 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isFunction = __webpack_require__(45),
-	    isMasked = __webpack_require__(47),
-	    isObject = __webpack_require__(46),
-	    toSource = __webpack_require__(49);
-
-	/**
-	 * Used to match `RegExp`
-	 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
-	 */
-	var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
-
-	/** Used to detect host constructors (Safari). */
-	var reIsHostCtor = /^\[object .+?Constructor\]$/;
-
-	/** Used for built-in method references. */
-	var funcProto = Function.prototype,
-	    objectProto = Object.prototype;
-
-	/** Used to resolve the decompiled source of functions. */
-	var funcToString = funcProto.toString;
-
-	/** Used to check objects for own properties. */
-	var hasOwnProperty = objectProto.hasOwnProperty;
-
-	/** Used to detect if a method is native. */
-	var reIsNative = RegExp('^' +
-	  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
-	  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
-	);
-
-	/**
-	 * The base implementation of `_.isNative` without bad shim checks.
-	 *
-	 * @private
-	 * @param {*} value The value to check.
-	 * @returns {boolean} Returns `true` if `value` is a native function,
-	 *  else `false`.
-	 */
-	function baseIsNative(value) {
-	  if (!isObject(value) || isMasked(value)) {
-	    return false;
-	  }
-	  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
-	  return pattern.test(toSource(value));
-	}
-
-	module.exports = baseIsNative;
-
-
-/***/ },
-/* 45 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var baseGetTag = __webpack_require__(28),
-	    isObject = __webpack_require__(46);
-
-	/** `Object#toString` result references. */
-	var asyncTag = '[object AsyncFunction]',
-	    funcTag = '[object Function]',
-	    genTag = '[object GeneratorFunction]',
-	    proxyTag = '[object Proxy]';
-
-	/**
-	 * Checks if `value` is classified as a `Function` object.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 0.1.0
-	 * @category Lang
-	 * @param {*} value The value to check.
-	 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
-	 * @example
-	 *
-	 * _.isFunction(_);
-	 * // => true
-	 *
-	 * _.isFunction(/abc/);
-	 * // => false
-	 */
-	function isFunction(value) {
-	  if (!isObject(value)) {
-	    return false;
-	  }
-	  // The use of `Object#toString` avoids issues with the `typeof` operator
-	  // in Safari 9 which returns 'object' for typed arrays and other constructors.
-	  var tag = baseGetTag(value);
-	  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
-	}
-
-	module.exports = isFunction;
-
-
-/***/ },
-/* 46 */
-/***/ function(module, exports) {
-
-	/**
-	 * Checks if `value` is the
-	 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
-	 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 0.1.0
-	 * @category Lang
-	 * @param {*} value The value to check.
-	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
-	 * @example
-	 *
-	 * _.isObject({});
-	 * // => true
-	 *
-	 * _.isObject([1, 2, 3]);
-	 * // => true
-	 *
-	 * _.isObject(_.noop);
-	 * // => true
-	 *
-	 * _.isObject(null);
-	 * // => false
-	 */
-	function isObject(value) {
-	  var type = typeof value;
-	  return value != null && (type == 'object' || type == 'function');
-	}
-
-	module.exports = isObject;
-
-
-/***/ },
-/* 47 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var coreJsData = __webpack_require__(48);
-
-	/** Used to detect methods masquerading as native. */
-	var maskSrcKey = (function() {
-	  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
-	  return uid ? ('Symbol(src)_1.' + uid) : '';
-	}());
-
-	/**
-	 * Checks if `func` has its source masked.
-	 *
-	 * @private
-	 * @param {Function} func The function to check.
-	 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
-	 */
-	function isMasked(func) {
-	  return !!maskSrcKey && (maskSrcKey in func);
-	}
-
-	module.exports = isMasked;
-
-
-/***/ },
-/* 48 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var root = __webpack_require__(30);
-
-	/** Used to detect overreaching core-js shims. */
-	var coreJsData = root['__core-js_shared__'];
-
-	module.exports = coreJsData;
-
-
-/***/ },
-/* 49 */
-/***/ function(module, exports) {
-
-	/** Used for built-in method references. */
-	var funcProto = Function.prototype;
-
-	/** Used to resolve the decompiled source of functions. */
-	var funcToString = funcProto.toString;
-
-	/**
-	 * Converts `func` to its source code.
-	 *
-	 * @private
-	 * @param {Function} func The function to convert.
-	 * @returns {string} Returns the source code.
-	 */
-	function toSource(func) {
-	  if (func != null) {
-	    try {
-	      return funcToString.call(func);
-	    } catch (e) {}
-	    try {
-	      return (func + '');
-	    } catch (e) {}
-	  }
-	  return '';
-	}
-
-	module.exports = toSource;
-
-
-/***/ },
-/* 50 */
-/***/ function(module, exports) {
-
-	/**
-	 * Gets the value at `key` of `object`.
-	 *
-	 * @private
-	 * @param {Object} [object] The object to query.
-	 * @param {string} key The key of the property to get.
-	 * @returns {*} Returns the property value.
-	 */
-	function getValue(object, key) {
-	  return object == null ? undefined : object[key];
-	}
-
-	module.exports = getValue;
-
-
-/***/ },
-/* 51 */
-/***/ function(module, exports) {
-
-	/**
-	 * Removes `key` and its value from the hash.
-	 *
-	 * @private
-	 * @name delete
-	 * @memberOf Hash
-	 * @param {Object} hash The hash to modify.
-	 * @param {string} key The key of the value to remove.
-	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
-	 */
-	function hashDelete(key) {
-	  var result = this.has(key) && delete this.__data__[key];
-	  this.size -= result ? 1 : 0;
-	  return result;
-	}
-
-	module.exports = hashDelete;
-
-
-/***/ },
-/* 52 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var nativeCreate = __webpack_require__(42);
-
-	/** Used to stand-in for `undefined` hash values. */
-	var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
-	/** Used for built-in method references. */
-	var objectProto = Object.prototype;
-
-	/** Used to check objects for own properties. */
-	var hasOwnProperty = objectProto.hasOwnProperty;
-
-	/**
-	 * Gets the hash value for `key`.
-	 *
-	 * @private
-	 * @name get
-	 * @memberOf Hash
-	 * @param {string} key The key of the value to get.
-	 * @returns {*} Returns the entry value.
-	 */
-	function hashGet(key) {
-	  var data = this.__data__;
-	  if (nativeCreate) {
-	    var result = data[key];
-	    return result === HASH_UNDEFINED ? undefined : result;
-	  }
-	  return hasOwnProperty.call(data, key) ? data[key] : undefined;
-	}
-
-	module.exports = hashGet;
-
-
-/***/ },
-/* 53 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var nativeCreate = __webpack_require__(42);
-
-	/** Used for built-in method references. */
-	var objectProto = Object.prototype;
-
-	/** Used to check objects for own properties. */
-	var hasOwnProperty = objectProto.hasOwnProperty;
-
-	/**
-	 * Checks if a hash value for `key` exists.
-	 *
-	 * @private
-	 * @name has
-	 * @memberOf Hash
-	 * @param {string} key The key of the entry to check.
-	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-	 */
-	function hashHas(key) {
-	  var data = this.__data__;
-	  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
-	}
-
-	module.exports = hashHas;
-
-
-/***/ },
-/* 54 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var nativeCreate = __webpack_require__(42);
-
-	/** Used to stand-in for `undefined` hash values. */
-	var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
-	/**
-	 * Sets the hash `key` to `value`.
-	 *
-	 * @private
-	 * @name set
-	 * @memberOf Hash
-	 * @param {string} key The key of the value to set.
-	 * @param {*} value The value to set.
-	 * @returns {Object} Returns the hash instance.
-	 */
-	function hashSet(key, value) {
-	  var data = this.__data__;
-	  this.size += this.has(key) ? 0 : 1;
-	  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
-	  return this;
-	}
-
-	module.exports = hashSet;
-
-
-/***/ },
-/* 55 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var listCacheClear = __webpack_require__(56),
-	    listCacheDelete = __webpack_require__(57),
-	    listCacheGet = __webpack_require__(60),
-	    listCacheHas = __webpack_require__(61),
-	    listCacheSet = __webpack_require__(62);
-
-	/**
-	 * Creates an list cache object.
-	 *
-	 * @private
-	 * @constructor
-	 * @param {Array} [entries] The key-value pairs to cache.
-	 */
-	function ListCache(entries) {
-	  var index = -1,
-	      length = entries == null ? 0 : entries.length;
-
-	  this.clear();
-	  while (++index < length) {
-	    var entry = entries[index];
-	    this.set(entry[0], entry[1]);
-	  }
-	}
-
-	// Add methods to `ListCache`.
-	ListCache.prototype.clear = listCacheClear;
-	ListCache.prototype['delete'] = listCacheDelete;
-	ListCache.prototype.get = listCacheGet;
-	ListCache.prototype.has = listCacheHas;
-	ListCache.prototype.set = listCacheSet;
-
-	module.exports = ListCache;
-
-
-/***/ },
-/* 56 */
-/***/ function(module, exports) {
-
-	/**
-	 * Removes all key-value entries from the list cache.
-	 *
-	 * @private
-	 * @name clear
-	 * @memberOf ListCache
-	 */
-	function listCacheClear() {
-	  this.__data__ = [];
-	  this.size = 0;
-	}
-
-	module.exports = listCacheClear;
-
-
-/***/ },
-/* 57 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var assocIndexOf = __webpack_require__(58);
-
-	/** Used for built-in method references. */
-	var arrayProto = Array.prototype;
-
-	/** Built-in value references. */
-	var splice = arrayProto.splice;
-
-	/**
-	 * Removes `key` and its value from the list cache.
-	 *
-	 * @private
-	 * @name delete
-	 * @memberOf ListCache
-	 * @param {string} key The key of the value to remove.
-	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
-	 */
-	function listCacheDelete(key) {
-	  var data = this.__data__,
-	      index = assocIndexOf(data, key);
-
-	  if (index < 0) {
-	    return false;
-	  }
-	  var lastIndex = data.length - 1;
-	  if (index == lastIndex) {
-	    data.pop();
-	  } else {
-	    splice.call(data, index, 1);
-	  }
-	  --this.size;
-	  return true;
-	}
-
-	module.exports = listCacheDelete;
-
-
-/***/ },
-/* 58 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var eq = __webpack_require__(59);
-
-	/**
-	 * Gets the index at which the `key` is found in `array` of key-value pairs.
-	 *
-	 * @private
-	 * @param {Array} array The array to inspect.
-	 * @param {*} key The key to search for.
-	 * @returns {number} Returns the index of the matched value, else `-1`.
-	 */
-	function assocIndexOf(array, key) {
-	  var length = array.length;
-	  while (length--) {
-	    if (eq(array[length][0], key)) {
-	      return length;
-	    }
-	  }
-	  return -1;
-	}
-
-	module.exports = assocIndexOf;
-
-
-/***/ },
-/* 59 */
-/***/ function(module, exports) {
-
-	/**
-	 * Performs a
-	 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-	 * comparison between two values to determine if they are equivalent.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 4.0.0
-	 * @category Lang
-	 * @param {*} value The value to compare.
-	 * @param {*} other The other value to compare.
-	 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
-	 * @example
-	 *
-	 * var object = { 'a': 1 };
-	 * var other = { 'a': 1 };
-	 *
-	 * _.eq(object, object);
-	 * // => true
-	 *
-	 * _.eq(object, other);
-	 * // => false
-	 *
-	 * _.eq('a', 'a');
-	 * // => true
-	 *
-	 * _.eq('a', Object('a'));
-	 * // => false
-	 *
-	 * _.eq(NaN, NaN);
-	 * // => true
-	 */
-	function eq(value, other) {
-	  return value === other || (value !== value && other !== other);
-	}
-
-	module.exports = eq;
-
-
-/***/ },
-/* 60 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var assocIndexOf = __webpack_require__(58);
-
-	/**
-	 * Gets the list cache value for `key`.
-	 *
-	 * @private
-	 * @name get
-	 * @memberOf ListCache
-	 * @param {string} key The key of the value to get.
-	 * @returns {*} Returns the entry value.
-	 */
-	function listCacheGet(key) {
-	  var data = this.__data__,
-	      index = assocIndexOf(data, key);
-
-	  return index < 0 ? undefined : data[index][1];
-	}
-
-	module.exports = listCacheGet;
-
-
-/***/ },
-/* 61 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var assocIndexOf = __webpack_require__(58);
-
-	/**
-	 * Checks if a list cache value for `key` exists.
-	 *
-	 * @private
-	 * @name has
-	 * @memberOf ListCache
-	 * @param {string} key The key of the entry to check.
-	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-	 */
-	function listCacheHas(key) {
-	  return assocIndexOf(this.__data__, key) > -1;
-	}
-
-	module.exports = listCacheHas;
-
-
-/***/ },
-/* 62 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var assocIndexOf = __webpack_require__(58);
-
-	/**
-	 * Sets the list cache `key` to `value`.
-	 *
-	 * @private
-	 * @name set
-	 * @memberOf ListCache
-	 * @param {string} key The key of the value to set.
-	 * @param {*} value The value to set.
-	 * @returns {Object} Returns the list cache instance.
-	 */
-	function listCacheSet(key, value) {
-	  var data = this.__data__,
-	      index = assocIndexOf(data, key);
-
-	  if (index < 0) {
-	    ++this.size;
-	    data.push([key, value]);
-	  } else {
-	    data[index][1] = value;
-	  }
-	  return this;
-	}
-
-	module.exports = listCacheSet;
-
-
-/***/ },
-/* 63 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var getNative = __webpack_require__(43),
-	    root = __webpack_require__(30);
-
-	/* Built-in method references that are verified to be native. */
-	var Map = getNative(root, 'Map');
-
-	module.exports = Map;
-
-
-/***/ },
-/* 64 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var getMapData = __webpack_require__(65);
-
-	/**
-	 * Removes `key` and its value from the map.
-	 *
-	 * @private
-	 * @name delete
-	 * @memberOf MapCache
-	 * @param {string} key The key of the value to remove.
-	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
-	 */
-	function mapCacheDelete(key) {
-	  var result = getMapData(this, key)['delete'](key);
-	  this.size -= result ? 1 : 0;
-	  return result;
-	}
-
-	module.exports = mapCacheDelete;
-
-
-/***/ },
-/* 65 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isKeyable = __webpack_require__(66);
-
-	/**
-	 * Gets the data for `map`.
-	 *
-	 * @private
-	 * @param {Object} map The map to query.
-	 * @param {string} key The reference key.
-	 * @returns {*} Returns the map data.
-	 */
-	function getMapData(map, key) {
-	  var data = map.__data__;
-	  return isKeyable(key)
-	    ? data[typeof key == 'string' ? 'string' : 'hash']
-	    : data.map;
-	}
-
-	module.exports = getMapData;
-
-
-/***/ },
-/* 66 */
-/***/ function(module, exports) {
-
-	/**
-	 * Checks if `value` is suitable for use as unique object key.
-	 *
-	 * @private
-	 * @param {*} value The value to check.
-	 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
-	 */
-	function isKeyable(value) {
-	  var type = typeof value;
-	  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
-	    ? (value !== '__proto__')
-	    : (value === null);
-	}
-
-	module.exports = isKeyable;
-
-
-/***/ },
-/* 67 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var getMapData = __webpack_require__(65);
-
-	/**
-	 * Gets the map value for `key`.
-	 *
-	 * @private
-	 * @name get
-	 * @memberOf MapCache
-	 * @param {string} key The key of the value to get.
-	 * @returns {*} Returns the entry value.
-	 */
-	function mapCacheGet(key) {
-	  return getMapData(this, key).get(key);
-	}
-
-	module.exports = mapCacheGet;
-
-
-/***/ },
-/* 68 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var getMapData = __webpack_require__(65);
-
-	/**
-	 * Checks if a map value for `key` exists.
-	 *
-	 * @private
-	 * @name has
-	 * @memberOf MapCache
-	 * @param {string} key The key of the entry to check.
-	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
-	 */
-	function mapCacheHas(key) {
-	  return getMapData(this, key).has(key);
-	}
-
-	module.exports = mapCacheHas;
-
-
-/***/ },
-/* 69 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var getMapData = __webpack_require__(65);
-
-	/**
-	 * Sets the map `key` to `value`.
-	 *
-	 * @private
-	 * @name set
-	 * @memberOf MapCache
-	 * @param {string} key The key of the value to set.
-	 * @param {*} value The value to set.
-	 * @returns {Object} Returns the map cache instance.
-	 */
-	function mapCacheSet(key, value) {
-	  var data = getMapData(this, key),
-	      size = data.size;
-
-	  data.set(key, value);
-	  this.size += data.size == size ? 0 : 1;
-	  return this;
-	}
-
-	module.exports = mapCacheSet;
-
-
-/***/ },
-/* 70 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var baseToString = __webpack_require__(71);
-
-	/**
-	 * Converts `value` to a string. An empty string is returned for `null`
-	 * and `undefined` values. The sign of `-0` is preserved.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 4.0.0
-	 * @category Lang
-	 * @param {*} value The value to convert.
-	 * @returns {string} Returns the converted string.
-	 * @example
-	 *
-	 * _.toString(null);
-	 * // => ''
-	 *
-	 * _.toString(-0);
-	 * // => '-0'
-	 *
-	 * _.toString([1, 2, 3]);
-	 * // => '1,2,3'
-	 */
-	function toString(value) {
-	  return value == null ? '' : baseToString(value);
-	}
-
-	module.exports = toString;
-
-
-/***/ },
-/* 71 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var Symbol = __webpack_require__(29),
-	    arrayMap = __webpack_require__(72),
-	    isArray = __webpack_require__(25),
-	    isSymbol = __webpack_require__(27);
-
-	/** Used as references for various `Number` constants. */
-	var INFINITY = 1 / 0;
-
-	/** Used to convert symbols to primitives and strings. */
-	var symbolProto = Symbol ? Symbol.prototype : undefined,
-	    symbolToString = symbolProto ? symbolProto.toString : undefined;
-
-	/**
-	 * The base implementation of `_.toString` which doesn't convert nullish
-	 * values to empty strings.
-	 *
-	 * @private
-	 * @param {*} value The value to process.
-	 * @returns {string} Returns the string.
-	 */
-	function baseToString(value) {
-	  // Exit early for strings to avoid a performance hit in some environments.
-	  if (typeof value == 'string') {
-	    return value;
-	  }
-	  if (isArray(value)) {
-	    // Recursively convert values (susceptible to call stack limits).
-	    return arrayMap(value, baseToString) + '';
-	  }
-	  if (isSymbol(value)) {
-	    return symbolToString ? symbolToString.call(value) : '';
-	  }
-	  var result = (value + '');
-	  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-	}
-
-	module.exports = baseToString;
-
-
-/***/ },
-/* 72 */
-/***/ function(module, exports) {
-
-	/**
-	 * A specialized version of `_.map` for arrays without support for iteratee
-	 * shorthands.
-	 *
-	 * @private
-	 * @param {Array} [array] The array to iterate over.
-	 * @param {Function} iteratee The function invoked per iteration.
-	 * @returns {Array} Returns the new mapped array.
-	 */
-	function arrayMap(array, iteratee) {
-	  var index = -1,
-	      length = array == null ? 0 : array.length,
-	      result = Array(length);
-
-	  while (++index < length) {
-	    result[index] = iteratee(array[index], index, array);
-	  }
-	  return result;
-	}
-
-	module.exports = arrayMap;
-
-
-/***/ },
-/* 73 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var isSymbol = __webpack_require__(27);
-
-	/** Used as references for various `Number` constants. */
-	var INFINITY = 1 / 0;
-
-	/**
-	 * Converts `value` to a string key if it's not a string or symbol.
-	 *
-	 * @private
-	 * @param {*} value The value to inspect.
-	 * @returns {string|symbol} Returns the key.
-	 */
-	function toKey(value) {
-	  if (typeof value == 'string' || isSymbol(value)) {
-	    return value;
-	  }
-	  var result = (value + '');
-	  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-	}
-
-	module.exports = toKey;
-
-
-/***/ },
-/* 74 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var baseSet = __webpack_require__(75);
-
-	/**
-	 * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
-	 * it's created. Arrays are created for missing index properties while objects
-	 * are created for all other missing properties. Use `_.setWith` to customize
-	 * `path` creation.
-	 *
-	 * **Note:** This method mutates `object`.
-	 *
-	 * @static
-	 * @memberOf _
-	 * @since 3.7.0
-	 * @category Object
-	 * @param {Object} object The object to modify.
-	 * @param {Array|string} path The path of the property to set.
-	 * @param {*} value The value to set.
-	 * @returns {Object} Returns `object`.
-	 * @example
-	 *
-	 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
-	 *
-	 * _.set(object, 'a[0].b.c', 4);
-	 * console.log(object.a[0].b.c);
-	 * // => 4
-	 *
-	 * _.set(object, ['x', '0', 'y', 'z'], 5);
-	 * console.log(object.x[0].y.z);
-	 * // => 5
-	 */
-	function set(object, path, value) {
-	  return object == null ? object : baseSet(object, path, value);
-	}
-
-	module.exports = set;
-
-
-/***/ },
-/* 75 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var assignValue = __webpack_require__(76),
-	    castPath = __webpack_require__(24),
-	    isIndex = __webpack_require__(79),
-	    isObject = __webpack_require__(46),
-	    toKey = __webpack_require__(73);
-
-	/**
-	 * The base implementation of `_.set`.
-	 *
-	 * @private
-	 * @param {Object} object The object to modify.
-	 * @param {Array|string} path The path of the property to set.
-	 * @param {*} value The value to set.
-	 * @param {Function} [customizer] The function to customize path creation.
-	 * @returns {Object} Returns `object`.
-	 */
-	function baseSet(object, path, value, customizer) {
-	  if (!isObject(object)) {
-	    return object;
-	  }
-	  path = castPath(path, object);
-
-	  var index = -1,
-	      length = path.length,
-	      lastIndex = length - 1,
-	      nested = object;
-
-	  while (nested != null && ++index < length) {
-	    var key = toKey(path[index]),
-	        newValue = value;
-
-	    if (index != lastIndex) {
-	      var objValue = nested[key];
-	      newValue = customizer ? customizer(objValue, key, nested) : undefined;
-	      if (newValue === undefined) {
-	        newValue = isObject(objValue)
-	          ? objValue
-	          : (isIndex(path[index + 1]) ? [] : {});
-	      }
-	    }
-	    assignValue(nested, key, newValue);
-	    nested = nested[key];
-	  }
-	  return object;
-	}
-
-	module.exports = baseSet;
-
-
-/***/ },
-/* 76 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var baseAssignValue = __webpack_require__(77),
-	    eq = __webpack_require__(59);
-
-	/** Used for built-in method references. */
-	var objectProto = Object.prototype;
-
-	/** Used to check objects for own properties. */
-	var hasOwnProperty = objectProto.hasOwnProperty;
-
-	/**
-	 * Assigns `value` to `key` of `object` if the existing value is not equivalent
-	 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
-	 * for equality comparisons.
-	 *
-	 * @private
-	 * @param {Object} object The object to modify.
-	 * @param {string} key The key of the property to assign.
-	 * @param {*} value The value to assign.
-	 */
-	function assignValue(object, key, value) {
-	  var objValue = object[key];
-	  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
-	      (value === undefined && !(key in object))) {
-	    baseAssignValue(object, key, value);
-	  }
-	}
-
-	module.exports = assignValue;
-
-
-/***/ },
-/* 77 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var defineProperty = __webpack_require__(78);
-
-	/**
-	 * The base implementation of `assignValue` and `assignMergeValue` without
-	 * value checks.
-	 *
-	 * @private
-	 * @param {Object} object The object to modify.
-	 * @param {string} key The key of the property to assign.
-	 * @param {*} value The value to assign.
-	 */
-	function baseAssignValue(object, key, value) {
-	  if (key == '__proto__' && defineProperty) {
-	    defineProperty(object, key, {
-	      'configurable': true,
-	      'enumerable': true,
-	      'value': value,
-	      'writable': true
-	    });
-	  } else {
-	    object[key] = value;
-	  }
-	}
-
-	module.exports = baseAssignValue;
-
-
-/***/ },
-/* 78 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var getNative = __webpack_require__(43);
-
-	var defineProperty = (function() {
-	  try {
-	    var func = getNative(Object, 'defineProperty');
-	    func({}, '', {});
-	    return func;
-	  } catch (e) {}
-	}());
-
-	module.exports = defineProperty;
-
-
-/***/ },
-/* 79 */
-/***/ function(module, exports) {
-
-	/** Used as references for various `Number` constants. */
-	var MAX_SAFE_INTEGER = 9007199254740991;
-
-	/** Used to detect unsigned integer values. */
-	var reIsUint = /^(?:0|[1-9]\d*)$/;
-
-	/**
-	 * Checks if `value` is a valid array-like index.
-	 *
-	 * @private
-	 * @param {*} value The value to check.
-	 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
-	 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
-	 */
-	function isIndex(value, length) {
-	  length = length == null ? MAX_SAFE_INTEGER : length;
-	  return !!length &&
-	    (typeof value == 'number' || reIsUint.test(value)) &&
-	    (value > -1 && value % 1 == 0 && value < length);
-	}
-
-	module.exports = isIndex;
-
-
-/***/ },
-/* 80 */
-/***/ function(module, exports) {
-
-	
-
-/***/ },
-/* 81 */
-/***/ function(module, exports, __webpack_require__) {
-
-	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
-	//
-	// Permission is hereby granted, free of charge, to any person obtaining a
-	// copy of this software and associated documentation files (the
-	// "Software"), to deal in the Software without restriction, including
-	// without limitation the rights to use, copy, modify, merge, publish,
-	// distribute, sublicense, and/or sell copies of the Software, and to permit
-	// persons to whom the Software is furnished to do so, subject to the
-	// following conditions:
-	//
-	// The above copyright notice and this permission notice shall be included
-	// in all copies or substantial portions of the Software.
-	//
-	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-	// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-	// resolves . and .. elements in a path array with directory names there
-	// must be no slashes, empty elements, or device names (c:\) in the array
-	// (so also no leading and trailing slashes - it does not distinguish
-	// relative and absolute paths)
-	function normalizeArray(parts, allowAboveRoot) {
-	  // if the path tries to go above the root, `up` ends up > 0
-	  var up = 0;
-	  for (var i = parts.length - 1; i >= 0; i--) {
-	    var last = parts[i];
-	    if (last === '.') {
-	      parts.splice(i, 1);
-	    } else if (last === '..') {
-	      parts.splice(i, 1);
-	      up++;
-	    } else if (up) {
-	      parts.splice(i, 1);
-	      up--;
-	    }
-	  }
-
-	  // if the path is allowed to go above the root, restore leading ..s
-	  if (allowAboveRoot) {
-	    for (; up--; up) {
-	      parts.unshift('..');
-	    }
-	  }
-
-	  return parts;
-	}
-
-	// Split a filename into [root, dir, basename, ext], unix version
-	// 'root' is just a slash, or nothing.
-	var splitPathRe =
-	    /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
-	var splitPath = function(filename) {
-	  return splitPathRe.exec(filename).slice(1);
-	};
-
-	// path.resolve([from ...], to)
-	// posix version
-	exports.resolve = function() {
-	  var resolvedPath = '',
-	      resolvedAbsolute = false;
-
-	  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
-	    var path = (i >= 0) ? arguments[i] : process.cwd();
-
-	    // Skip empty and invalid entries
-	    if (typeof path !== 'string') {
-	      throw new TypeError('Arguments to path.resolve must be strings');
-	    } else if (!path) {
-	      continue;
-	    }
-
-	    resolvedPath = path + '/' + resolvedPath;
-	    resolvedAbsolute = path.charAt(0) === '/';
-	  }
-
-	  // At this point the path should be resolved to a full absolute path, but
-	  // handle relative paths to be safe (might happen when process.cwd() fails)
-
-	  // Normalize the path
-	  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
-	    return !!p;
-	  }), !resolvedAbsolute).join('/');
-
-	  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
-	};
-
-	// path.normalize(path)
-	// posix version
-	exports.normalize = function(path) {
-	  var isAbsolute = exports.isAbsolute(path),
-	      trailingSlash = substr(path, -1) === '/';
-
-	  // Normalize the path
-	  path = normalizeArray(filter(path.split('/'), function(p) {
-	    return !!p;
-	  }), !isAbsolute).join('/');
-
-	  if (!path && !isAbsolute) {
-	    path = '.';
-	  }
-	  if (path && trailingSlash) {
-	    path += '/';
-	  }
-
-	  return (isAbsolute ? '/' : '') + path;
-	};
-
-	// posix version
-	exports.isAbsolute = function(path) {
-	  return path.charAt(0) === '/';
-	};
-
-	// posix version
-	exports.join = function() {
-	  var paths = Array.prototype.slice.call(arguments, 0);
-	  return exports.normalize(filter(paths, function(p, index) {
-	    if (typeof p !== 'string') {
-	      throw new TypeError('Arguments to path.join must be strings');
-	    }
-	    return p;
-	  }).join('/'));
-	};
-
-
-	// path.relative(from, to)
-	// posix version
-	exports.relative = function(from, to) {
-	  from = exports.resolve(from).substr(1);
-	  to = exports.resolve(to).substr(1);
-
-	  function trim(arr) {
-	    var start = 0;
-	    for (; start < arr.length; start++) {
-	      if (arr[start] !== '') break;
-	    }
-
-	    var end = arr.length - 1;
-	    for (; end >= 0; end--) {
-	      if (arr[end] !== '') break;
-	    }
-
-	    if (start > end) return [];
-	    return arr.slice(start, end - start + 1);
-	  }
-
-	  var fromParts = trim(from.split('/'));
-	  var toParts = trim(to.split('/'));
-
-	  var length = Math.min(fromParts.length, toParts.length);
-	  var samePartsLength = length;
-	  for (var i = 0; i < length; i++) {
-	    if (fromParts[i] !== toParts[i]) {
-	      samePartsLength = i;
-	      break;
-	    }
-	  }
-
-	  var outputParts = [];
-	  for (var i = samePartsLength; i < fromParts.length; i++) {
-	    outputParts.push('..');
-	  }
-
-	  outputParts = outputParts.concat(toParts.slice(samePartsLength));
-
-	  return outputParts.join('/');
-	};
-
-	exports.sep = '/';
-	exports.delimiter = ':';
-
-	exports.dirname = function(path) {
-	  var result = splitPath(path),
-	      root = result[0],
-	      dir = result[1];
-
-	  if (!root && !dir) {
-	    // No dirname whatsoever
-	    return '.';
-	  }
-
-	  if (dir) {
-	    // It has a dirname, strip trailing slash
-	    dir = dir.substr(0, dir.length - 1);
-	  }
-
-	  return root + dir;
-	};
-
-
-	exports.basename = function(path, ext) {
-	  var f = splitPath(path)[2];
-	  // TODO: make this comparison case-insensitive on windows?
-	  if (ext && f.substr(-1 * ext.length) === ext) {
-	    f = f.substr(0, f.length - ext.length);
-	  }
-	  return f;
-	};
-
-
-	exports.extname = function(path) {
-	  return splitPath(path)[3];
-	};
-
-	function filter (xs, f) {
-	    if (xs.filter) return xs.filter(f);
-	    var res = [];
-	    for (var i = 0; i < xs.length; i++) {
-	        if (f(xs[i], i, xs)) res.push(xs[i]);
-	    }
-	    return res;
-	}
-
-	// String.prototype.substr - negative index don't work in IE8
-	var substr = 'ab'.substr(-1) === 'b'
-	    ? function (str, start, len) { return str.substr(start, len) }
-	    : function (str, start, len) {
-	        if (start < 0) start = str.length + start;
-	        return str.substr(start, len);
-	    }
-	;
-
-	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(82)))
-
-/***/ },
-/* 82 */
-/***/ function(module, exports) {
-
-	// shim for using process in browser
-	var process = module.exports = {};
-
-	// cached from whatever global is present so that test runners that stub it
-	// don't break things.  But we need to wrap it in a try catch in case it is
-	// wrapped in strict mode code which doesn't define any globals.  It's inside a
-	// function because try/catches deoptimize in certain engines.
-
-	var cachedSetTimeout;
-	var cachedClearTimeout;
-
-	function defaultSetTimout() {
-	    throw new Error('setTimeout has not been defined');
-	}
-	function defaultClearTimeout () {
-	    throw new Error('clearTimeout has not been defined');
-	}
-	(function () {
-	    try {
-	        if (typeof setTimeout === 'function') {
-	            cachedSetTimeout = setTimeout;
-	        } else {
-	            cachedSetTimeout = defaultSetTimout;
-	        }
-	    } catch (e) {
-	        cachedSetTimeout = defaultSetTimout;
-	    }
-	    try {
-	        if (typeof clearTimeout === 'function') {
-	            cachedClearTimeout = clearTimeout;
-	        } else {
-	            cachedClearTimeout = defaultClearTimeout;
-	        }
-	    } catch (e) {
-	        cachedClearTimeout = defaultClearTimeout;
-	    }
-	} ())
-	function runTimeout(fun) {
-	    if (cachedSetTimeout === setTimeout) {
-	        //normal enviroments in sane situations
-	        return setTimeout(fun, 0);
-	    }
-	    // if setTimeout wasn't available but was latter defined
-	    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
-	        cachedSetTimeout = setTimeout;
-	        return setTimeout(fun, 0);
-	    }
-	    try {
-	        // when when somebody has screwed with setTimeout but no I.E. maddness
-	        return cachedSetTimeout(fun, 0);
-	    } catch(e){
-	        try {
-	            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
-	            return cachedSetTimeout.call(null, fun, 0);
-	        } catch(e){
-	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
-	            return cachedSetTimeout.call(this, fun, 0);
-	        }
-	    }
-
-
-	}
-	function runClearTimeout(marker) {
-	    if (cachedClearTimeout === clearTimeout) {
-	        //normal enviroments in sane situations
-	        return clearTimeout(marker);
-	    }
-	    // if clearTimeout wasn't available but was latter defined
-	    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
-	        cachedClearTimeout = clearTimeout;
-	        return clearTimeout(marker);
-	    }
-	    try {
-	        // when when somebody has screwed with setTimeout but no I.E. maddness
-	        return cachedClearTimeout(marker);
-	    } catch (e){
-	        try {
-	            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
-	            return cachedClearTimeout.call(null, marker);
-	        } catch (e){
-	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
-	            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
-	            return cachedClearTimeout.call(this, marker);
-	        }
-	    }
-
-
-
-	}
-	var queue = [];
-	var draining = false;
-	var currentQueue;
-	var queueIndex = -1;
-
-	function cleanUpNextTick() {
-	    if (!draining || !currentQueue) {
-	        return;
-	    }
-	    draining = false;
-	    if (currentQueue.length) {
-	        queue = currentQueue.concat(queue);
-	    } else {
-	        queueIndex = -1;
-	    }
-	    if (queue.length) {
-	        drainQueue();
-	    }
-	}
-
-	function drainQueue() {
-	    if (draining) {
-	        return;
-	    }
-	    var timeout = runTimeout(cleanUpNextTick);
-	    draining = true;
-
-	    var len = queue.length;
-	    while(len) {
-	        currentQueue = queue;
-	        queue = [];
-	        while (++queueIndex < len) {
-	            if (currentQueue) {
-	                currentQueue[queueIndex].run();
-	            }
-	        }
-	        queueIndex = -1;
-	        len = queue.length;
-	    }
-	    currentQueue = null;
-	    draining = false;
-	    runClearTimeout(timeout);
-	}
-
-	process.nextTick = function (fun) {
-	    var args = new Array(arguments.length - 1);
-	    if (arguments.length > 1) {
-	        for (var i = 1; i < arguments.length; i++) {
-	            args[i - 1] = arguments[i];
-	        }
-	    }
-	    queue.push(new Item(fun, args));
-	    if (queue.length === 1 && !draining) {
-	        runTimeout(drainQueue);
-	    }
-	};
-
-	// v8 likes predictible objects
-	function Item(fun, array) {
-	    this.fun = fun;
-	    this.array = array;
-	}
-	Item.prototype.run = function () {
-	    this.fun.apply(null, this.array);
-	};
-	process.title = 'browser';
-	process.browser = true;
-	process.env = {};
-	process.argv = [];
-	process.version = ''; // empty string to avoid regexp issues
-	process.versions = {};
-
-	function noop() {}
-
-	process.on = noop;
-	process.addListener = noop;
-	process.once = noop;
-	process.off = noop;
-	process.removeListener = noop;
-	process.removeAllListeners = noop;
-	process.emit = noop;
-
-	process.binding = function (name) {
-	    throw new Error('process.binding is not supported');
-	};
-
-	process.cwd = function () { return '/' };
-	process.chdir = function (dir) {
-	    throw new Error('process.chdir is not supported');
-	};
-	process.umask = function() { return 0; };
-
-
-/***/ },
-/* 83 */
-/***/ function(module, exports) {
-
-	module.exports = __WEBPACK_EXTERNAL_MODULE_83__;
-
 /***/ }
 /******/ ])
 });
 ;
\ No newline at end of file
--- a/devtools/client/shared/source-map/worker.js
+++ b/devtools/client/shared/source-map/worker.js
@@ -54,40 +54,34 @@ return /******/ (function(modules) { // 
 /* 0 */
 /***/ function(module, exports, __webpack_require__) {
 
 	const {
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
 	  getOriginalSourceText,
+	  hasMappedSource,
 	  applySourceMap,
 	  clearSourceMaps
-	} = __webpack_require__(84);
+	} = __webpack_require__(9);
+
+	const { workerUtils: { workerHandler } } = __webpack_require__(6);
 
 	// The interface is implemented in source-map to be
 	// easier to unit test.
-	const publicInterface = {
+	self.onmessage = workerHandler({
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
 	  getOriginalSourceText,
+	  hasMappedSource,
 	  applySourceMap,
 	  clearSourceMaps
-	};
-
-	self.onmessage = function (msg) {
-	  const { id, method, args } = msg.data;
-	  const response = publicInterface[method].apply(undefined, args);
-	  if (response instanceof Promise) {
-	    response.then(val => self.postMessage({ id, response: val }), err => self.postMessage({ id, error: err }));
-	  } else {
-	    self.postMessage({ id, response });
-	  }
-	};
+	});
 
 /***/ },
 /* 1 */
 /***/ function(module, exports, __webpack_require__) {
 
 	const md5 = __webpack_require__(2);
 
 	function originalToGeneratedId(originalId) {
@@ -115,231 +109,220 @@ return /******/ (function(modules) { // 
 	  let q1 = url.indexOf("?");
 	  let q2 = url.indexOf("&");
 	  let q3 = url.indexOf("#");
 	  let q = Math.min(q1 != -1 ? q1 : length, q2 != -1 ? q2 : length, q3 != -1 ? q3 : length);
 
 	  return url.slice(0, q);
 	}
 
+	// Map suffix to content type.
+	const contentMap = {
+	  "js": "text/javascript",
+	  "jsm": "text/javascript",
+	  "ts": "text/typescript",
+	  "tsx": "text/typescript-jsx",
+	  "jsx": "text/jsx",
+	  "coffee": "text/coffeescript",
+	  "elm": "text/elm",
+	  "cljs": "text/x-clojure"
+	};
+
 	/**
-	 * Returns true if the specified URL and/or content type are specific to
-	 * JavaScript files.
+	 * Returns the content type for the specified URL.  If no specific
+	 * content type can be determined, "text/plain" is returned.
 	 *
-	 * @return boolean
-	 *         True if the source is likely JavaScript.
+	 * @return String
+	 *         The content type.
 	 */
-	function isJavaScript(url, contentType = "") {
-	  return url && /\.(jsm|js)?$/.test(trimUrlQuery(url)) || contentType.includes("javascript");
-	}
-
 	function getContentType(url) {
-	  if (isJavaScript(url)) {
-	    return "text/javascript";
-	  }
-
-	  if (url.match(/ts$/)) {
-	    return "text/typescript";
+	  url = trimUrlQuery(url);
+	  let dot = url.lastIndexOf(".");
+	  if (dot >= 0) {
+	    let name = url.substring(dot + 1);
+	    if (name in contentMap) {
+	      return contentMap[name];
+	    }
 	  }
-
-	  if (url.match(/tsx$/)) {
-	    return "text/typescript-jsx";
-	  }
-
-	  if (url.match(/jsx$/)) {
-	    return "text/jsx";
-	  }
-
-	  if (url.match(/coffee$/)) {
-	    return "text/coffeescript";
-	  }
-
-	  if (url.match(/elm$/)) {
-	    return "text/elm";
-	  }
-
-	  if (url.match(/cljs$/)) {
-	    return "text/x-clojure";
-	  }
-
 	  return "text/plain";
 	}
 
 	module.exports = {
 	  originalToGeneratedId,
 	  generatedToOriginalId,
 	  isOriginalId,
 	  isGeneratedId,
-	  getContentType
+	  getContentType,
+	  contentMapForTesting: contentMap
 	};
 
 /***/ },
 /* 2 */
 /***/ function(module, exports, __webpack_require__) {
 
-	(function(){
-	  var crypt = __webpack_require__(3),
-	      utf8 = __webpack_require__(4).utf8,
-	      isBuffer = __webpack_require__(5),
-	      bin = __webpack_require__(4).bin,
-
-	  // The core
-	  md5 = function (message, options) {
-	    // Convert to byte array
-	    if (message.constructor == String)
-	      if (options && options.encoding === 'binary')
-	        message = bin.stringToBytes(message);
-	      else
-	        message = utf8.stringToBytes(message);
-	    else if (isBuffer(message))
-	      message = Array.prototype.slice.call(message, 0);
-	    else if (!Array.isArray(message))
-	      message = message.toString();
-	    // else, assume byte array already
-
-	    var m = crypt.bytesToWords(message),
-	        l = message.length * 8,
-	        a =  1732584193,
-	        b = -271733879,
-	        c = -1732584194,
-	        d =  271733878;
-
-	    // Swap endian
-	    for (var i = 0; i < m.length; i++) {
-	      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
-	             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
-	    }
-
-	    // Padding
-	    m[l >>> 5] |= 0x80 << (l % 32);
-	    m[(((l + 64) >>> 9) << 4) + 14] = l;
-
-	    // Method shortcuts
-	    var FF = md5._ff,
-	        GG = md5._gg,
-	        HH = md5._hh,
-	        II = md5._ii;
-
-	    for (var i = 0; i < m.length; i += 16) {
-
-	      var aa = a,
-	          bb = b,
-	          cc = c,
-	          dd = d;
-
-	      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
-	      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
-	      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
-	      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
-	      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
-	      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
-	      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
-	      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
-	      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
-	      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
-	      c = FF(c, d, a, b, m[i+10], 17, -42063);
-	      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
-	      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
-	      d = FF(d, a, b, c, m[i+13], 12, -40341101);
-	      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
-	      b = FF(b, c, d, a, m[i+15], 22,  1236535329);
-
-	      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
-	      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
-	      c = GG(c, d, a, b, m[i+11], 14,  643717713);
-	      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
-	      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
-	      d = GG(d, a, b, c, m[i+10],  9,  38016083);
-	      c = GG(c, d, a, b, m[i+15], 14, -660478335);
-	      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
-	      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
-	      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
-	      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
-	      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
-	      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
-	      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
-	      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
-	      b = GG(b, c, d, a, m[i+12], 20, -1926607734);
-
-	      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
-	      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
-	      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
-	      b = HH(b, c, d, a, m[i+14], 23, -35309556);
-	      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
-	      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
-	      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
-	      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
-	      a = HH(a, b, c, d, m[i+13],  4,  681279174);
-	      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
-	      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
-	      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
-	      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
-	      d = HH(d, a, b, c, m[i+12], 11, -421815835);
-	      c = HH(c, d, a, b, m[i+15], 16,  530742520);
-	      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
-
-	      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
-	      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
-	      c = II(c, d, a, b, m[i+14], 15, -1416354905);
-	      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
-	      a = II(a, b, c, d, m[i+12],  6,  1700485571);
-	      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
-	      c = II(c, d, a, b, m[i+10], 15, -1051523);
-	      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
-	      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
-	      d = II(d, a, b, c, m[i+15], 10, -30611744);
-	      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
-	      b = II(b, c, d, a, m[i+13], 21,  1309151649);
-	      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
-	      d = II(d, a, b, c, m[i+11], 10, -1120210379);
-	      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
-	      b = II(b, c, d, a, m[i+ 9], 21, -343485551);
-
-	      a = (a + aa) >>> 0;
-	      b = (b + bb) >>> 0;
-	      c = (c + cc) >>> 0;
-	      d = (d + dd) >>> 0;
-	    }
-
-	    return crypt.endian([a, b, c, d]);
-	  };
-
-	  // Auxiliary functions
-	  md5._ff  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._gg  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._hh  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._ii  = function (a, b, c, d, x, s, t) {
-	    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-
-	  // Package private blocksize
-	  md5._blocksize = 16;
-	  md5._digestsize = 16;
-
-	  module.exports = function (message, options) {
-	    if (message === undefined || message === null)
-	      throw new Error('Illegal argument ' + message);
-
-	    var digestbytes = crypt.wordsToBytes(md5(message, options));
-	    return options && options.asBytes ? digestbytes :
-	        options && options.asString ? bin.bytesToString(digestbytes) :
-	        crypt.bytesToHex(digestbytes);
-	  };
-
-	})();
+	(function(){
+	  var crypt = __webpack_require__(3),
+	      utf8 = __webpack_require__(4).utf8,
+	      isBuffer = __webpack_require__(5),
+	      bin = __webpack_require__(4).bin,
+
+	  // The core
+	  md5 = function (message, options) {
+	    // Convert to byte array
+	    if (message.constructor == String)
+	      if (options && options.encoding === 'binary')
+	        message = bin.stringToBytes(message);
+	      else
+	        message = utf8.stringToBytes(message);
+	    else if (isBuffer(message))
+	      message = Array.prototype.slice.call(message, 0);
+	    else if (!Array.isArray(message))
+	      message = message.toString();
+	    // else, assume byte array already
+
+	    var m = crypt.bytesToWords(message),
+	        l = message.length * 8,
+	        a =  1732584193,
+	        b = -271733879,
+	        c = -1732584194,
+	        d =  271733878;
+
+	    // Swap endian
+	    for (var i = 0; i < m.length; i++) {
+	      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
+	             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
+	    }
+
+	    // Padding
+	    m[l >>> 5] |= 0x80 << (l % 32);
+	    m[(((l + 64) >>> 9) << 4) + 14] = l;
+
+	    // Method shortcuts
+	    var FF = md5._ff,
+	        GG = md5._gg,
+	        HH = md5._hh,
+	        II = md5._ii;
+
+	    for (var i = 0; i < m.length; i += 16) {
+
+	      var aa = a,
+	          bb = b,
+	          cc = c,
+	          dd = d;
+
+	      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
+	      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
+	      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
+	      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
+	      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
+	      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
+	      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
+	      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
+	      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
+	      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
+	      c = FF(c, d, a, b, m[i+10], 17, -42063);
+	      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
+	      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
+	      d = FF(d, a, b, c, m[i+13], 12, -40341101);
+	      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
+	      b = FF(b, c, d, a, m[i+15], 22,  1236535329);
+
+	      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
+	      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
+	      c = GG(c, d, a, b, m[i+11], 14,  643717713);
+	      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
+	      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
+	      d = GG(d, a, b, c, m[i+10],  9,  38016083);
+	      c = GG(c, d, a, b, m[i+15], 14, -660478335);
+	      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
+	      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
+	      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
+	      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
+	      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
+	      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
+	      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
+	      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
+	      b = GG(b, c, d, a, m[i+12], 20, -1926607734);
+
+	      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
+	      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
+	      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
+	      b = HH(b, c, d, a, m[i+14], 23, -35309556);
+	      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
+	      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
+	      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
+	      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
+	      a = HH(a, b, c, d, m[i+13],  4,  681279174);
+	      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
+	      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
+	      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
+	      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
+	      d = HH(d, a, b, c, m[i+12], 11, -421815835);
+	      c = HH(c, d, a, b, m[i+15], 16,  530742520);
+	      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
+
+	      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
+	      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
+	      c = II(c, d, a, b, m[i+14], 15, -1416354905);
+	      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
+	      a = II(a, b, c, d, m[i+12],  6,  1700485571);
+	      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
+	      c = II(c, d, a, b, m[i+10], 15, -1051523);
+	      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
+	      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
+	      d = II(d, a, b, c, m[i+15], 10, -30611744);
+	      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
+	      b = II(b, c, d, a, m[i+13], 21,  1309151649);
+	      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
+	      d = II(d, a, b, c, m[i+11], 10, -1120210379);
+	      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
+	      b = II(b, c, d, a, m[i+ 9], 21, -343485551);
+
+	      a = (a + aa) >>> 0;
+	      b = (b + bb) >>> 0;
+	      c = (c + cc) >>> 0;
+	      d = (d + dd) >>> 0;
+	    }
+
+	    return crypt.endian([a, b, c, d]);
+	  };
+
+	  // Auxiliary functions
+	  md5._ff  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._gg  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._hh  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._ii  = function (a, b, c, d, x, s, t) {
+	    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+
+	  // Package private blocksize
+	  md5._blocksize = 16;
+	  md5._digestsize = 16;
+
+	  module.exports = function (message, options) {
+	    if (message === undefined || message === null)
+	      throw new Error('Illegal argument ' + message);
+
+	    var digestbytes = crypt.wordsToBytes(md5(message, options));
+	    return options && options.asBytes ? digestbytes :
+	        options && options.asString ? bin.bytesToString(digestbytes) :
+	        crypt.bytesToHex(digestbytes);
+	  };
+
+	})();
 
 
 /***/ },
 /* 3 */
 /***/ function(module, exports) {
 
 	(function() {
 	  var base64map
@@ -501,95 +484,133 @@ return /******/ (function(modules) { // 
 
 	// For Node v0.10 support. Remove this eventually.
 	function isSlowBuffer (obj) {
 	  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
 	}
 
 
 /***/ },
-/* 6 */,
-/* 7 */,
-/* 8 */,
-/* 9 */,
-/* 10 */,
-/* 11 */,
-/* 12 */,
-/* 13 */,
-/* 14 */,
-/* 15 */,
-/* 16 */,
-/* 17 */,
-/* 18 */,
-/* 19 */,
-/* 20 */,
-/* 21 */,
-/* 22 */,
-/* 23 */,
-/* 24 */,
-/* 25 */,
-/* 26 */,
-/* 27 */,
-/* 28 */,
-/* 29 */,
-/* 30 */,
-/* 31 */,
-/* 32 */,
-/* 33 */,
-/* 34 */,
-/* 35 */,
-/* 36 */,
-/* 37 */,
-/* 38 */,
-/* 39 */,
-/* 40 */,
-/* 41 */,
-/* 42 */,
-/* 43 */,
-/* 44 */,
-/* 45 */,
-/* 46 */,
-/* 47 */,
-/* 48 */,
-/* 49 */,
-/* 50 */,
-/* 51 */,
-/* 52 */,
-/* 53 */,
-/* 54 */,
-/* 55 */,
-/* 56 */,
-/* 57 */,
-/* 58 */,
-/* 59 */,
-/* 60 */,
-/* 61 */,
-/* 62 */,
-/* 63 */,
-/* 64 */,
-/* 65 */,
-/* 66 */,
-/* 67 */,
-/* 68 */,
-/* 69 */,
-/* 70 */,
-/* 71 */,
-/* 72 */,
-/* 73 */,
-/* 74 */,
-/* 75 */,
-/* 76 */,
-/* 77 */,
-/* 78 */,
-/* 79 */,
-/* 80 */,
-/* 81 */,
-/* 82 */,
-/* 83 */,
-/* 84 */
+/* 6 */
+/***/ function(module, exports, __webpack_require__) {
+
+	const networkRequest = __webpack_require__(7);
+	const workerUtils = __webpack_require__(8);
+
+	module.exports = {
+	  networkRequest,
+	  workerUtils
+	};
+
+/***/ },
+/* 7 */
+/***/ function(module, exports) {
+
+	function networkRequest(url, opts) {
+	  return new Promise((resolve, reject) => {
+	    const req = new XMLHttpRequest();
+
+	    req.addEventListener("readystatechange", () => {
+	      if (req.readyState === XMLHttpRequest.DONE) {
+	        if (req.status === 200) {
+	          resolve({ content: req.responseText });
+	        } else {
+	          resolve(req.statusText);
+	        }
+	      }
+	    });
+
+	    // Not working yet.
+	    // if (!opts.loadFromCache) {
+	    //   req.channel.loadFlags = (
+	    //     Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE |
+	    //       Components.interfaces.nsIRequest.INHIBIT_CACHING |
+	    //       Components.interfaces.nsIRequest.LOAD_ANONYMOUS
+	    //   );
+	    // }
+
+	    req.open("GET", url);
+	    req.send();
+	  });
+	}
+
+	module.exports = networkRequest;
+
+/***/ },
+/* 8 */
+/***/ function(module, exports) {
+
+	
+
+	function WorkerDispatcher() {
+	  this.msgId = 1;
+	  this.worker = null;
+	}
+
+	WorkerDispatcher.prototype = {
+	  start(url) {
+	    this.worker = new Worker(url);
+	    this.worker.onerror = () => {
+	      console.error(`Error in worker ${url}`);
+	    };
+	  },
+
+	  stop() {
+	    if (!this.worker) {
+	      return;
+	    }
+
+	    this.worker.terminate();
+	    this.worker = null;
+	  },
+
+	  task(method) {
+	    return (...args) => {
+	      return new Promise((resolve, reject) => {
+	        const id = this.msgId++;
+	        this.worker.postMessage({ id, method, args });
+
+	        const listener = ({ data: result }) => {
+	          if (result.id !== id) {
+	            return;
+	          }
+
+	          this.worker.removeEventListener("message", listener);
+	          if (result.error) {
+	            reject(result.error);
+	          } else {
+	            resolve(result.response);
+	          }
+	        };
+
+	        this.worker.addEventListener("message", listener);
+	      });
+	    };
+	  }
+	};
+
+	function workerHandler(publicInterface) {
+	  return function workerHandler(msg) {
+	    const { id, method, args } = msg.data;
+	    const response = publicInterface[method].apply(undefined, args);
+	    if (response instanceof Promise) {
+	      response.then(val => self.postMessage({ id, response: val }), err => self.postMessage({ id, error: err }));
+	    } else {
+	      self.postMessage({ id, response });
+	    }
+	  };
+	}
+
+	module.exports = {
+	  WorkerDispatcher,
+	  workerHandler
+	};
+
+/***/ },
+/* 9 */
 /***/ function(module, exports, __webpack_require__) {
 
 	let _resolveAndFetch = (() => {
 	  var _ref = _asyncToGenerator(function* (generatedSource) {
 	    // Fetch the sourcemap over the network and create it.
 	    const sourceMapURL = _resolveSourceMapURL(generatedSource);
 	    const fetched = yield networkRequest(sourceMapURL, { loadFromCache: false });
 
@@ -665,16 +686,17 @@ return /******/ (function(modules) { // 
 
 	    if (url == null) {
 	      // No url means the location didn't map.
 	      return location;
 	    }
 
 	    return {
 	      sourceId: generatedToOriginalId(location.sourceId, url),
+	      sourceUrl: url,
 	      line,
 	      column
 	    };
 	  });
 
 	  return function getOriginalLocation(_x5) {
 	    return _ref4.apply(this, arguments);
 	  };
@@ -701,29 +723,44 @@ return /******/ (function(modules) { // 
 	    };
 	  });
 
 	  return function getOriginalSourceText(_x6) {
 	    return _ref5.apply(this, arguments);
 	  };
 	})();
 
+	let hasMappedSource = (() => {
+	  var _ref6 = _asyncToGenerator(function* (location) {
+	    if (isOriginalId(location.sourceId)) {
+	      return true;
+	    }
+
+	    const loc = yield getOriginalLocation(location);
+	    return loc.sourceId !== location.sourceId;
+	  });
+
+	  return function hasMappedSource(_x7) {
+	    return _ref6.apply(this, arguments);
+	  };
+	})();
+
 	function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
 
 	/**
 	 * Source Map Worker
 	 * @module utils/source-map-worker
 	 */
 
-	const networkRequest = __webpack_require__(85);
-
-	const { parse } = __webpack_require__(86);
-	const path = __webpack_require__(93);
-	const { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(94);
-	const assert = __webpack_require__(105);
+	const { networkRequest } = __webpack_require__(6);
+
+	const { parse } = __webpack_require__(10);
+	const path = __webpack_require__(17);
+	const { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(18);
+	const assert = __webpack_require__(29);
 	const {
 	  originalToGeneratedId,
 	  generatedToOriginalId,
 	  isGeneratedId,
 	  isOriginalId,
 	  getContentType
 	} = __webpack_require__(1);
 
@@ -808,55 +845,22 @@ return /******/ (function(modules) { // 
 	}
 
 	module.exports = {
 	  getOriginalURLs,
 	  getGeneratedLocation,
 	  getOriginalLocation,
 	  getOriginalSourceText,
 	  applySourceMap,
-	  clearSourceMaps
+	  clearSourceMaps,
+	  hasMappedSource
 	};
 
 /***/ },
-/* 85 */
-/***/ function(module, exports) {
-
-	function networkRequest(url, opts) {
-	  return new Promise((resolve, reject) => {
-	    const req = new XMLHttpRequest();
-
-	    req.addEventListener("readystatechange", () => {
-	      if (req.readyState === XMLHttpRequest.DONE) {
-	        if (req.status === 200) {
-	          resolve({ content: req.responseText });
-	        } else {
-	          resolve(req.statusText);
-	        }
-	      }
-	    });
-
-	    // Not working yet.
-	    // if (!opts.loadFromCache) {
-	    //   req.channel.loadFlags = (
-	    //     Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE |
-	    //       Components.interfaces.nsIRequest.INHIBIT_CACHING |
-	    //       Components.interfaces.nsIRequest.LOAD_ANONYMOUS
-	    //   );
-	    // }
-
-	    req.open("GET", url);
-	    req.send();
-	  });
-	}
-
-	module.exports = networkRequest;
-
-/***/ },
-/* 86 */
+/* 10 */
 /***/ function(module, exports, __webpack_require__) {
 
 	// Copyright Joyent, Inc. and other Node contributors.
 	//
 	// Permission is hereby granted, free of charge, to any person obtaining a
 	// copy of this software and associated documentation files (the
 	// "Software"), to deal in the Software without restriction, including
 	// without limitation the rights to use, copy, modify, merge, publish,
@@ -872,18 +876,18 @@ return /******/ (function(modules) { // 
 	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 	// USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 	'use strict';
 
-	var punycode = __webpack_require__(87);
-	var util = __webpack_require__(89);
+	var punycode = __webpack_require__(11);
+	var util = __webpack_require__(13);
 
 	exports.parse = urlParse;
 	exports.resolve = urlResolve;
 	exports.resolveObject = urlResolveObject;
 	exports.format = urlFormat;
 
 	exports.Url = Url;
 
@@ -948,17 +952,17 @@ return /******/ (function(modules) { // 
 	      'gopher': true,