Merge m-c to m-i
authorPhil Ringnalda <philringnalda@gmail.com>
Tue, 13 Dec 2016 19:30:23 -0800
changeset 325783 896c2e2190869600e65d5d8c5c4365e4a0bcc9b3
parent 325750 463b97f06397a48af538932db829fb3a71af1dde (current diff)
parent 325782 1ea0c60db5d25a7d522e2f252c1978ff4fc7538e (diff)
child 325784 33c69deecb7a16639664b91e7e107e1d7dd74e33
push id84796
push userphilringnalda@gmail.com
push dateWed, 14 Dec 2016 03:30:34 +0000
treeherdermozilla-inbound@896c2e219086 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone53.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 m-i MozReview-Commit-ID: EDvQhOpyRJu
--- a/browser/.eslintrc.js
+++ b/browser/.eslintrc.js
@@ -1,16 +1,11 @@
 "use strict";
 
 module.exports = {
   "extends": [
     "../toolkit/.eslintrc.js"
   ],
 
   "rules": {
-    "no-unused-vars": ["error", {
-      "vars": "local",
-      "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
-      "args": "none",
-    }],
     "no-shadow": "error"
   }
 };
--- a/browser/base/.eslintrc.js
+++ b/browser/base/.eslintrc.js
@@ -1,11 +1,4 @@
 "use strict";
 
 module.exports = {
-  "rules": {
-    "no-unused-vars": ["error", {
-      "vars": "local",
-      "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
-      "args": "none",
-    }]
-  }
 };
--- a/browser/components/originattributes/test/browser/browser.ini
+++ b/browser/components/originattributes/test/browser/browser.ini
@@ -62,8 +62,10 @@ support-files =
 [browser_favicon_firstParty.js]
 [browser_favicon_userContextId.js]
 [browser_firstPartyIsolation.js]
 [browser_localStorageIsolation.js]
 [browser_blobURLIsolation.js]
 [browser_imageCacheIsolation.js]
 [browser_sharedworker.js]
 [browser_httpauth.js]
+[browser_clientAuth.js]
+[browser_cacheAPI.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/browser_cacheAPI.js
@@ -0,0 +1,18 @@
+const requestURL = "https://test1.example.com";
+
+function getResult(aBrowser) {
+  return ContentTask.spawn(aBrowser, requestURL, function* (url) {
+    let cache = yield content.caches.open("TEST_CACHE");
+    let response = yield cache.match(url);
+    if (response) {
+      return response.statusText;
+    }
+    let result = Math.random().toString();
+    response = new content.Response("", { statusText: result });
+    yield cache.put(url, response);
+    return result;
+  });
+}
+
+IsolationTestTools.runTests("https://test2.example.com", getResult, null, null,
+                            false, /* aUseHttps */ true);
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/browser_clientAuth.js
@@ -0,0 +1,44 @@
+let certCached = true;
+let secondTabStarted = false;
+
+function onCertDialogLoaded(subject) {
+  certCached = false;
+  // Click OK.
+  subject.acceptDialog();
+}
+
+Services.obs.addObserver(onCertDialogLoaded, "cert-dialog-loaded", false);
+
+registerCleanupFunction(() => {
+  Services.obs.removeObserver(onCertDialogLoaded, "cert-dialog-loaded");
+});
+
+function* setup() {
+  yield SpecialPowers.pushPrefEnv({
+    set: [["security.default_personal_cert", "Ask Every Time"]]
+  });
+}
+
+function getResult() {
+  // The first tab always returns true.
+  if (!secondTabStarted) {
+    certCached = true;
+    secondTabStarted = true;
+    return true;
+  }
+
+  // The second tab returns true if the cert is cached, so it will be different
+  // from the result of the first tab, and considered isolated.
+  let ret = certCached;
+  certCached = true;
+  secondTabStarted = false;
+  return ret;
+}
+
+// aGetResultImmediately must be true because we need to get the result before
+// the next tab is opened.
+IsolationTestTools.runTests("https://requireclientcert.example.com",
+                            getResult,
+                            null, // aCompareResultFunc
+                            setup, // aBeginFunc
+                            true); // aGetResultImmediately
--- a/browser/components/originattributes/test/browser/head.js
+++ b/browser/components/originattributes/test/browser/head.js
@@ -270,18 +270,21 @@ this.IsolationTestTools = {
    *    An optional function which allows modifying the way how does framework
    *    check results. This function will be provided a boolean to indicate
    *    the isolation is no or off and two results. This function should return
    *    a boolean to tell that whether isolation is working. If this function
    *    is not given, the framework will take case checking by itself.
    * @param aBeforeFunc
    *    An optional function which is called before any tabs are created so
    *    that the test case can set up/reset local state.
+   * @param aGetResultImmediately
+   *    An optional boolean to ensure we get results before the next tab is opened.
    */
-  runTests(aURL, aGetResultFuncs, aCompareResultFunc, aBeforeFunc) {
+  runTests(aURL, aGetResultFuncs, aCompareResultFunc, aBeforeFunc,
+           aGetResultImmediately, aUseHttps) {
     let pageURL;
     let firstFrameSetting;
     let secondFrameSetting;
 
     // Request a longer timeout since the test will run a test for three times
     // with different settings. Thus, one test here represents three tests.
     // For this reason, we triple the timeout.
     requestLongerTimeout(3);
@@ -293,17 +296,20 @@ this.IsolationTestTools = {
       firstFrameSetting = aURL.firstFrameSetting;
       secondFrameSetting = aURL.secondFrameSetting;
     }
 
     if (!Array.isArray(aGetResultFuncs)) {
       aGetResultFuncs = [aGetResultFuncs];
     }
 
-    let tabSettings = [
+    let tabSettings = aUseHttps ? [
+                        { firstPartyDomain: "https://example.com", userContextId: 1},
+                        { firstPartyDomain: "https://example.org", userContextId: 2}
+                      ] : [
                         { firstPartyDomain: "http://example.com", userContextId: 1},
                         { firstPartyDomain: "http://example.org", userContextId: 2}
                       ];
 
     this._add_task(function* (aMode) {
       let tabSettingA = 0;
 
       for (let tabSettingB of [0, 1]) {
@@ -312,24 +318,31 @@ this.IsolationTestTools = {
           yield aBeforeFunc(aMode);
         }
 
         // Create Tabs.
         let tabInfoA = yield IsolationTestTools._addTab(aMode,
                                                         pageURL,
                                                         tabSettings[tabSettingA],
                                                         firstFrameSetting);
+        let resultsA = [];
+        if (aGetResultImmediately) {
+          for (let getResultFunc of aGetResultFuncs) {
+            resultsA.push(yield getResultFunc(tabInfoA.browser));
+          }
+        }
         let tabInfoB = yield IsolationTestTools._addTab(aMode,
                                                         pageURL,
                                                         tabSettings[tabSettingB],
                                                         secondFrameSetting);
-
+        let i = 0;
         for (let getResultFunc of aGetResultFuncs) {
           // Fetch results from tabs.
-          let resultA = yield getResultFunc(tabInfoA.browser);
+          let resultA = aGetResultImmediately ? resultsA[i++] :
+                        yield getResultFunc(tabInfoA.browser);
           let resultB = yield getResultFunc(tabInfoB.browser);
 
           // Compare results.
           let result = false;
           let shouldIsolate = (aMode !== TEST_MODE_NO_ISOLATION) &&
                               tabSettingA !== tabSettingB;
           if (aCompareResultFunc) {
             result = yield aCompareResultFunc(shouldIsolate, resultA, resultB);
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -969,32 +969,35 @@
             return;
           }
 
           // Check for middle-click or modified clicks on the search bar
           if (popupForSearchBar) {
             // Handle search bar popup clicks
             var search = controller.getValueAt(this.selectedIndex);
 
-            // close the autocomplete popup and revert the entered search term
-            this.closePopup();
-            controller.handleEscape();
-
             // open the search results according to the clicking subtlety
             var where = whereToOpenLink(aEvent, false, true);
             let params = {};
 
             // But open ctrl/cmd clicks on autocomplete items in a new background tab.
             let modifier = this.AppConstants.platform == "macosx" ?
                            aEvent.metaKey :
                            aEvent.ctrlKey;
             if (where == "tab" && (aEvent instanceof MouseEvent) &&
                 (aEvent.button == 1 || modifier))
               params.inBackground = true;
 
+            // leave the popup open for background tab loads
+            if (!(where == "tab" && params.inBackground)) {
+              // close the autocomplete popup and revert the entered search term
+              this.closePopup();
+              controller.handleEscape();
+            }
+
             searchBar.doSearch(search, where, null, params);
             if (where == "tab" && params.inBackground)
               searchBar.focus();
             else
               searchBar.value = search;
           }
         ]]></body>
       </method>
@@ -2222,24 +2225,16 @@
           return; // ignore right clicks.
 
         let button = event.originalTarget;
         let engine = button.engine || button.parentNode.engine;
 
         if (!engine)
           return;
 
-        // For some reason, if the context menu had been opened prior to the
-        // click, the suggestions popup won't be closed after loading the search
-        // in the current tab - so we hide it manually. Some focusing magic
-        // that happens when a search is loaded ensures that the popup is opened
-        // again if it needs to be, so we don't need to worry about which cases
-        // require manual hiding.
-        this.popup.hidePopup();
-
         // Select the clicked button so that consumers can easily tell which
         // button was acted on.
         this.selectedButton = button;
         this.handleSearchCommand(event, engine);
       ]]></handler>
 
       <handler event="command"><![CDATA[
         let target = event.originalTarget;
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -698,16 +698,17 @@ GK_ATOM(onanimationiteration, "onanimati
 GK_ATOM(onanimationstart, "onanimationstart")
 GK_ATOM(onantennaavailablechange, "onantennaavailablechange")
 GK_ATOM(onAppCommand, "onAppCommand")
 GK_ATOM(onappinstalled, "onappinstalled")
 GK_ATOM(onattributechanged, "onattributechanged")
 GK_ATOM(onattributereadreq, "onattributereadreq")
 GK_ATOM(onattributewritereq, "onattributewritereq")
 GK_ATOM(onaudioprocess, "onaudioprocess")
+GK_ATOM(onauxclick, "onauxclick")
 GK_ATOM(onbeforecopy, "onbeforecopy")
 GK_ATOM(onbeforecut, "onbeforecut")
 GK_ATOM(onbeforepaste, "onbeforepaste")
 GK_ATOM(onbeforeevicted, "onbeforeevicted")
 GK_ATOM(onbeforeprint, "onbeforeprint")
 GK_ATOM(onbeforescriptexecute, "onbeforescriptexecute")
 GK_ATOM(onbeforeunload, "onbeforeunload")
 GK_ATOM(onblocked, "onblocked")
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -159,16 +159,20 @@ EVENT(canplay,
 EVENT(canplaythrough,
       eCanPlayThrough,
       EventNameType_HTML,
       eBasicEventClass)
 EVENT(change,
       eFormChange,
       EventNameType_HTMLXUL,
       eBasicEventClass)
+EVENT(auxclick,
+      eMouseAuxClick,
+      EventNameType_All,
+      eMouseEventClass)
 EVENT(click,
       eMouseClick,
       EventNameType_All,
       eMouseEventClass)
 EVENT(contextmenu,
       eContextMenu,
       EventNameType_HTMLXUL,
       eMouseEventClass)
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -484,16 +484,17 @@ EventStateManager::TryToFlushPendingNoti
 }
 
 static bool
 IsMessageMouseUserActivity(EventMessage aMessage)
 {
   return aMessage == eMouseMove ||
          aMessage == eMouseUp ||
          aMessage == eMouseDown ||
+         aMessage == eMouseAuxClick ||
          aMessage == eMouseDoubleClick ||
          aMessage == eMouseClick ||
          aMessage == eMouseActivate ||
          aMessage == eMouseLongTap;
 }
 
 static bool
 IsMessageGamepadUserActivity(EventMessage aMessage)
@@ -4613,16 +4614,42 @@ EventStateManager::SetClickCount(WidgetM
     }
     break;
   }
 
   return NS_OK;
 }
 
 nsresult
+EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aEvent,
+                                             nsEventStatus* aStatus,
+                                             EventMessage aMessage,
+                                             nsIPresShell* aPresShell,
+                                             nsIContent* aMouseTarget,
+                                             nsWeakFrame aCurrentTarget,
+                                             bool aNoContentDispatch)
+{
+  WidgetMouseEvent event(aEvent->IsTrusted(), aMessage,
+                         aEvent->mWidget, WidgetMouseEvent::eReal);
+
+  event.mRefPoint = aEvent->mRefPoint;
+  event.mClickCount = aEvent->mClickCount;
+  event.mModifiers = aEvent->mModifiers;
+  event.buttons = aEvent->buttons;
+  event.mTime = aEvent->mTime;
+  event.mTimeStamp = aEvent->mTimeStamp;
+  event.mFlags.mNoContentDispatch = aNoContentDispatch;
+  event.button = aEvent->button;
+  event.inputSource = aEvent->inputSource;
+
+  return aPresShell->HandleEventWithTarget(&event, aCurrentTarget,
+                                           aMouseTarget, aStatus);
+}
+
+nsresult
 EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
                                             nsEventStatus* aStatus)
 {
   nsresult ret = NS_OK;
 
   //If mouse is still over same element, clickcount will be > 1.
   //If it has moved it will be zero, so no click.
   if (aEvent->mClickCount) {
@@ -4631,27 +4658,17 @@ EventStateManager::CheckForAndDispatchCl
     if (aEvent->mWidget && !aEvent->mWidget->IsEnabled()) {
       return ret;
     }
     //fire click
     bool notDispatchToContents =
      (aEvent->button == WidgetMouseEvent::eMiddleButton ||
       aEvent->button == WidgetMouseEvent::eRightButton);
 
-    WidgetMouseEvent event(aEvent->IsTrusted(), eMouseClick,
-                           aEvent->mWidget, WidgetMouseEvent::eReal);
-    event.mRefPoint = aEvent->mRefPoint;
-    event.mClickCount = aEvent->mClickCount;
-    event.mModifiers = aEvent->mModifiers;
-    event.buttons = aEvent->buttons;
-    event.mTime = aEvent->mTime;
-    event.mTimeStamp = aEvent->mTimeStamp;
-    event.mFlags.mNoContentDispatch = notDispatchToContents;
-    event.button = aEvent->button;
-    event.inputSource = aEvent->inputSource;
+    bool fireAuxClick = notDispatchToContents;
 
     nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
     if (presShell) {
       nsCOMPtr<nsIContent> mouseContent = GetEventTargetContent(aEvent);
       // Click events apply to *elements* not nodes. At this point the target
       // content may have been reset to some non-element content, and so we need
       // to walk up the closest ancestor element, just like we do in
       // nsPresShell::HandlePositionedEvent.
@@ -4660,35 +4677,32 @@ EventStateManager::CheckForAndDispatchCl
       }
 
       if (!mouseContent && !mCurrentTarget) {
         return NS_OK;
       }
 
       // HandleEvent clears out mCurrentTarget which we might need again
       nsWeakFrame currentTarget = mCurrentTarget;
-      ret = presShell->HandleEventWithTarget(&event, currentTarget,
-                                             mouseContent, aStatus);
+      ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseClick,
+                                      presShell, mouseContent, currentTarget,
+                                      notDispatchToContents);
+
       if (NS_SUCCEEDED(ret) && aEvent->mClickCount == 2 &&
           mouseContent && mouseContent->IsInComposedDoc()) {
         //fire double click
-        WidgetMouseEvent event2(aEvent->IsTrusted(), eMouseDoubleClick,
-                                aEvent->mWidget, WidgetMouseEvent::eReal);
-        event2.mRefPoint = aEvent->mRefPoint;
-        event2.mClickCount = aEvent->mClickCount;
-        event2.mModifiers = aEvent->mModifiers;
-        event2.buttons = aEvent->buttons;
-        event2.mTime = aEvent->mTime;
-        event2.mTimeStamp = aEvent->mTimeStamp;
-        event2.mFlags.mNoContentDispatch = notDispatchToContents;
-        event2.button = aEvent->button;
-        event2.inputSource = aEvent->inputSource;
-
-        ret = presShell->HandleEventWithTarget(&event2, currentTarget,
-                                               mouseContent, aStatus);
+        ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseDoubleClick,
+                                        presShell, mouseContent, currentTarget,
+                                        notDispatchToContents);
+      }
+      if (NS_SUCCEEDED(ret) && mouseContent && fireAuxClick &&
+          mouseContent->IsInComposedDoc()) {
+        ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseAuxClick,
+                                        presShell, mouseContent, currentTarget,
+                                        false);
       }
     }
   }
   return ret;
 }
 
 nsIFrame*
 EventStateManager::GetEventTarget()
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -410,16 +410,23 @@ protected:
                            nsIContent* aTargetContent,
                            nsWeakFrame& aTargetFrame);
   /**
    * Update the initial drag session data transfer with any changes that occur
    * on cloned data transfer objects used for events.
    */
   void UpdateDragDataTransfer(WidgetDragEvent* dragEvent);
 
+  static nsresult InitAndDispatchClickEvent(WidgetMouseEvent* aEvent,
+                                            nsEventStatus* aStatus,
+                                            EventMessage aMessage,
+                                            nsIPresShell* aPresShell,
+                                            nsIContent* aMouseTarget,
+                                            nsWeakFrame aCurrentTarget,
+                                            bool aNoContentDispatch);
   nsresult SetClickCount(WidgetMouseEvent* aEvent, nsEventStatus* aStatus);
   nsresult CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
                                     nsEventStatus* aStatus);
   void EnsureDocument(nsPresContext* aPresContext);
   void FlushPendingEvents(nsPresContext* aPresContext);
 
   /**
    * The phases of HandleAccessKey processing. See below.
@@ -1039,11 +1046,12 @@ private:
 
 } // namespace mozilla
 
 // Click and double-click events need to be handled even for content that
 // has no frame. This is required for Web compatibility.
 #define NS_EVENT_NEEDS_FRAME(event) \
     (!(event)->HasPluginActivationEventMessage() && \
      (event)->mMessage != eMouseClick && \
-     (event)->mMessage != eMouseDoubleClick)
+     (event)->mMessage != eMouseDoubleClick && \
+     (event)->mMessage != eMouseAuxClick)
 
 #endif // mozilla_EventStateManager_h_
--- a/dom/events/WheelHandlingHelper.cpp
+++ b/dom/events/WheelHandlingHelper.cpp
@@ -252,16 +252,17 @@ WheelTransaction::OnEvent(WidgetEvent* a
       return;
     }
     case eKeyPress:
     case eKeyUp:
     case eKeyDown:
     case eMouseUp:
     case eMouseDown:
     case eMouseDoubleClick:
+    case eMouseAuxClick:
     case eMouseClick:
     case eContextMenu:
     case eDrop:
       EndTransaction();
       return;
     default:
       break;
   }
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -179,8 +179,9 @@ skip-if = toolkit == 'android' #CRASH_DU
 [test_offsetxy.html]
 [test_onerror_handler_args.html]
 [test_passive_listeners.html]
 [test_paste_image.html]
 [test_wheel_default_action.html]
 [test_bug687787.html]
 [test_bug1305458.html]
 [test_bug1298970.html]
+[test_bug1304044.html]
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1304044.html
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1304044
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1304044</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+    var eventsFired = [];
+    var target;
+    var eventsExpected;
+
+    function GetNodeString(node) {
+      if (node == window)
+        return "window";
+      if (node == document)
+        return "document";
+      if (node.id)
+        return node.id;
+      if (node.nodeName)
+        return node.nodeName;
+      return node;
+    }
+
+    function TargetAndListener(listener, target) {
+      this.listener = listener;
+      this.target = target;
+    }
+
+    TargetAndListener.prototype.toString = function() {
+      var targetName = GetNodeString(this.target);
+      var listenerName = GetNodeString(this.listener);
+      return "(listener: " + listenerName + ", target: " + targetName + ")";
+    }
+
+    var tests = [
+      TestAuxClickBubblesForEventListener,
+      TestAuxClickBubblesForOnAuxClick,
+    ];
+
+    function CompareEvents(evt, expected) {
+      return evt && expected && evt.listener == expected.listener &&
+          evt.target == expected.target;
+    }
+
+    function ResetEventsFired() {
+      eventsFired = [];
+    }
+
+    function ClearEventListeners() {
+      for (i in arguments) {
+        arguments[i].removeEventListener("auxclick", log_event);
+      }
+    }
+
+    function ClickTarget(tgt) {
+      synthesizeMouseAtCenter(tgt, {type : "mousedown", button: 2}, window);
+      synthesizeMouseAtCenter(tgt, {type : "mouseup", button: 2}, window);
+    }
+
+    function log_event(e) {
+      eventsFired[eventsFired.length] = new TargetAndListener(this, e.target);
+    }
+
+    function CompareEventsToExpected(expected, actual) {
+      for (var i = 0; i < expected.length || i < actual.length; i++) {
+        ok(CompareEvents(actual[i], expected[i]),
+           "Auxclick receiver's don't match: TargetAndListener " +
+           i + ": Expected: " + expected[i] + ", Actual: " + actual[i]);
+      }
+    }
+
+    function TestAuxClickBubblesForEventListener() {
+      target.addEventListener("auxclick", log_event);
+      document.addEventListener("auxclick", log_event);
+      window.addEventListener("auxclick", log_event);
+
+      ClickTarget(target)
+      CompareEventsToExpected(eventsExpected, eventsFired);
+      ResetEventsFired();
+      ClearEventListeners(target, document, window);
+    }
+
+    function TestAuxClickBubblesForOnAuxClick() {
+      target.onauxclick = log_event;
+      document.onauxclick = log_event;
+      window.onauxclick = log_event;
+
+      ClickTarget(target);
+      CompareEventsToExpected(eventsExpected, eventsFired);
+      ResetEventsFired();
+    }
+
+    function RunTests(){
+      for (var i = 0; i < tests.length; i++) {
+        tests[i]();
+      }
+    }
+
+    function Begin() {
+      target = document.getElementById("target");
+      eventsExpected =  [
+        new TargetAndListener(target, target),
+        new TargetAndListener(document, target),
+        new TargetAndListener(window, target),
+      ];
+      RunTests();
+      target.remove();
+      SimpleTest.finish();
+    }
+
+    window.onload = function() {
+      SimpleTest.waitForExplicitFinish();
+      SimpleTest.executeSoon(Begin);
+    }
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1304044">Mozilla Bug 1304044</a>
+<p id="display">
+  <div id="target">Target</div>
+</p>
+<div id="content" style:"display:none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -14,17 +14,17 @@
 #include "nsIFormControl.h"
 #include "nsGkAtoms.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozilla/ErrorResult.h"
 #include "nsIDOMHTMLMenuElement.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/DOMRect.h"
 #include "mozilla/dom/ValidityState.h"
-#include "mozilla/dom/ElementInlines.h"
+#include "mozilla/dom/Element.h"
 
 class nsDOMTokenList;
 class nsIDOMHTMLMenuElement;
 class nsIEditor;
 class nsIFormControlFrame;
 class nsIFrame;
 class nsILayoutHistoryState;
 class nsIURI;
--- a/dom/mathml/nsMathMLElement.h
+++ b/dom/mathml/nsMathMLElement.h
@@ -3,17 +3,17 @@
 /* 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/. */
 
 #ifndef nsMathMLElement_h
 #define nsMathMLElement_h
 
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/ElementInlines.h"
+#include "mozilla/dom/Element.h"
 #include "nsMappedAttributeElement.h"
 #include "nsIDOMElement.h"
 #include "Link.h"
 #include "mozilla/dom/DOMRect.h"
 
 class nsCSSValue;
 
 typedef nsMappedAttributeElement nsMathMLElementBase;
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -437,17 +437,21 @@ RTCPeerConnection.prototype = {
     this.__DOM_IMPL__._innerObject = this;
     this._observer = new this._win.PeerConnectionObserver(this.__DOM_IMPL__);
 
     var location = "" + this._win.location;
 
     // Warn just once per PeerConnection about deprecated getStats usage.
     this._warnDeprecatedStatsAccessNullable = { warn: () =>
       this.logWarning("non-maplike pc.getStats access is deprecated! " +
-                      "See http://w3c.github.io/webrtc-pc/#example for usage.") };
+                      "See http://w3c.github.io/webrtc-pc/#getstats-example for usage.") };
+
+    this._warnDeprecatedStatsCallbacksNullable = { warn: () =>
+      this.logWarning("Callback-based pc.getStats is deprecated! Use promise-version! " +
+                      "See http://w3c.github.io/webrtc-pc/#getstats-example for usage.") };
 
     // Add a reference to the PeerConnection to global list (before init).
     _globalPCList.addPC(this);
 
     this._impl.initialize(this._observer, this._win, rtcConfig,
                           Services.tm.currentThread);
 
     this._certificateReady = this._initCertificate(rtcConfig.certificates);
@@ -1208,16 +1212,21 @@ RTCPeerConnection.prototype = {
 
   changeIceConnectionState: function(state) {
     this._iceConnectionState = state;
     _globalPCList.notifyLifecycleObservers(this, "iceconnectionstatechange");
     this.dispatchEvent(new this._win.Event("iceconnectionstatechange"));
   },
 
   getStats: function(selector, onSucc, onErr) {
+    if (typeof onSucc == "function" &&
+        this._warnDeprecatedStatsCallbacksNullable.warn) {
+      this._warnDeprecatedStatsCallbacksNullable.warn();
+      this._warnDeprecatedStatsCallbacksNullable.warn = null;
+    }
     return this._auto(onSucc, onErr, () => this._getStats(selector));
   },
 
   _getStats: async function(selector) {
     // getStats is allowed even in closed state.
     return await this._chain(() => new Promise((resolve, reject) => {
       this._onGetStatsSuccess = resolve;
       this._onGetStatsFailure = reject;
@@ -1485,17 +1494,18 @@ PeerConnectionObserver.prototype = {
         break;
     }
   },
 
   onGetStatsSuccess: function(dict) {
     let pc = this._dompc;
     let chromeobj = new RTCStatsReport(pc._win, dict);
     let webidlobj = pc._win.RTCStatsReport._create(pc._win, chromeobj);
-    chromeobj.makeStatsPublic(pc._warnDeprecatedStatsAccessNullable);
+    chromeobj.makeStatsPublic(pc._warnDeprecatedStatsCallbacksNullable &&
+                              pc._warnDeprecatedStatsAccessNullable);
     pc._onGetStatsSuccess(webidlobj);
   },
 
   onGetStatsError: function(code, message) {
     this._dompc._onGetStatsFailure(this.newError(message, code));
   },
 
   onAddStream: function(stream) {
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -107,16 +107,18 @@ struct ParamTraits<mozilla::dom::RTCStat
     WriteParam(aMsg, aParam.mInboundRTPStreamStats);
     WriteParam(aMsg, aParam.mLocalSdp);
     WriteParam(aMsg, aParam.mMediaStreamStats);
     WriteParam(aMsg, aParam.mMediaStreamTrackStats);
     WriteParam(aMsg, aParam.mOutboundRTPStreamStats);
     WriteParam(aMsg, aParam.mPcid);
     WriteParam(aMsg, aParam.mRemoteSdp);
     WriteParam(aMsg, aParam.mTimestamp);
+    WriteParam(aMsg, aParam.mIceRestarts);
+    WriteParam(aMsg, aParam.mIceRollbacks);
     WriteParam(aMsg, aParam.mTransportStats);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mClosed)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCodecStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIceCandidatePairStats)) ||
@@ -125,16 +127,18 @@ struct ParamTraits<mozilla::dom::RTCStat
         !ReadParam(aMsg, aIter, &(aResult->mInboundRTPStreamStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mLocalSdp)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMediaStreamStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMediaStreamTrackStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mOutboundRTPStreamStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPcid)) ||
         !ReadParam(aMsg, aIter, &(aResult->mRemoteSdp)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTimestamp)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mIceRestarts)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mIceRollbacks)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTransportStats))) {
       return false;
     }
 
     return true;
   }
 };
 
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -2527,16 +2527,17 @@ nsEventStatus nsPluginInstanceOwner::Pro
     if (pPluginEvent) {
       // Make event coordinates relative to our enclosing widget,
       // not the widget they were received on.
       // See use of NPEvent in widget/windows/nsWindow.cpp
       // for why this assert should be safe
       NS_ASSERTION(anEvent.mMessage == eMouseDown ||
                    anEvent.mMessage == eMouseUp ||
                    anEvent.mMessage == eMouseDoubleClick ||
+                   anEvent.mMessage == eMouseAuxClick ||
                    anEvent.mMessage == eMouseOver ||
                    anEvent.mMessage == eMouseOut ||
                    anEvent.mMessage == eMouseMove ||
                    anEvent.mMessage == eWheel,
                    "Incorrect event type for coordinate translation");
       nsPoint pt =
         nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
         mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
@@ -2589,16 +2590,17 @@ nsEventStatus nsPluginInstanceOwner::Pro
   pluginEvent.type = 0;
 
   switch(anEvent.mClass) {
     case eMouseEventClass:
       {
         switch (anEvent.mMessage) {
           case eMouseClick:
           case eMouseDoubleClick:
+          case eMouseAuxClick:
             // Button up/down events sent instead.
             return rv;
           default:
             break;
           }
 
         // Get reference point relative to plugin origin.
         const nsPresContext* presContext = mPluginFrame->PresContext();
@@ -2792,16 +2794,17 @@ nsEventStatus nsPluginInstanceOwner::Pro
     }
   }
   switch(anEvent.mClass) {
     case eMouseEventClass:
       {
         switch (anEvent.mMessage) {
           case eMouseClick:
           case eMouseDoubleClick:
+          case eMouseAuxClick:
             // Button up/down events sent instead.
             return rv;
           default:
             break;
           }
 
         // Get reference point relative to plugin origin.
         const nsPresContext* presContext = mPluginFrame->PresContext();
--- a/dom/svg/nsSVGElement.h
+++ b/dom/svg/nsSVGElement.h
@@ -15,17 +15,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsAutoPtr.h"
 #include "nsChangeHint.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
 #include "mozilla/dom/DOMRect.h"
-#include "mozilla/dom/ElementInlines.h"
+#include "mozilla/dom/Element.h"
 #include "nsISupportsImpl.h"
 #include "nsStyledElement.h"
 #include "nsSVGClass.h"
 #include "nsIDOMSVGElement.h"
 #include "SVGContentUtils.h"
 
 class nsSVGAngle;
 class nsSVGBoolean;
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -32,125 +32,16 @@ typedef (HTMLImageElement or
          ImageBitmap) CanvasImageSource;
 
 interface CanvasRenderingContext2D {
 
   // back-reference to the canvas.  Might be null if we're not
   // associated with a canvas.
   readonly attribute HTMLCanvasElement? canvas;
 
-  // state
-  void save(); // push state on state stack
-  void restore(); // pop state stack and restore state
-
-  // transformations (default transform is the identity matrix)
-// NOT IMPLEMENTED           attribute SVGMatrix currentTransform;
-  [Throws, LenientFloat]
-  void scale(double x, double y);
-  [Throws, LenientFloat]
-  void rotate(double angle);
-  [Throws, LenientFloat]
-  void translate(double x, double y);
-  [Throws, LenientFloat]
-  void transform(double a, double b, double c, double d, double e, double f);
-  [Throws, LenientFloat]
-  void setTransform(double a, double b, double c, double d, double e, double f);
-  [Throws]
-  void resetTransform();
-
-  // compositing
-           attribute unrestricted double globalAlpha; // (default 1.0)
-           [Throws]
-           attribute DOMString globalCompositeOperation; // (default source-over)
-
-  // colors and styles (see also the CanvasDrawingStyles interface)
-           attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default black)
-           attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
-  [NewObject]
-  CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
-  [NewObject, Throws]
-  CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
-  [NewObject, Throws]
-  CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetition);
-
-  // shadows
-           [LenientFloat]
-           attribute double shadowOffsetX; // (default 0)
-           [LenientFloat]
-           attribute double shadowOffsetY; // (default 0)
-           [LenientFloat]
-           attribute double shadowBlur; // (default 0)
-           attribute DOMString shadowColor; // (default transparent black)
-
-  [Pref="canvas.filters.enabled", SetterThrows]
-  attribute DOMString filter; // (default empty string = no filter)
-
-  // rects
-  [LenientFloat]
-  void clearRect(double x, double y, double w, double h);
-  [LenientFloat]
-  void fillRect(double x, double y, double w, double h);
-  [LenientFloat]
-  void strokeRect(double x, double y, double w, double h);
-
-  // path API (see also CanvasPathMethods)
-  void beginPath();
-  void fill(optional CanvasWindingRule winding = "nonzero");
-  void fill(Path2D path, optional CanvasWindingRule winding = "nonzero");
-  void stroke();
-  void stroke(Path2D path);
-  [Pref="canvas.focusring.enabled", Throws] void drawFocusIfNeeded(Element element);
-// NOT IMPLEMENTED  void drawSystemFocusRing(Path path, HTMLElement element);
-  [Pref="canvas.customfocusring.enabled"] boolean drawCustomFocusRing(Element element);
-// NOT IMPLEMENTED  boolean drawCustomFocusRing(Path path, HTMLElement element);
-// NOT IMPLEMENTED  void scrollPathIntoView();
-// NOT IMPLEMENTED  void scrollPathIntoView(Path path);
-  void clip(optional CanvasWindingRule winding = "nonzero");
-  void clip(Path2D path, optional CanvasWindingRule winding = "nonzero");
-// NOT IMPLEMENTED  void resetClip();
-  boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
-  boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
-  boolean isPointInStroke(double x, double y);
-  boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y);
-
-  // text (see also the CanvasDrawingStyles interface)
-  [Throws, LenientFloat]
-  void fillText(DOMString text, double x, double y, optional double maxWidth);
-  [Throws, LenientFloat]
-  void strokeText(DOMString text, double x, double y, optional double maxWidth);
-  [NewObject, Throws]
-  TextMetrics measureText(DOMString text);
-
-  // drawing images
-  attribute boolean imageSmoothingEnabled;
-
-  [Throws, LenientFloat]
-  void drawImage(CanvasImageSource image, double dx, double dy);
-  [Throws, LenientFloat]
-  void drawImage(CanvasImageSource image, double dx, double dy, double dw, double dh);
-  [Throws, LenientFloat]
-  void drawImage(CanvasImageSource image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh);
-
-  // hit regions
-  [Pref="canvas.hitregions.enabled", Throws] void addHitRegion(optional HitRegionOptions options);
-  [Pref="canvas.hitregions.enabled"] void removeHitRegion(DOMString id);
-  [Pref="canvas.hitregions.enabled"] void clearHitRegions();
-
-  // pixel manipulation
-  [NewObject, Throws]
-  ImageData createImageData(double sw, double sh);
-  [NewObject, Throws]
-  ImageData createImageData(ImageData imagedata);
-  [NewObject, Throws]
-  ImageData getImageData(double sx, double sy, double sw, double sh);
-  [Throws]
-  void putImageData(ImageData imagedata, double dx, double dy);
-  [Throws]
-  void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
-
   // Mozilla-specific stuff
   // FIXME Bug 768048 mozCurrentTransform/mozCurrentTransformInverse should return a WebIDL array.
   [Throws]
   attribute object mozCurrentTransform; // [ m11, m12, m21, m22, dx, dy ], i.e. row major
   [Throws]
   attribute object mozCurrentTransformInverse;
 
   [SetterThrows]
@@ -226,40 +117,201 @@ interface CanvasRenderingContext2D {
 
   /**
    * This causes a context that is currently using a hardware-accelerated
    * backend to fallback to a software one. All state should be preserved.
    */
   [ChromeOnly]
   void demote();
 };
-CanvasRenderingContext2D implements CanvasDrawingStyles;
+
+CanvasRenderingContext2D implements CanvasState;
+CanvasRenderingContext2D implements CanvasTransform;
+CanvasRenderingContext2D implements CanvasCompositing;
+CanvasRenderingContext2D implements CanvasImageSmoothing;
+CanvasRenderingContext2D implements CanvasFillStrokeStyles;
+CanvasRenderingContext2D implements CanvasShadowStyles;
+CanvasRenderingContext2D implements CanvasFilters;
+CanvasRenderingContext2D implements CanvasRect;
+CanvasRenderingContext2D implements CanvasDrawPath;
+CanvasRenderingContext2D implements CanvasUserInterface;
+CanvasRenderingContext2D implements CanvasText;
+CanvasRenderingContext2D implements CanvasDrawImage;
+CanvasRenderingContext2D implements CanvasImageData;
+CanvasRenderingContext2D implements CanvasPathDrawingStyles;
+CanvasRenderingContext2D implements CanvasTextDrawingStyles;
 CanvasRenderingContext2D implements CanvasPathMethods;
+CanvasRenderingContext2D implements CanvasHitRegions;
+
+
+[NoInterfaceObject]
+interface CanvasState {
+  // state
+  void save(); // push state on state stack
+  void restore(); // pop state stack and restore state
+};
+
+[NoInterfaceObject]
+interface CanvasTransform {
+  // transformations (default transform is the identity matrix)
+// NOT IMPLEMENTED           attribute SVGMatrix currentTransform;
+  [Throws, LenientFloat]
+  void scale(double x, double y);
+  [Throws, LenientFloat]
+  void rotate(double angle);
+  [Throws, LenientFloat]
+  void translate(double x, double y);
+  [Throws, LenientFloat]
+  void transform(double a, double b, double c, double d, double e, double f);
+  [Throws, LenientFloat]
+  void setTransform(double a, double b, double c, double d, double e, double f);
+  [Throws]
+  void resetTransform();
+};
+
+[NoInterfaceObject]
+interface CanvasCompositing {
+  attribute unrestricted double globalAlpha; // (default 1.0)
+  [Throws]
+  attribute DOMString globalCompositeOperation; // (default source-over)
+};
+
+[NoInterfaceObject]
+interface CanvasImageSmoothing {
+  // drawing images
+  attribute boolean imageSmoothingEnabled;
+};
+
+[NoInterfaceObject]
+interface CanvasFillStrokeStyles {
+  // colors and styles (see also the CanvasPathDrawingStyles interface)
+  attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default black)
+  attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
+  [NewObject]
+  CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
+  [NewObject, Throws]
+  CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
+  [NewObject, Throws]
+  CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetition);
+};
+
+[NoInterfaceObject]
+interface CanvasShadowStyles {
+  [LenientFloat]
+  attribute double shadowOffsetX; // (default 0)
+  [LenientFloat]
+  attribute double shadowOffsetY; // (default 0)
+  [LenientFloat]
+  attribute double shadowBlur; // (default 0)
+  attribute DOMString shadowColor; // (default transparent black)
+};
+
+[NoInterfaceObject]
+interface CanvasFilters {
+  [Pref="canvas.filters.enabled", SetterThrows]
+  attribute DOMString filter; // (default empty string = no filter)
+};
 
 [NoInterfaceObject]
-interface CanvasDrawingStyles {
+interface CanvasRect {
+  [LenientFloat]
+  void clearRect(double x, double y, double w, double h);
+  [LenientFloat]
+  void fillRect(double x, double y, double w, double h);
+  [LenientFloat]
+  void strokeRect(double x, double y, double w, double h);
+};
+
+[NoInterfaceObject]
+interface CanvasDrawPath {
+  // path API (see also CanvasPathMethods)
+  void beginPath();
+  void fill(optional CanvasWindingRule winding = "nonzero");
+  void fill(Path2D path, optional CanvasWindingRule winding = "nonzero");
+  void stroke();
+  void stroke(Path2D path);
+  void clip(optional CanvasWindingRule winding = "nonzero");
+  void clip(Path2D path, optional CanvasWindingRule winding = "nonzero");
+// NOT IMPLEMENTED  void resetClip();
+  boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
+  boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
+  boolean isPointInStroke(double x, double y);
+  boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y);
+};
+
+[NoInterfaceObject]
+interface CanvasUserInterface {
+  [Pref="canvas.focusring.enabled", Throws] void drawFocusIfNeeded(Element element);
+// NOT IMPLEMENTED  void drawSystemFocusRing(Path path, HTMLElement element);
+  [Pref="canvas.customfocusring.enabled"] boolean drawCustomFocusRing(Element element);
+// NOT IMPLEMENTED  boolean drawCustomFocusRing(Path path, HTMLElement element);
+// NOT IMPLEMENTED  void scrollPathIntoView();
+// NOT IMPLEMENTED  void scrollPathIntoView(Path path);
+};
+
+[NoInterfaceObject]
+interface CanvasText {
+  // text (see also the CanvasPathDrawingStyles interface)
+  [Throws, LenientFloat]
+  void fillText(DOMString text, double x, double y, optional double maxWidth);
+  [Throws, LenientFloat]
+  void strokeText(DOMString text, double x, double y, optional double maxWidth);
+  [NewObject, Throws]
+  TextMetrics measureText(DOMString text);
+};
+
+[NoInterfaceObject]
+interface CanvasDrawImage {
+  [Throws, LenientFloat]
+  void drawImage(CanvasImageSource image, double dx, double dy);
+  [Throws, LenientFloat]
+  void drawImage(CanvasImageSource image, double dx, double dy, double dw, double dh);
+  [Throws, LenientFloat]
+  void drawImage(CanvasImageSource image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh);
+};
+
+[NoInterfaceObject]
+interface CanvasImageData {
+  // pixel manipulation
+  [NewObject, Throws]
+  ImageData createImageData(double sw, double sh);
+  [NewObject, Throws]
+  ImageData createImageData(ImageData imagedata);
+  [NewObject, Throws]
+  ImageData getImageData(double sx, double sy, double sw, double sh);
+  [Throws]
+  void putImageData(ImageData imagedata, double dx, double dy);
+  [Throws]
+  void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
+};
+
+[NoInterfaceObject]
+interface CanvasPathDrawingStyles {
   // line caps/joins
-           [LenientFloat]
-           attribute double lineWidth; // (default 1)
-           attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
-           [GetterThrows]
-           attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
-           [LenientFloat]
-           attribute double miterLimit; // (default 10)
+  [LenientFloat]
+  attribute double lineWidth; // (default 1)
+  attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
+  [GetterThrows]
+  attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
+  [LenientFloat]
+  attribute double miterLimit; // (default 10)
 
   // dashed lines
-    [LenientFloat, Throws] void setLineDash(sequence<double> segments); // default empty
-    sequence<double> getLineDash();
-    [LenientFloat] attribute double lineDashOffset;
+  [LenientFloat, Throws] void setLineDash(sequence<double> segments); // default empty
+  sequence<double> getLineDash();
+  [LenientFloat] attribute double lineDashOffset;
+};
 
+[NoInterfaceObject]
+interface CanvasTextDrawingStyles {
   // text
-           [SetterThrows]
-           attribute DOMString font; // (default 10px sans-serif)
-           attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
-           attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
+  [SetterThrows]
+  attribute DOMString font; // (default 10px sans-serif)
+  attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
+  attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
 };
 
 [NoInterfaceObject]
 interface CanvasPathMethods {
   // shared path API methods
   void closePath();
   [LenientFloat]
   void moveTo(double x, double y);
@@ -280,16 +332,24 @@ interface CanvasPathMethods {
 
   [Throws, LenientFloat]
   void arc(double x, double y, double radius, double startAngle, double endAngle, optional boolean anticlockwise = false); 
 
   [Throws, LenientFloat]
   void ellipse(double x, double y, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, optional boolean anticlockwise = false);
 };
 
+[NoInterfaceObject]
+interface CanvasHitRegions {
+  // hit regions
+  [Pref="canvas.hitregions.enabled", Throws] void addHitRegion(optional HitRegionOptions options);
+  [Pref="canvas.hitregions.enabled"] void removeHitRegion(DOMString id);
+  [Pref="canvas.hitregions.enabled"] void clearHitRegions();
+};
+
 interface CanvasGradient {
   // opaque object
   [Throws]
   // addColorStop should take a double
   void addColorStop(float offset, DOMString color);
 };
 
 interface CanvasPattern {
--- a/dom/webidl/EventHandler.webidl
+++ b/dom/webidl/EventHandler.webidl
@@ -28,16 +28,17 @@ typedef OnErrorEventHandlerNonNull? OnEr
 interface GlobalEventHandlers {
            attribute EventHandler onabort;
            attribute EventHandler onblur;
 // We think the spec is wrong here. See OnErrorEventHandlerForNodes/Window
 // below.
 //         attribute OnErrorEventHandler onerror;
            attribute EventHandler onfocus;
            //(Not implemented)attribute EventHandler oncancel;
+           attribute EventHandler onauxclick;
            attribute EventHandler oncanplay;
            attribute EventHandler oncanplaythrough;
            attribute EventHandler onchange;
            attribute EventHandler onclick;
            //(Not implemented)attribute EventHandler onclose;
            attribute EventHandler oncontextmenu;
            //(Not implemented)attribute EventHandler oncuechange;
            attribute EventHandler ondblclick;
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -158,16 +158,18 @@ dictionary RTCStatsReportInternal {
   sequence<RTCTransportStats>         transportStats;
   sequence<RTCIceComponentStats>      iceComponentStats;
   sequence<RTCIceCandidatePairStats>  iceCandidatePairStats;
   sequence<RTCIceCandidateStats>      iceCandidateStats;
   sequence<RTCCodecStats>             codecStats;
   DOMString                           localSdp;
   DOMString                           remoteSdp;
   DOMHighResTimeStamp                 timestamp;
+  unsigned long                       iceRestarts;
+  unsigned long                       iceRollbacks;
   boolean                             closed; // Is the PC now closed
 };
 
 [Pref="media.peerconnection.enabled",
 // TODO: Use MapClass here once it's available (Bug 928114)
 // MapClass(DOMString, object)
  JSImplementation="@mozilla.org/dom/rtcstatsreport;1"]
 interface RTCStatsReport {
--- a/dom/xml/nsXMLElement.h
+++ b/dom/xml/nsXMLElement.h
@@ -4,17 +4,17 @@
  * 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/. */
 
 #ifndef nsXMLElement_h___
 #define nsXMLElement_h___
 
 #include "mozilla/Attributes.h"
 #include "nsIDOMElement.h"
-#include "mozilla/dom/ElementInlines.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/dom/DOMRect.h"
 
 class nsXMLElement : public mozilla::dom::Element,
                      public nsIDOMElement
 {
 public:
   explicit nsXMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : mozilla::dom::Element(aNodeInfo)
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -1272,17 +1272,17 @@ nsXULElement::List(FILE* out, int32_t aI
 
 bool
 nsXULElement::IsEventStoppedFromAnonymousScrollbar(EventMessage aMessage)
 {
     return (IsRootOfNativeAnonymousSubtree() &&
             IsAnyOfXULElements(nsGkAtoms::scrollbar, nsGkAtoms::scrollcorner) &&
             (aMessage == eMouseClick || aMessage == eMouseDoubleClick ||
              aMessage == eXULCommand || aMessage == eContextMenu ||
-             aMessage == eDragStart));
+             aMessage == eDragStart  || aMessage == eMouseAuxClick));
 }
 
 nsresult
 nsXULElement::DispatchXULCommand(const EventChainVisitor& aVisitor,
                                  nsAutoString& aCommand)
 {
     // XXX sXBL/XBL2 issue! Owner or current document?
     nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetUncomposedDoc()));
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -28,17 +28,17 @@
 #include "nsIXULTemplateBuilder.h"
 #include "nsLayoutCID.h"
 #include "nsAttrAndChildArray.h"
 #include "nsGkAtoms.h"
 #include "nsStyledElement.h"
 #include "nsIFrameLoader.h"
 #include "nsFrameLoader.h"
 #include "mozilla/dom/DOMRect.h"
-#include "mozilla/dom/ElementInlines.h"
+#include "mozilla/dom/Element.h"
 
 class nsIDocument;
 class nsString;
 class nsXULPrototypeDocument;
 
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class nsIOffThreadScriptReceiver;
--- a/editor/libeditor/tests/browser_bug629172.js
+++ b/editor/libeditor/tests/browser_bug629172.js
@@ -28,22 +28,18 @@ add_task(function*() {
       LTRRef.style.display = "";
       document.body.clientWidth;
       window.Screenshots.ltr = window.snapshotWindow(window);
       LTRRef.parentNode.removeChild(LTRRef);
       RTLRef.style.display = "";
       document.body.clientWidth;
       window.Screenshots.rtl = window.snapshotWindow(window);
       RTLRef.parentNode.removeChild(RTLRef);
-      window.Screenshots.get = function(dir, flip) {
-        if (flip) {
-          return this[dir == "rtl" ? "ltr" : "rtl"];
-        } else {
-          return this[dir];
-        }
+      window.Screenshots.get = function(dir) {
+        return this[dir];
       };
     });
 
     function simulateCtrlShiftX(aBrowser) {
       // In e10s, the keypress event will be dispatched to the content process,
       // but in non-e10s it is handled by the browser UI code and hence won't
       // reach the web page.  As a result, we need to observe the event in
       // the content process only in e10s mode.
@@ -63,44 +59,60 @@ add_task(function*() {
         var t = window.t = document.createElement("textarea");
         t.setAttribute("dir", initialDir);
         t.value = "test.";
         window.inputEventCount = 0;
         t.oninput = function() { window.inputEventCount++; };
         document.getElementById("content").appendChild(t);
         document.body.clientWidth;
         var s1 = window.snapshotWindow(window);
-        ok(window.compareSnapshots(s1, window.Screenshots.get(initialDir, false), true)[0],
-           "Textarea should appear correctly before switching the direction (" + initialDir + ")");
+        window.ok = ok; // for assertSnapshots
+        window.
+          assertSnapshots(s1, window.Screenshots.get(initialDir), true,
+                          /* fuzz = */ null,
+                          "Textarea before switching the direction from " +
+                            initialDir,
+                          "Reference " + initialDir + " textarea");
         t.focus();
         is(window.inputEventCount, 0, "input event count must be 0 before");
       });
       yield simulateCtrlShiftX(aBrowser);
       yield ContentTask.spawn(aBrowser, {initialDir}, function({initialDir}) {
         var window = content.window.wrappedJSObject;
-
-        is(window.t.getAttribute("dir"), initialDir == "ltr" ? "rtl" : "ltr", "The dir attribute must be correctly updated");
+        var expectedDir = initialDir == "ltr" ? "rtl" : "ltr"
+        is(window.t.getAttribute("dir"), expectedDir,
+           "The dir attribute must be correctly updated");
         is(window.inputEventCount, 1, "input event count must be 1 after");
         window.t.blur();
         var s2 = window.snapshotWindow(window);
-        ok(window.compareSnapshots(s2, window.Screenshots.get(initialDir, true), true)[0],
-           "Textarea should appear correctly after switching the direction (" + initialDir + ")");
+        window.ok = ok; // for assertSnapshots
+        window.
+          assertSnapshots(s2, window.Screenshots.get(expectedDir), true,
+                        /* fuzz = */ null,
+                          "Textarea after switching the direction from " +
+                            initialDir,
+                          "Reference " + expectedDir + " textarea");
         window.t.focus();
         is(window.inputEventCount, 1, "input event count must be 1 before");
       });
       yield simulateCtrlShiftX(aBrowser);
       yield ContentTask.spawn(aBrowser, {initialDir}, function({initialDir}) {
         var window = content.window.wrappedJSObject;
 
         is(window.inputEventCount, 2, "input event count must be 2 after");
         is(window.t.getAttribute("dir"), initialDir == "ltr" ? "ltr" : "rtl", "The dir attribute must be correctly updated");
         window.t.blur();
         var s3 = window.snapshotWindow(window);
-        ok(window.compareSnapshots(s3, window.Screenshots.get(initialDir, false), true)[0],
-           "Textarea should appear correctly after switching back the direction (" + initialDir + ")");
+        window.ok = ok; // for assertSnapshots
+        window.
+          assertSnapshots(s3, window.Screenshots.get(initialDir), true,
+                          /* fuzz = */ null,
+                          "Textarea after switching back the direction to " +
+                            initialDir,
+                          "Reference " + initialDir + " textarea");
         window.t.parentNode.removeChild(window.t);
       });
     }
 
     yield testDirection("ltr", aBrowser);
     yield testDirection("rtl", aBrowser);
   });
 });
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1140,16 +1140,17 @@ APZCTreeManager::UpdateWheelTransaction(
     return;
    }
    case eKeyPress:
    case eKeyUp:
    case eKeyDown:
    case eMouseUp:
    case eMouseDown:
    case eMouseDoubleClick:
+   case eMouseAuxClick:
    case eMouseClick:
    case eContextMenu:
    case eDrop:
      txn->EndTransaction();
      return;
    default:
      break;
   }
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -765,20 +765,20 @@ ConstructBorderRenderer(nsPresContext* a
                "don't have borders but those shouldn't reach this point. "
                "Overflow containers do reach this point though.");
     border.ApplySkipSides(aSkipSides);
   }
 
   // Convert to dev pixels.
   nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
   Rect joinedBorderAreaPx = NSRectToRect(joinedBorderArea, twipsPerPixel);
-  Float borderWidths[4] = { Float(border.top / twipsPerPixel),
-                                   Float(border.right / twipsPerPixel),
-                                   Float(border.bottom / twipsPerPixel),
-                                   Float(border.left / twipsPerPixel) };
+  Float borderWidths[4] = { Float(border.top) / twipsPerPixel,
+                                   Float(border.right) / twipsPerPixel,
+                                   Float(border.bottom) / twipsPerPixel,
+                                   Float(border.left) / twipsPerPixel };
   Rect dirtyRect = NSRectToRect(aDirtyRect, twipsPerPixel);
 
   uint8_t borderStyles[4];
   nscolor borderColors[4];
   nsBorderColors* compositeColors[4];
 
   // pull out styles, colors, composite colors
   NS_FOR_CSS_SIDES (i) {
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -7270,20 +7270,18 @@ nsDisplayMask::BuildLayer(nsDisplayListB
     return nullptr;
   }
 
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
 
-  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
-  effectProperties.GetClipPathFrame(&isOK);
-
-  if (!isOK) {
+  if (effectProperties.HasInvalidClipPath() ||
+      effectProperties.HasInvalidMask()) {
     return nullptr;
   }
 
   RefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
                            aContainerParameters, nullptr);
 
   return container.forget();
@@ -7433,18 +7431,17 @@ nsDisplayMask::PaintAsLayer(nsDisplayLis
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayMask::PrintEffects(nsACString& aTo)
 {
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
-  bool isOK = true;
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
+  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
   bool first = true;
   aTo += " effects=(";
   if (mFrame->StyleEffects()->mOpacity != 1.0f && mHandleOpacity) {
     first = false;
     aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
   }
   if (clipPathFrame) {
     if (!first) {
@@ -7457,17 +7454,18 @@ nsDisplayMask::PrintEffects(nsACString& 
   if (style->HasClipPath() && !clipPathFrame) {
     if (!first) {
       aTo += ", ";
     }
     aTo += "clip(basic-shape)";
     first = false;
   }
 
-  if (effectProperties.GetFirstMaskFrame()) {
+  nsTArray<nsSVGMaskFrame*> masks = effectProperties.GetMaskFrames();
+  if (!masks.IsEmpty() && masks[0]) {
     if (!first) {
       aTo += ", ";
     }
     aTo += "mask";
   }
   aTo += ")";
 }
 #endif
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -153,17 +153,17 @@ nsSVGClipPathFrame::PaintClipMask(gfxCon
   // Paint this clipPath's contents into aMaskDT:
   // We need to set mMatrixForChildren here so that under the PaintSVG calls
   // on our children (below) our GetCanvasTM() method will return the correct
   // transform.
   mMatrixForChildren = GetClipPathTransform(aClippedFrame) * aMatrix;
 
   // Check if this clipPath is itself clipped by another clipPath:
   nsSVGClipPathFrame* clipPathThatClipsClipPath =
-    nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nullptr);
+    nsSVGEffects::GetEffectProperties(this).GetClipPathFrame();
   nsSVGUtils::MaskUsage maskUsage;
   nsSVGUtils::DetermineMaskUsage(this, true, maskUsage);
 
   if (maskUsage.shouldApplyClipPath) {
     clipPathThatClipsClipPath->ApplyClipPath(aMaskContext, aClippedFrame,
                                              aMatrix);
   } else if (maskUsage.shouldGenerateClipMaskLayer) {
     Matrix maskTransform;
@@ -210,23 +210,24 @@ nsSVGClipPathFrame::PaintFrameIntoMask(n
   nsISVGChildFrame* frame = do_QueryFrame(aFrame);
   if (!frame) {
     return DrawResult::SUCCESS;
   }
 
   // The CTM of each frame referencing us can be different.
   frame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
 
-  bool isOK = true;
   // Children of this clipPath may themselves be clipped.
-  nsSVGClipPathFrame *clipPathThatClipsChild =
-    nsSVGEffects::GetEffectProperties(aFrame).GetClipPathFrame(&isOK);
-  if (!isOK) {
+  nsSVGEffects::EffectProperties effectProperties =
+    nsSVGEffects::GetEffectProperties(aFrame);
+  if (effectProperties.HasInvalidClipPath()) {
     return DrawResult::SUCCESS;
   }
+  nsSVGClipPathFrame *clipPathThatClipsChild =
+    effectProperties.GetClipPathFrame();
 
   nsSVGUtils::MaskUsage maskUsage;
   nsSVGUtils::DetermineMaskUsage(aFrame, true, maskUsage);
   DrawResult result = DrawResult::SUCCESS;
   if (maskUsage.shouldApplyClipPath) {
     clipPathThatClipsChild->ApplyClipPath(aTarget, aClippedFrame, aMatrix);
   } else if (maskUsage.shouldGenerateClipMaskLayer) {
     Matrix maskTransform;
@@ -323,17 +324,17 @@ nsSVGClipPathFrame::PointIsInsideClipPat
   gfxPoint point = matrix.Transform(aPoint);
 
   // clipPath elements can themselves be clipped by a different clip path. In
   // that case the other clip path further clips away the element that is being
   // clipped by the original clipPath. If this clipPath is being clipped by a
   // different clip path we need to check if it prevents the original element
   // from recieving events at aPoint:
   nsSVGClipPathFrame *clipPathFrame =
-    nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nullptr);
+    nsSVGEffects::GetEffectProperties(this).GetClipPathFrame();
   if (clipPathFrame &&
       !clipPathFrame->PointIsInsideClipPath(aClippedFrame, aPoint)) {
     return false;
   }
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
     nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
@@ -355,17 +356,17 @@ nsSVGClipPathFrame::PointIsInsideClipPat
 
   return false;
 }
 
 bool
 nsSVGClipPathFrame::IsTrivial(nsISVGChildFrame **aSingleChild)
 {
   // If the clip path is clipped then it's non-trivial
-  if (nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nullptr))
+  if (nsSVGEffects::GetEffectProperties(this).GetClipPathFrame())
     return false;
 
   if (aSingleChild) {
     *aSingleChild = nullptr;
   }
 
   nsISVGChildFrame *foundChild = nullptr;
 
@@ -374,17 +375,17 @@ nsSVGClipPathFrame::IsTrivial(nsISVGChil
     nsISVGChildFrame *svgChild = do_QueryFrame(kid);
     if (svgChild) {
       // We consider a non-trivial clipPath to be one containing
       // either more than one svg child and/or a svg container
       if (foundChild || svgChild->IsDisplayContainer())
         return false;
 
       // or where the child is itself clipped
-      if (nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame(nullptr))
+      if (nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame())
         return false;
 
       foundChild = svgChild;
     }
   }
   if (aSingleChild) {
     *aSingleChild = foundChild;
   }
@@ -406,19 +407,17 @@ nsSVGClipPathFrame::IsValid()
 
   // And to prevent reference loops we check that this clipPath only appears
   // once in the reference chain (if any) that we're currently processing:
   AutoReferenceLimiter refLoopDetector(&mReferencing, 1);
   if (!refLoopDetector.Reference()) {
     return false; // Reference loop!
   }
 
-  bool isOK = true;
-  nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(&isOK);
-  if (!isOK) {
+  if (nsSVGEffects::GetEffectProperties(this).HasInvalidClipPath()) {
     return false;
   }
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
 
     nsIAtom* kidType = kid->GetType();
 
@@ -497,48 +496,51 @@ nsSVGClipPathFrame::GetClipPathTransform
 
   nsSVGEnum* clipPathUnits =
     &content->mEnumAttributes[SVGClipPathElement::CLIPPATHUNITS];
 
   return nsSVGUtils::AdjustMatrixForUnits(tm, clipPathUnits, aClippedFrame);
 }
 
 SVGBBox
-nsSVGClipPathFrame::GetBBoxForClipPathFrame(const SVGBBox &aBBox, 
+nsSVGClipPathFrame::GetBBoxForClipPathFrame(const SVGBBox &aBBox,
                                             const gfxMatrix &aMatrix)
 {
   nsIContent* node = GetContent()->GetFirstChild();
   SVGBBox unionBBox, tmpBBox;
   for (; node; node = node->GetNextSibling()) {
-    nsIFrame *frame = 
+    nsIFrame *frame =
       static_cast<nsSVGElement*>(node)->GetPrimaryFrame();
     if (frame) {
       nsISVGChildFrame *svg = do_QueryFrame(frame);
       if (svg) {
-        tmpBBox = svg->GetBBoxContribution(mozilla::gfx::ToMatrix(aMatrix), 
-                                         nsSVGUtils::eBBoxIncludeFill);
+        tmpBBox = svg->GetBBoxContribution(mozilla::gfx::ToMatrix(aMatrix),
+                                           nsSVGUtils::eBBoxIncludeFill);
         nsSVGEffects::EffectProperties effectProperties =
                               nsSVGEffects::GetEffectProperties(frame);
-        bool isOK = true;
-        nsSVGClipPathFrame *clipPathFrame = 
-                              effectProperties.GetClipPathFrame(&isOK);
-        if (clipPathFrame && isOK) {
-          tmpBBox = clipPathFrame->GetBBoxForClipPathFrame(tmpBBox, aMatrix);
-        } 
+        if (effectProperties.HasNoOrValidClipPath()) {
+          nsSVGClipPathFrame *clipPathFrame =
+            effectProperties.GetClipPathFrame();
+          if (clipPathFrame) {
+            tmpBBox = clipPathFrame->GetBBoxForClipPathFrame(tmpBBox, aMatrix);
+          }
+        }
         tmpBBox.Intersect(aBBox);
         unionBBox.UnionEdges(tmpBBox);
       }
     }
   }
-  nsSVGEffects::EffectProperties props = 
-    nsSVGEffects::GetEffectProperties(this);    
+
+  nsSVGEffects::EffectProperties props =
+    nsSVGEffects::GetEffectProperties(this);
   if (props.mClipPath) {
-    bool isOK = true;
-    nsSVGClipPathFrame *clipPathFrame = props.GetClipPathFrame(&isOK);
-    if (clipPathFrame && isOK) {
-      tmpBBox = clipPathFrame->GetBBoxForClipPathFrame(aBBox, aMatrix);                                                       
-      unionBBox.Intersect(tmpBBox);
-    } else if (!isOK) {
+    if (props.HasInvalidClipPath()) {
       unionBBox = SVGBBox();
+    } else  {
+      nsSVGClipPathFrame *clipPathFrame = props.GetClipPathFrame();
+      if (clipPathFrame) {
+        tmpBBox = clipPathFrame->GetBBoxForClipPathFrame(aBBox, aMatrix);
+        unionBBox.Intersect(tmpBBox);
+      }
     }
   }
   return unionBBox;
 }
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -630,65 +630,55 @@ nsSVGEffects::GetPaintServer(nsIFrame* a
       type != nsGkAtoms::svgRadialGradientFrame &&
       type != nsGkAtoms::svgPatternFrame)
     return nullptr;
 
   return static_cast<nsSVGPaintServerFrame*>(result);
 }
 
 nsSVGClipPathFrame *
-nsSVGEffects::EffectProperties::GetClipPathFrame(bool* aOK)
+nsSVGEffects::EffectProperties::GetClipPathFrame()
 {
   if (!mClipPath)
     return nullptr;
-  nsSVGClipPathFrame *frame = static_cast<nsSVGClipPathFrame *>
-    (mClipPath->GetReferencedFrame(nsGkAtoms::svgClipPathFrame, aOK));
-  if (frame && aOK && *aOK) {
-    *aOK = frame->IsValid();
-  }
-  return frame;
-}
 
-nsSVGMaskFrame *
-nsSVGEffects::EffectProperties::GetFirstMaskFrame(bool* aOK)
-{
-  if (!mMask) {
-    return nullptr;
-  }
+  nsSVGClipPathFrame *frame = static_cast<nsSVGClipPathFrame *>
+    (mClipPath->GetReferencedFrame(nsGkAtoms::svgClipPathFrame, nullptr));
 
-  const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
-
-  if (props.IsEmpty()) {
-    return nullptr;
-  }
-
-  return static_cast<nsSVGMaskFrame *>
-    (props[0]->GetReferencedFrame(nsGkAtoms::svgMaskFrame, aOK));
+  return frame;
 }
 
 nsTArray<nsSVGMaskFrame *>
 nsSVGEffects::EffectProperties::GetMaskFrames()
 {
   nsTArray<nsSVGMaskFrame *> result;
   if (!mMask)
     return result;
 
-  bool ok = false;
+  bool ok = true;
   const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
   for (size_t i = 0; i < props.Length(); i++) {
     nsSVGMaskFrame* maskFrame =
       static_cast<nsSVGMaskFrame *>(props[i]->GetReferencedFrame(
                                                 nsGkAtoms::svgMaskFrame, &ok));
+    MOZ_ASSERT_IF(maskFrame, ok);
     result.AppendElement(maskFrame);
   }
 
   return result;
 }
 
 bool
+nsSVGEffects::EffectProperties::HasNoOrValidEffects()
+{
+  return HasNoOrValidClipPath() && HasNoOrValidMask() &&
+         HasNoFilterOrHasValidFilter();
+}
+
+bool
 nsSVGEffects::EffectProperties::MightHaveNoneSVGMask() const
 {
   if (!mMask) {
     return false;
   }
 
   const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
   for (size_t i = 0; i < props.Length(); i++) {
@@ -696,16 +686,48 @@ nsSVGEffects::EffectProperties::MightHav
         !props[i]->GetReferencedFrame(nsGkAtoms::svgMaskFrame, nullptr)) {
       return true;
     }
   }
 
   return false;
 }
 
+bool
+nsSVGEffects::EffectProperties::HasNoOrValidClipPath()
+{
+  if (mClipPath) {
+    bool ok = true;
+    nsSVGClipPathFrame *frame = static_cast<nsSVGClipPathFrame *>
+      (mClipPath->GetReferencedFrame(nsGkAtoms::svgClipPathFrame, &ok));
+    if (!ok || (frame && !frame->IsValid())) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool
+nsSVGEffects::EffectProperties::HasNoOrValidMask()
+{
+  if (mMask) {
+    bool ok = true;
+    const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
+    for (size_t i = 0; i < props.Length(); i++) {
+      props[i]->GetReferencedFrame(nsGkAtoms::svgMaskFrame, &ok);
+      if (!ok) {
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
 void
 nsSVGEffects::UpdateEffects(nsIFrame* aFrame)
 {
   NS_ASSERTION(aFrame->GetContent()->IsElement(),
                "aFrame's content should be an element");
 
   FrameProperties props = aFrame->Properties();
   props.Delete(FilterProperty());
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -470,35 +470,65 @@ public:
 
   struct EffectProperties {
     nsSVGFilterProperty*   mFilter;
     nsSVGMaskProperty*     mMask;
     nsSVGPaintingProperty* mClipPath;
 
     /**
      * @return the clip-path frame, or null if there is no clip-path frame
-     * @param aOK if a clip-path was specified and the designated element
-     * exists but is an element of the wrong type, *aOK is set to false.
-     * Otherwise *aOK is untouched.
      */
-    nsSVGClipPathFrame *GetClipPathFrame(bool* aOK);
-    /**
-     * @return the first mask frame, or null if there is no mask frame
-     * @param aOK if a mask was specified and the designated element
-     * exists but is an element of the wrong type, *aOK is set to false.
-     * Otherwise *aOK is untouched.
-     */
-    nsSVGMaskFrame *GetFirstMaskFrame(bool* aOK = nullptr);
+    nsSVGClipPathFrame* GetClipPathFrame();
 
     /**
      * @return an array which contains all SVG mask frames.
      */
     nsTArray<nsSVGMaskFrame*> GetMaskFrames();
 
     bool MightHaveNoneSVGMask() const;
+
+    /*
+     * @return true if all effects we have are valid or we have no effect
+     * at all.
+     */
+    bool HasNoOrValidEffects();
+
+    /*
+     * @return true if we have any invalid effect.
+     */
+    bool HasInvalidEffects() {
+      return !HasNoOrValidEffects();
+    }
+
+    /*
+     * @return true if we either do not have clip-path or have a valid
+     * clip-path.
+     */
+    bool HasNoOrValidClipPath();
+
+    /*
+     * @return true if we have an invalid clip-path.
+     */
+    bool HasInvalidClipPath() {
+      return !HasNoOrValidClipPath();
+    }
+
+    /*
+     * @return true if we either do not have mask or all masks we have
+     * are valid.
+     */
+    bool HasNoOrValidMask();
+
+    /*
+     * @return true if we have an invalid mask.
+     */
+    bool HasInvalidMask() {
+      return !HasNoOrValidMask();
+    }
+
     bool HasValidFilter() {
       return mFilter && mFilter->ReferencesValidResources();
     }
 
     bool HasNoFilterOrHasValidFilter() {
       return !mFilter || mFilter->ReferencesValidResources();
     }
   };
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -801,19 +801,17 @@ nsSVGIntegrationUtils::PaintMask(const P
     matSR.Restore();
     matSR.SetContext(&ctx);
 
     SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
                        offsetToUserSpace, false);
     Matrix clipMaskTransform;
     gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(frame);
 
-    bool isOK = true;
-    nsSVGClipPathFrame *clipPathFrame =
-      effectProperties.GetClipPathFrame(&isOK);
+    nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
     RefPtr<SourceSurface> maskSurface =
       maskUsage.shouldGenerateMaskLayer ? target->Snapshot() : nullptr;
     result =
       clipPathFrame->PaintClipMask(ctx, frame, cssPxToDevPxMatrix,
                                    &clipMaskTransform, maskSurface,
                                    ToMatrix(ctx.CurrentMatrix()));
   }
 
@@ -859,18 +857,17 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(frame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
 
-  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
+  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
 
   gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(frame);
   nsTArray<nsSVGMaskFrame*> maskFrames = effectProperties.GetMaskFrames();
 
   nsPoint offsetToBoundingBox;
   nsPoint offsetToUserSpace;
 
   bool shouldGenerateMask = (maskUsage.opacity != 1.0f ||
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -519,18 +519,17 @@ nsSVGUtils::DetermineMaskUsage(nsIFrame*
 #else
   // Since we do not support image mask so far, we should treat any
   // unresolvable mask as no mask. Otherwise, any object with a valid image
   // mask, e.g. url("xxx.png"), will become invisible just because we can not
   // handle image mask correctly. (See bug 1294171)
   aUsage.shouldGenerateMaskLayer = maskFrames.Length() == 1 && maskFrames[0];
 #endif
 
-  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
+  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
   MOZ_ASSERT_IF(clipPathFrame,
                 svgReset->mClipPath.GetType() == StyleShapeSourceType::URL);
 
   switch (svgReset->mClipPath.GetType()) {
     case StyleShapeSourceType::URL:
       if (clipPathFrame) {
         if (clipPathFrame->IsTrivial()) {
           aUsage.shouldApplyClipPath = true;
@@ -735,24 +734,25 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
    *f
    * + Merge opacity and masking if both used together.
    */
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(aFrame);
-  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
-  nsSVGMaskFrame *maskFrame = effectProperties.GetFirstMaskFrame(&isOK);
-  if (!isOK) {
+  if (effectProperties.HasInvalidEffects()) {
     // Some resource is invalid. We shouldn't paint anything.
     return DrawResult::SUCCESS;
   }
 
+  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
+  nsTArray<nsSVGMaskFrame*> masks = effectProperties.GetMaskFrames();
+  nsSVGMaskFrame *maskFrame = masks.IsEmpty() ? nullptr : masks[0];
+
   MixModeBlender blender(aFrame, &aContext);
   gfxContext* target = blender.ShouldCreateDrawTargetForBlend()
                        ? blender.CreateBlendTarget(aTransform) : &aContext;
 
   if (!target) {
     return DrawResult::TEMPORARY_ERROR;
   }
 
@@ -874,23 +874,23 @@ nsSVGUtils::HitTestClip(nsIFrame *aFrame
   if (!props.mClipPath) {
     const nsStyleSVGReset *style = aFrame->StyleSVGReset();
     if (style->HasClipPath()) {
       return nsCSSClipPathInstance::HitTestBasicShapeClip(aFrame, aPoint);
     }
     return true;
   }
 
-  bool isOK = true;
-  nsSVGClipPathFrame *clipPathFrame = props.GetClipPathFrame(&isOK);
-  if (!isOK) {
+  if (props.HasInvalidClipPath()) {
     // clipPath is not a valid resource, so nothing gets painted, so
     // hit-testing must fail.
     return false;
   }
+  nsSVGClipPathFrame *clipPathFrame = props.GetClipPathFrame();
+
   if (!clipPathFrame) {
     // clipPath doesn't exist, ignore it.
     return true;
   }
 
   return clipPathFrame->PointIsInsideClipPath(aFrame, aPoint);
 }
 
@@ -1122,64 +1122,61 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, ui
       matrix = element->PrependLocalTransformsTo(matrix, eChildToUserSpace);
     }
     bbox = svg->GetBBoxContribution(ToMatrix(matrix), aFlags).ToThebesRect();
     // Account for 'clipped'.
     if (aFlags & nsSVGUtils::eBBoxIncludeClipped) {
       gfxRect clipRect(0, 0, 0, 0);
       float x, y, width, height;
       gfxMatrix tm;
-      gfxRect fillBBox = 
-        svg->GetBBoxContribution(ToMatrix(tm), 
+      gfxRect fillBBox =
+        svg->GetBBoxContribution(ToMatrix(tm),
                                  nsSVGUtils::eBBoxIncludeFill).ToThebesRect();
       x = fillBBox.x;
       y = fillBBox.y;
       width = fillBBox.width;
       height = fillBBox.height;
       bool hasClip = aFrame->StyleDisplay()->IsScrollableOverflow();
       if (hasClip) {
-        clipRect = 
+        clipRect =
           nsSVGUtils::GetClipRectForFrame(aFrame, x, y, width, height);
           if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame ||
               aFrame->GetType() == nsGkAtoms::svgUseFrame) {
             clipRect = matrix.TransformBounds(clipRect);
           }
       }
       nsSVGEffects::EffectProperties effectProperties =
         nsSVGEffects::GetEffectProperties(aFrame);
-      bool isOK = true;
-      nsSVGClipPathFrame *clipPathFrame = 
-        effectProperties.GetClipPathFrame(&isOK);
-      if (clipPathFrame && isOK) {
-        SVGClipPathElement *clipContent = 
-          static_cast<SVGClipPathElement*>(clipPathFrame->GetContent());
-        RefPtr<SVGAnimatedEnumeration> units = clipContent->ClipPathUnits();
-        if (units->AnimVal() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-          matrix.Translate(gfxPoint(x, y));
-          matrix.Scale(width, height);
-        } else if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame) {
-          matrix.Reset();
+      if (effectProperties.HasInvalidClipPath()) {
+        bbox = gfxRect(0, 0, 0, 0);
+      } else {
+        nsSVGClipPathFrame *clipPathFrame =
+          effectProperties.GetClipPathFrame();
+        if (clipPathFrame) {
+          SVGClipPathElement *clipContent =
+            static_cast<SVGClipPathElement*>(clipPathFrame->GetContent());
+          RefPtr<SVGAnimatedEnumeration> units = clipContent->ClipPathUnits();
+          if (units->AnimVal() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+            matrix.Translate(gfxPoint(x, y));
+            matrix.Scale(width, height);
+          } else if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame) {
+            matrix.Reset();
+          }
+          bbox =
+            clipPathFrame->GetBBoxForClipPathFrame(bbox, matrix).ToThebesRect();
         }
-        bbox = 
-          clipPathFrame->GetBBoxForClipPathFrame(bbox, matrix).ToThebesRect();
+
         if (hasClip) {
           bbox = bbox.Intersect(clipRect);
         }
-      } else {
-        if (!isOK) {
+
+        if (bbox.IsEmpty()) {
           bbox = gfxRect(0, 0, 0, 0);
-        } else {
-          if (hasClip) {
-            bbox = bbox.Intersect(clipRect);
-          }
         }
       }
-      if (bbox.IsEmpty()) {
-        bbox = gfxRect(0, 0, 0, 0);
-      }
     }
 
     if (aFlags == eBBoxIncludeFillGeometry) {
       // Obtaining the bbox for objectBoundingBox calculations is common so we
       // cache the result for future calls, since calculation can be expensive:
       props.Set(ObjectBoundingBoxProperty(), new gfxRect(bbox));
     }
 
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -331,16 +331,18 @@ PeerConnectionImpl::PeerConnectionImpl(c
   , mIdentity(nullptr)
 #endif
   , mPrivacyRequested(false)
   , mSTSThread(nullptr)
   , mAllowIceLoopback(false)
   , mAllowIceLinkLocal(false)
   , mMedia(nullptr)
   , mUuidGen(MakeUnique<PCUuidGenerator>())
+  , mIceRestartCount(0)
+  , mIceRollbackCount(0)
   , mNumAudioStreams(0)
   , mNumVideoStreams(0)
   , mHaveConfiguredCodecs(false)
   , mHaveDataStream(false)
   , mAddCandidateErrorCount(0)
   , mTrickle(true) // TODO(ekr@rtfm.com): Use pref
   , mNegotiationNeeded(false)
   , mPrivateWindow(false)
@@ -1732,27 +1734,29 @@ PeerConnectionImpl::RollbackIceRestart()
   if (NS_FAILED(nrv)) {
     CSFLogError(logTag, "%s: Couldn't set ICE credentials, res=%u",
                          __FUNCTION__,
                          static_cast<unsigned>(nrv));
     return nrv;
   }
   mPreviousIceUfrag = "";
   mPreviousIcePwd = "";
+  ++mIceRollbackCount;
 
   return NS_OK;
 }
 
 void
 PeerConnectionImpl::FinalizeIceRestart()
 {
   mMedia->FinalizeIceRestart();
   // clear the previous ice creds since they are no longer needed
   mPreviousIceUfrag = "";
   mPreviousIcePwd = "";
+  ++mIceRestartCount;
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
 {
   PC_AUTO_ENTER_API_CALL(true);
 
   if (!aSDP) {
@@ -3603,16 +3607,18 @@ PeerConnectionImpl::BuildStatsQuery_m(
 
   // We do not use the pcHandle here, since that's risky to expose to content.
   query->report = new RTCStatsReportInternalConstruct(
       NS_ConvertASCIItoUTF16(mName.c_str()),
       query->now);
 
   query->iceStartTime = mIceStartTime;
   query->failed = isFailed(mIceConnectionState);
+  query->report->mIceRestarts.Construct(mIceRestartCount);
+  query->report->mIceRollbacks.Construct(mIceRollbackCount);
 
   // Populate SDP on main
   if (query->internalStats) {
     if (mJsepSession) {
       std::string localDescription = mJsepSession->GetLocalDescription();
       std::string remoteDescription = mJsepSession->GetRemoteDescription();
       query->report->mLocalSdp.Construct(
           NS_ConvertASCIItoUTF16(localDescription.c_str()));
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -813,16 +813,18 @@ private:
   bool mAllowIceLinkLocal;
   RefPtr<PeerConnectionMedia> mMedia;
 
   // The JSEP negotiation session.
   mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
   mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
   std::string mPreviousIceUfrag; // used during rollback of ice restart
   std::string mPreviousIcePwd; // used during rollback of ice restart
+  unsigned long mIceRestartCount;
+  unsigned long mIceRollbackCount;
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // Start time of ICE, used for telemetry
   mozilla::TimeStamp mIceStartTime;
   // Start time of call used for Telemetry
   mozilla::TimeStamp mStartTime;
 #endif
 
--- a/mobile/android/base/java/org/mozilla/gecko/overlays/ui/ShareDialog.java
+++ b/mobile/android/base/java/org/mozilla/gecko/overlays/ui/ShareDialog.java
@@ -8,16 +8,17 @@ package org.mozilla.gecko.overlays.ui;
 import java.net.URISyntaxException;
 
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.Locales;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
+import org.mozilla.gecko.db.BrowserContract;
 import org.mozilla.gecko.db.LocalBrowserDB;
 import org.mozilla.gecko.db.RemoteClient;
 import org.mozilla.gecko.overlays.OverlayConstants;
 import org.mozilla.gecko.overlays.service.OverlayActionService;
 import org.mozilla.gecko.overlays.service.sharemethods.SendTab;
 import org.mozilla.gecko.overlays.service.sharemethods.ShareMethod;
 import org.mozilla.gecko.sync.setup.activities.WebURLFinder;
 import org.mozilla.gecko.util.IntentUtils;
@@ -61,16 +62,17 @@ public class ShareDialog extends Locales
 
     /** The maximum number of devices we'll show in the dialog when in State.DEFAULT. **/
     private static final int MAXIMUM_INLINE_DEVICES = 2;
 
     private State state;
 
     private SendTabList sendTabList;
     private OverlayDialogButton bookmarkButton;
+    private OverlayDialogButton openBrowserButton;
 
     // The bookmark button drawable set from XML - we need this to reset state.
     private Drawable bookmarkButtonDrawable;
 
     private String url;
     private String title;
 
     // The override intent specified by SendTab (if any). See SendTab.java.
@@ -174,28 +176,32 @@ public class ShareDialog extends Locales
         // Send tab.
         sendTabList = (SendTabList) findViewById(R.id.overlay_send_tab_btn);
 
         // Register ourselves as both the listener and the context for the Adapter.
         final SendTabDeviceListArrayAdapter adapter = new SendTabDeviceListArrayAdapter(this, this);
         sendTabList.setAdapter(adapter);
         sendTabList.setSendTabTargetSelectedListener(this);
 
-        bookmarkButton = (OverlayDialogButton) findViewById(R.id.overlay_share_bookmark_btn);
-
-        bookmarkButtonDrawable = bookmarkButton.getBackground();
-
         // Bookmark button
         bookmarkButton = (OverlayDialogButton) findViewById(R.id.overlay_share_bookmark_btn);
         bookmarkButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
                 addBookmark();
             }
         });
+        bookmarkButtonDrawable = bookmarkButton.getBackground();
+        openBrowserButton = (OverlayDialogButton) findViewById(R.id.overlay_share_open_browser_btn);
+        openBrowserButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                launchBrowser();
+            }
+        });
     }
 
     @Override
     protected void onResume() {
         super.onResume();
 
         final Intent intent = getIntent();
 
@@ -256,33 +262,22 @@ public class ShareDialog extends Locales
         subtitleView.setMarqueeRepeatLimit(5);
         subtitleView.setSelected(true);
 
         final View titleView = findViewById(R.id.title);
 
         if (state == State.DEVICES_ONLY) {
             bookmarkButton.setVisibility(View.GONE);
 
-            titleView.setOnClickListener(null);
-            subtitleView.setOnClickListener(null);
+            openBrowserButton.setVisibility(View.GONE);
             return;
         }
 
         bookmarkButton.setVisibility(View.VISIBLE);
-
-        // Configure buttons.
-        final View.OnClickListener launchBrowser = new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                ShareDialog.this.launchBrowser();
-            }
-        };
-
-        titleView.setOnClickListener(launchBrowser);
-        subtitleView.setOnClickListener(launchBrowser);
+        openBrowserButton.setVisibility(View.VISIBLE);
 
         final LocalBrowserDB browserDB = new LocalBrowserDB(getCurrentProfile());
         setButtonState(url, browserDB);
     }
 
     @Override
     protected void onNewIntent(final Intent intent) {
         super.onNewIntent(intent);
@@ -389,17 +384,19 @@ public class ShareDialog extends Locales
 
         Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, TelemetryContract.Method.SHARE_OVERLAY, "bookmark");
     }
 
     public void launchBrowser() {
         try {
             // This can launch in the guest profile. Sorry.
             final Intent i = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
+            i.putExtra(BrowserContract.SKIP_TAB_QUEUE_FLAG, true);
             i.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
+
             startActivity(i);
         } catch (URISyntaxException e) {
             // Nothing much we can do.
         } finally {
             // Since we're changing apps, users expect the default app switch animations.
             finish(false);
         }
     }
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -151,16 +151,17 @@
 
 <!-- Localization note (overlay_share_bookmark_btn_label) : This string is
      used in the share overlay menu to select an action. It is the verb
      "to bookmark", not the noun "a bookmark". -->
 <!ENTITY overlay_share_bookmark_btn_label "Bookmark">
 <!ENTITY overlay_share_bookmark_btn_label_already "Already bookmarked">
 <!ENTITY overlay_share_send_other "Send to other devices">
 
+<!ENTITY overlay_share_open_browser_btn_label "Open in &brandShortName;">
 <!-- Localization note (overlay_share_send_tab_btn_label) : Used on the
      share overlay menu to represent the "Send Tab" action when the user
      either has not set up Sync, or has no other devices to send a tab
      to. -->
 <!ENTITY overlay_share_send_tab_btn_label "Send to another device">
 <!ENTITY overlay_share_no_url "No link found in this share">
 <!ENTITY overlay_share_select_device "Select device">
 <!-- Localization note (overlay_no_synced_devices) : Used when the menu option
--- a/mobile/android/base/resources/layout/overlay_share_button.xml
+++ b/mobile/android/base/resources/layout/overlay_share_button.xml
@@ -1,24 +1,27 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
 
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <ImageView
-        android:layout_width="60dp"
-        android:layout_height="match_parent"
-        android:id="@+id/overlaybtn_icon"
-        android:padding="30dp"
-        android:scaleType="center"/>
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:gecko="http://schemas.android.com/apk/res-auto">
+    <org.mozilla.gecko.widget.themed.ThemedImageView
+            android:id="@+id/overlaybtn_icon"
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            android:layout_margin="15dp"
+            gecko:drawableTintList="@color/action_bar_secondary_menu_item_colors"
+            android:scaleType="centerInside"/>
 
     <TextView
-        android:textAppearance="@style/TextAppearance.ShareOverlay"
-        android:id="@+id/overlaybtn_label"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:clickable="false"
-        android:enabled="false"
-        android:maxLines="1"
-        android:textSize="14sp"
-        android:textColor="@color/primary_text_selector"/>
+            android:textAppearance="@style/TextAppearance.ShareOverlay"
+            android:id="@+id/overlaybtn_label"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:clickable="false"
+            android:enabled="false"
+            android:maxLines="1"
+            android:textSize="14sp"
+            android:textColor="@color/primary_text_selector"/>
 </merge>
--- a/mobile/android/base/resources/layout/overlay_share_dialog.xml
+++ b/mobile/android/base/resources/layout/overlay_share_dialog.xml
@@ -58,16 +58,26 @@
             android:id="@+id/overlay_share_bookmark_btn"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:enabled="false"
             gecko:drawable="@drawable/overlay_share_bookmark_button"
             gecko:enabledText="@string/overlay_share_bookmark_btn_label"
             gecko:disabledText="@string/overlay_share_bookmark_btn_label_already"/>
 
+        <!-- "Open in Browser" -->
+        <org.mozilla.gecko.overlays.ui.OverlayDialogButton
+                style="@style/ShareOverlayRow"
+                android:id="@+id/overlay_share_open_browser_btn"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:enabled="false"
+                gecko:drawable="@drawable/icon_search_empty_firefox"
+                gecko:enabledText="@string/overlay_share_open_browser_btn_label"/>
+
     </LinearLayout>
 
     <ImageView
         android:id="@+id/check"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:layout_gravity="center"
         android:src="@drawable/overlay_check"
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -126,16 +126,17 @@
   <string name="find_next">&find_next;</string>
   <string name="find_close">&find_close;</string>
 
   <string name="media_sending_to">&media_sending_to;</string>
   <string name="media_play">&media_play;</string>
   <string name="media_pause">&media_pause;</string>
   <string name="media_stop">&media_stop;</string>
 
+  <string name="overlay_share_open_browser_btn_label">&overlay_share_open_browser_btn_label;</string>
   <string name="overlay_share_send_other">&overlay_share_send_other;</string>
   <string name="overlay_share_label">&overlay_share_label;</string>
   <string name="overlay_share_bookmark_btn_label">&overlay_share_bookmark_btn_label;</string>
   <string name="overlay_share_bookmark_btn_label_already">&overlay_share_bookmark_btn_label_already;</string>
   <string name="overlay_share_send_tab_btn_label">&overlay_share_send_tab_btn_label;</string>
   <string name="overlay_share_no_url">&overlay_share_no_url;</string>
   <string name="overlay_share_select_device">&overlay_share_select_device;</string>
   <string name="overlay_no_synced_devices">&overlay_no_synced_devices;</string>
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3893,17 +3893,19 @@ Tab.prototype = {
             this.browser.removeEventListener("click", ErrorPageEventHandler, true);
             this.browser.removeEventListener("pagehide", listener, true);
           }.bind(this);
 
           this.browser.addEventListener("pagehide", listener, true);
         }
 
         if (AppConstants.NIGHTLY_BUILD || AppConstants.MOZ_ANDROID_ACTIVITY_STREAM) {
-          WebsiteMetadata.parseAsynchronously(this.browser.contentDocument);
+          if (!docURI.startsWith("about:")) {
+            WebsiteMetadata.parseAsynchronously(this.browser.contentDocument);
+          }
         }
 
         break;
       }
 
       case "DOMFormHasPassword": {
         LoginManagerContent.onDOMFormHasPassword(aEvent,
                                                  this.browser.contentWindow);
--- a/python/mozbuild/mozbuild/artifacts.py
+++ b/python/mozbuild/mozbuild/artifacts.py
@@ -447,17 +447,17 @@ JOB_DETAILS = {
     'linux-debug': (LinuxArtifactJob, ('public/build/firefox-(.*)\.linux-i686\.tar\.bz2',
                                  'public/build/firefox-(.*)\.common\.tests\.zip')),
     'linux64-opt': (LinuxArtifactJob, ('public/build/firefox-(.*)\.linux-x86_64\.tar\.bz2',
                                        'public/build/firefox-(.*)\.common\.tests\.zip')),
     'linux64-debug': (LinuxArtifactJob, ('public/build/target\.tar\.bz2',
                                          'public/build/target\.common\.tests\.zip')),
     'macosx64-opt': (MacArtifactJob, ('public/build/firefox-(.*)\.mac\.dmg',
                                       'public/build/firefox-(.*)\.common\.tests\.zip')),
-    'macosx64-debug': (MacArtifactJob, ('public/build/firefox-(.*)\.mac64\.dmg',
+    'macosx64-debug': (MacArtifactJob, ('public/build/firefox-(.*)\.mac\.dmg',
                                   'public/build/firefox-(.*)\.common\.tests\.zip')),
     'win32-opt': (WinArtifactJob, ('public/build/firefox-(.*)\.win32.zip',
                                    'public/build/firefox-(.*)\.common\.tests\.zip')),
     'win32-debug': (WinArtifactJob, ('public/build/firefox-(.*)\.win32.zip',
                                'public/build/firefox-(.*)\.common\.tests\.zip')),
     'win64-opt': (WinArtifactJob, ('public/build/firefox-(.*)\.win64.zip',
                                    'public/build/firefox-(.*)\.common\.tests\.zip')),
     'win64-debug': (WinArtifactJob, ('public/build/firefox-(.*)\.win64.zip',
--- a/security/manager/pki/resources/content/clientauthask.js
+++ b/security/manager/pki/resources/content/clientauthask.js
@@ -94,16 +94,19 @@ function onLoad() {
     menuItemNode.setAttribute("label", nickAndSerial); // This is displayed.
     selectElement.firstChild.appendChild(menuItemNode);
     if (i == 0) {
       selectElement.selectedItem = menuItemNode;
     }
   }
 
   setDetails();
+
+  Services.obs.notifyObservers(document.getElementById("certAuthAsk"),
+                               "cert-dialog-loaded", null);
 }
 
 /**
  * Populates the details section with information concerning the selected cert.
  */
 function setDetails() {
   let index = parseInt(document.getElementById("nicknames").value);
   let cert = certArray.queryElementAt(index, Ci.nsIX509Cert);
--- a/security/manager/ssl/nsClientAuthRemember.cpp
+++ b/security/manager/ssl/nsClientAuthRemember.cpp
@@ -2,16 +2,17 @@
  *
  * 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/. */
 
 #include "nsClientAuthRemember.h"
 
 #include "nsIX509Cert.h"
+#include "mozilla/BasePrincipal.h"
 #include "mozilla/RefPtr.h"
 #include "nsCRT.h"
 #include "nsNSSCertHelper.h"
 #include "nsIObserverService.h"
 #include "nsNetUtil.h"
 #include "nsISupportsPrimitives.h"
 #include "nsPromiseFlatString.h"
 #include "nsThreadUtils.h"
@@ -53,19 +54,19 @@ nsClientAuthRememberService::Init()
   if (observerService) {
     observerService->AddObserver(this, "profile-before-change", true);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsClientAuthRememberService::Observe(nsISupports     *aSubject,
-                               const char      *aTopic,
-                               const char16_t *aData)
+nsClientAuthRememberService::Observe(nsISupports* aSubject,
+                                     const char* aTopic,
+                                     const char16_t* aData)
 {
   // check the topic
   if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
     // The profile is about to change,
     // or is going away because the application is shutting down.
 
     ReentrantMonitorAutoEnter lock(monitor);
     RemoveAllFromMemory();
@@ -92,18 +93,19 @@ void nsClientAuthRememberService::ClearA
 
 void
 nsClientAuthRememberService::RemoveAllFromMemory()
 {
   mSettingsTable.Clear();
 }
 
 nsresult
-nsClientAuthRememberService::RememberDecision(const nsACString & aHostName, 
-                                              CERTCertificate *aServerCert, CERTCertificate *aClientCert)
+nsClientAuthRememberService::RememberDecision(
+  const nsACString& aHostName, const NeckoOriginAttributes& aOriginAttributes,
+  CERTCertificate* aServerCert, CERTCertificate* aClientCert)
 {
   // aClientCert == nullptr means: remember that user does not want to use a cert
   NS_ENSURE_ARG_POINTER(aServerCert);
   if (aHostName.IsEmpty()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsAutoCString fpStr;
@@ -114,95 +116,98 @@ nsClientAuthRememberService::RememberDec
 
   {
     ReentrantMonitorAutoEnter lock(monitor);
     if (aClientCert) {
       RefPtr<nsNSSCertificate> pipCert(new nsNSSCertificate(aClientCert));
       nsAutoCString dbkey;
       rv = pipCert->GetDbKey(dbkey);
       if (NS_SUCCEEDED(rv)) {
-        AddEntryToList(aHostName, fpStr, dbkey);
+        AddEntryToList(aHostName, aOriginAttributes, fpStr, dbkey);
       }
     } else {
       nsCString empty;
-      AddEntryToList(aHostName, fpStr, empty);
+      AddEntryToList(aHostName, aOriginAttributes, fpStr, empty);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-nsClientAuthRememberService::HasRememberedDecision(const nsACString & aHostName, 
-                                                   CERTCertificate *aCert, 
-                                                   nsACString & aCertDBKey,
-                                                   bool *_retval)
+nsClientAuthRememberService::HasRememberedDecision(
+  const nsACString& aHostName, const NeckoOriginAttributes& aOriginAttributes,
+  CERTCertificate* aCert, nsACString& aCertDBKey, bool* aRetVal)
 {
   if (aHostName.IsEmpty())
     return NS_ERROR_INVALID_ARG;
 
   NS_ENSURE_ARG_POINTER(aCert);
-  NS_ENSURE_ARG_POINTER(_retval);
-  *_retval = false;
+  NS_ENSURE_ARG_POINTER(aRetVal);
+  *aRetVal = false;
 
   nsresult rv;
   nsAutoCString fpStr;
   rv = GetCertFingerprintByOidTag(aCert, SEC_OID_SHA256, fpStr);
   if (NS_FAILED(rv))
     return rv;
 
-  nsAutoCString hostCert;
-  GetHostWithCert(aHostName, fpStr, hostCert);
+  nsAutoCString entryKey;
+  GetEntryKey(aHostName, aOriginAttributes, fpStr, entryKey);
   nsClientAuthRemember settings;
 
   {
     ReentrantMonitorAutoEnter lock(monitor);
-    nsClientAuthRememberEntry *entry = mSettingsTable.GetEntry(hostCert.get());
+    nsClientAuthRememberEntry* entry = mSettingsTable.GetEntry(entryKey.get());
     if (!entry)
       return NS_OK;
     settings = entry->mSettings; // copy
   }
 
   aCertDBKey = settings.mDBKey;
-  *_retval = true;
+  *aRetVal = true;
   return NS_OK;
 }
 
 nsresult
-nsClientAuthRememberService::AddEntryToList(const nsACString &aHostName, 
-                                      const nsACString &fingerprint,
-                                      const nsACString &db_key)
-
+nsClientAuthRememberService::AddEntryToList(
+  const nsACString& aHostName, const NeckoOriginAttributes& aOriginAttributes,
+  const nsACString& aFingerprint, const nsACString& aDBKey)
 {
-  nsAutoCString hostCert;
-  GetHostWithCert(aHostName, fingerprint, hostCert);
+  nsAutoCString entryKey;
+  GetEntryKey(aHostName, aOriginAttributes, aFingerprint, entryKey);
 
   {
     ReentrantMonitorAutoEnter lock(monitor);
-    nsClientAuthRememberEntry *entry = mSettingsTable.PutEntry(hostCert.get());
+    nsClientAuthRememberEntry* entry = mSettingsTable.PutEntry(entryKey.get());
 
     if (!entry) {
       NS_ERROR("can't insert a null entry!");
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    entry->mHostWithCert = hostCert;
+    entry->mEntryKey = entryKey;
 
-    nsClientAuthRemember &settings = entry->mSettings;
+    nsClientAuthRemember& settings = entry->mSettings;
     settings.mAsciiHost = aHostName;
-    settings.mFingerprint = fingerprint;
-    settings.mDBKey = db_key;
+    settings.mFingerprint = aFingerprint;
+    settings.mDBKey = aDBKey;
   }
 
   return NS_OK;
 }
 
 void
-nsClientAuthRememberService::GetHostWithCert(const nsACString & aHostName, 
-                                             const nsACString & fingerprint, 
-                                             nsACString& _retval)
+nsClientAuthRememberService::GetEntryKey(
+  const nsACString& aHostName,
+  const NeckoOriginAttributes& aOriginAttributes,
+  const nsACString& aFingerprint,
+  nsACString& aEntryKey)
 {
   nsAutoCString hostCert(aHostName);
+  nsAutoCString suffix;
+  aOriginAttributes.CreateSuffix(suffix);
+  hostCert.Append(suffix);
   hostCert.Append(':');
-  hostCert.Append(fingerprint);
-  
-  _retval.Assign(hostCert);
+  hostCert.Append(aFingerprint);
+
+  aEntryKey.Assign(hostCert);
 }
--- a/security/manager/ssl/nsClientAuthRemember.h
+++ b/security/manager/ssl/nsClientAuthRemember.h
@@ -11,34 +11,40 @@
 #include "nsTHashtable.h"
 #include "nsIObserver.h"
 #include "nsIX509Cert.h"
 #include "nsNSSCertificate.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 #include "mozilla/Attributes.h"
 
+namespace mozilla {
+  class NeckoOriginAttributes;
+}
+
+using mozilla::NeckoOriginAttributes;
+
 class nsClientAuthRemember
 {
 public:
 
   nsClientAuthRemember()
   {
   }
-  
-  nsClientAuthRemember(const nsClientAuthRemember &other)
+
+  nsClientAuthRemember(const nsClientAuthRemember& aOther)
   {
-    this->operator=(other);
+    this->operator=(aOther);
   }
 
-  nsClientAuthRemember &operator=(const nsClientAuthRemember &other)
+  nsClientAuthRemember& operator=(const nsClientAuthRemember& aOther)
   {
-    mAsciiHost = other.mAsciiHost;
-    mFingerprint = other.mFingerprint;
-    mDBKey = other.mDBKey;
+    mAsciiHost = aOther.mAsciiHost;
+    mFingerprint = aOther.mFingerprint;
+    mDBKey = aOther.mDBKey;
     return *this;
   }
 
   nsCString mAsciiHost;
   nsCString mFingerprint;
   nsCString mDBKey;
 };
 
@@ -51,92 +57,99 @@ class nsClientAuthRememberEntry final : 
     typedef const char* KeyType;
     typedef const char* KeyTypePointer;
 
     // do nothing with aHost - we require mHead to be set before we're live!
     explicit nsClientAuthRememberEntry(KeyTypePointer aHostWithCertUTF8)
     {
     }
 
-    nsClientAuthRememberEntry(const nsClientAuthRememberEntry& toCopy)
+    nsClientAuthRememberEntry(const nsClientAuthRememberEntry& aToCopy)
     {
-      mSettings = toCopy.mSettings;
+      mSettings = aToCopy.mSettings;
     }
 
     ~nsClientAuthRememberEntry()
     {
     }
 
     KeyType GetKey() const
     {
-      return HostWithCertPtr();
+      return EntryKeyPtr();
     }
 
     KeyTypePointer GetKeyPointer() const
     {
-      return HostWithCertPtr();
+      return EntryKeyPtr();
     }
 
     bool KeyEquals(KeyTypePointer aKey) const
     {
-      return !strcmp(HostWithCertPtr(), aKey);
+      return !strcmp(EntryKeyPtr(), aKey);
     }
 
     static KeyTypePointer KeyToPointer(KeyType aKey)
     {
       return aKey;
     }
 
     static PLDHashNumber HashKey(KeyTypePointer aKey)
     {
       return PLDHashTable::HashStringKey(aKey);
     }
 
     enum { ALLOW_MEMMOVE = false };
 
     // get methods
-    inline const nsCString &HostWithCert() const { return mHostWithCert; }
+    inline const nsCString& GetEntryKey() const { return mEntryKey; }
 
-    inline KeyTypePointer HostWithCertPtr() const
+    inline KeyTypePointer EntryKeyPtr() const
     {
-      return mHostWithCert.get();
+      return mEntryKey.get();
     }
 
     nsClientAuthRemember mSettings;
-    nsCString mHostWithCert;
+    nsCString mEntryKey;
 };
 
 class nsClientAuthRememberService final : public nsIObserver,
                                           public nsSupportsWeakReference
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   nsClientAuthRememberService();
 
   nsresult Init();
 
-  static void GetHostWithCert(const nsACString & aHostName, 
-                              const nsACString & nickname, nsACString& _retval);
+  static void GetEntryKey(const nsACString& aHostName,
+                          const NeckoOriginAttributes& aOriginAttributes,
+                          const nsACString& aFingerprint,
+                          /*out*/ nsACString& aEntryKey);
 
-  nsresult RememberDecision(const nsACString & aHostName, 
-                            CERTCertificate *aServerCert, CERTCertificate *aClientCert);
-  nsresult HasRememberedDecision(const nsACString & aHostName, 
-                                 CERTCertificate *aServerCert, 
-                                 nsACString & aCertDBKey, bool *_retval);
+  nsresult RememberDecision(const nsACString& aHostName,
+                            const NeckoOriginAttributes& aOriginAttributes,
+                            CERTCertificate* aServerCert,
+                            CERTCertificate* aClientCert);
+
+  nsresult HasRememberedDecision(const nsACString& aHostName,
+                                 const NeckoOriginAttributes& aOriginAttributes,
+                                 CERTCertificate* aServerCert,
+                                 nsACString& aCertDBKey, bool* aRetVal);
 
   void ClearRememberedDecisions();
   static void ClearAllRememberedDecisions();
 
 protected:
     ~nsClientAuthRememberService();
 
     mozilla::ReentrantMonitor monitor;
     nsTHashtable<nsClientAuthRememberEntry> mSettingsTable;
 
     void RemoveAllFromMemory();
-    nsresult AddEntryToList(const nsACString &host, 
-                            const nsACString &server_fingerprint,
-                            const nsACString &db_key);
+    nsresult AddEntryToList(const nsACString& aHost,
+                            const NeckoOriginAttributes& aOriginAttributes,
+                            const nsACString& aServerFingerprint,
+                            const nsACString& aDBKey);
 };
 
 #endif
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -2130,18 +2130,19 @@ ClientAuthDataRunnable::RunOnTargetThrea
 
     RefPtr<nsClientAuthRememberService> cars =
       mSocketInfo->SharedState().GetClientAuthRememberService();
 
     bool hasRemembered = false;
     nsCString rememberedDBKey;
     if (cars) {
       bool found;
-      rv = cars->HasRememberedDecision(hostname, mServerCert,
-        rememberedDBKey, &found);
+      rv = cars->HasRememberedDecision(hostname,
+                                       mSocketInfo->GetOriginAttributes(),
+                                       mServerCert, rememberedDBKey, &found);
       if (NS_SUCCEEDED(rv) && found) {
         hasRemembered = true;
       }
     }
 
     if (hasRemembered && !rememberedDBKey.IsEmpty()) {
       nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
       if (certdb) {
@@ -2245,18 +2246,18 @@ ClientAuthDataRunnable::RunOnTargetThrea
                                                                selectedIndex);
         if (!selectedCert) {
           goto loser;
         }
         cert.reset(selectedCert->GetCert());
       }
 
       if (cars && wantRemember) {
-        cars->RememberDecision(hostname, mServerCert,
-                               certChosen ? cert.get() : nullptr);
+        cars->RememberDecision(hostname, mSocketInfo->GetOriginAttributes(),
+                               mServerCert, certChosen ? cert.get() : nullptr);
       }
     }
 
     if (!cert) {
       goto loser;
     }
 
     // go get the private key
--- a/storage/test/unit/test_bug-429521.js
+++ b/storage/test/unit/test_bug-429521.js
@@ -19,17 +19,17 @@ function test_bug429521() {
   print("*** test_bug429521: started");
 
   try {
     while (stmt.executeStep()) {
       print("*** test_bug429521: step() Read wrapper.row.zone");
 
       // BUG: the print commands after the following statement
       // are never executed. Script stops immediately.
-      var tzId = stmt.row.zone;
+      stmt.row.zone;
 
       print("*** test_bug429521: step() Read wrapper.row.zone finished");
     }
   } catch (e) {
     print("*** test_bug429521: " + e);
   }
 
   print("*** test_bug429521: finished");
--- a/storage/test/unit/test_statement_executeAsync.js
+++ b/storage/test/unit/test_statement_executeAsync.js
@@ -823,17 +823,17 @@ function test_not_right_owning_statement
     "VALUES (:int)"
   );
   let stmt2 = makeTestStatement(
     "INSERT INTO test (id) " +
     "VALUES (:int)"
   );
 
   let array1 = stmt1.newBindingParamsArray();
-  let array2 = stmt2.newBindingParamsArray();
+  stmt2.newBindingParamsArray();
   let bp = array1.newBindingParams();
   bp.bindByName("int", INTEGER);
   array1.addParams(bp);
 
   // We should not be able to bind array1 since it was created from stmt1.
   expectError(Cr.NS_ERROR_UNEXPECTED,
               () => stmt2.bindParameters(array1));
 
--- a/storage/test/unit/test_storage_connection.js
+++ b/storage/test/unit/test_storage_connection.js
@@ -176,17 +176,17 @@ add_task(function* test_createTable() {
   } finally {
     if (con) {
       con.close();
     }
   }
 });
 
 add_task(function* test_defaultSynchronousAtNormal() {
-  var msc = getOpenedDatabase();
+  getOpenedDatabase();
   var stmt = createStatement("PRAGMA synchronous;");
   try {
     stmt.executeStep();
     do_check_eq(1, stmt.getInt32(0));
   }
   finally {
     stmt.reset();
     stmt.finalize();
--- a/taskcluster/ci/docker-image/image.yml
+++ b/taskcluster/ci/docker-image/image.yml
@@ -60,9 +60,9 @@ task:
       imageName: '{{image_name}}'
     treeherderEnv:
       - staging
       - production
     treeherder:
       jobKind: other
       build:
         platform: 'taskcluster-images'
-      symbol: 'I'
+      groupSymbol: 'I'
--- a/taskcluster/ci/docker-image/kind.yml
+++ b/taskcluster/ci/docker-image/kind.yml
@@ -6,14 +6,14 @@ implementation: 'taskgraph.task.docker_i
 images_path: '../../../testing/docker'
 
 # make a task for each docker-image we might want.  For the moment, since we
 # write artifacts for each, these are whitelisted, but ideally that will change
 # (to use subdirectory clones of the proper directory), at which point we can
 # generate tasks for every docker image in the directory, secure in the
 # knowledge that unnecessary images will be omitted from the target task graph
 images:
-  - desktop-test
-  - desktop1604-test
-  - desktop-build
-  - tester
-  - lint
-  - android-gradle-build
+  desktop-test: dt
+  desktop1604-test: dt16t
+  desktop-build: db
+  tester: tst
+  lint: lnt
+  android-gradle-build: agb
--- a/taskcluster/taskgraph/task/docker_image.py
+++ b/taskcluster/taskgraph/task/docker_image.py
@@ -53,27 +53,31 @@ class DockerImageTask(base.Task):
             'source': '{repo}file/{rev}/taskcluster/ci/docker-image/image.yml'
                       .format(repo=params['head_repository'], rev=params['head_rev']),
             'index_image_prefix': INDEX_PREFIX,
             'artifact_path': 'public/image.tar.zst',
         }
 
         tasks = []
         templates = Templates(path)
-        for image_name in config['images']:
+        for image_name, image_symbol in config['images'].iteritems():
             context_path = os.path.join('testing', 'docker', image_name)
             context_hash = generate_context_hash(GECKO, context_path, image_name)
 
             image_parameters = dict(parameters)
             image_parameters['image_name'] = image_name
             image_parameters['context_hash'] = context_hash
 
             image_task = templates.load('image.yml', image_parameters)
             attributes = {'image_name': image_name}
 
+            # unique symbol for different docker image
+            if 'extra' in image_task['task']:
+                image_task['task']['extra']['treeherder']['symbol'] = image_symbol
+
             # As an optimization, if the context hash exists for a high level, that image
             # task ID will be used.  The reasoning behind this is that eventually everything ends
             # up on level 3 at some point if most tasks use this as a common image
             # for a given context hash, a worker within Taskcluster does not need to contain
             # the same image per branch.
             index_paths = ['{}.level-{}.{}.hash.{}'.format(
                                 INDEX_PREFIX, level, image_name, context_hash)
                            for level in range(int(params['level']), 4)]
--- a/testing/marionette/accessibility.js
+++ b/testing/marionette/accessibility.js
@@ -100,17 +100,17 @@ accessibility.ActionableRoles = new Set(
   "switch",
 ]);
 
 
 /**
  * Factory function that constructs a new {@code accessibility.Checks}
  * object with enforced strictness or not.
  */
-accessibility.get = function(strict = false) {
+accessibility.get = function (strict = false) {
   return new accessibility.Checks(!!strict);
 };
 
 /**
  * Component responsible for interacting with platform accessibility
  * API.
  *
  * Its methods serve as wrappers for testing content and chrome
--- a/testing/marionette/action.js
+++ b/testing/marionette/action.js
@@ -54,17 +54,17 @@ action.PointerType = {
  *     Name of pointer type.
  *
  * @return {string}
  *     A pointer type for processing pointer parameters.
  *
  * @throws InvalidArgumentError
  *     If |str| is not a valid pointer type.
  */
-action.PointerType.get = function(str) {
+action.PointerType.get = function (str) {
   let name = capitalize(str);
   if (!(name in this)) {
     throw new InvalidArgumentError(`Unknown pointerType: ${str}`);
   }
   return this[name];
 };
 
 /**
--- a/testing/marionette/addon.js
+++ b/testing/marionette/addon.js
@@ -44,37 +44,37 @@ function lookupError(code) {
  *     True to install the addon temporarily, false (default) otherwise.
  *
  * @return {Promise: string}
  *     Addon ID.
  *
  * @throws {UnknownError}
  *     If there is a problem installing the addon.
  */
-addon.install = function(path, temporary = false) {
+addon.install = function (path, temporary = false) {
   return new Promise((resolve, reject) => {
     let file = new FileUtils.File(path);
 
     let listener = {
-      onInstallEnded: function(install, addon) {
+      onInstallEnded: function (install, addon) {
         resolve(addon.id);
       },
 
-      onInstallFailed: function(install) {
+      onInstallFailed: function (install) {
         reject(lookupError(install.error));
       },
 
-      onInstalled: function(addon) {
+      onInstalled: function (addon) {
         AddonManager.removeAddonListener(listener);
         resolve(addon.id);
       }
     };
 
     if (!temporary) {
-      AddonManager.getInstallForFile(file, function(aInstall) {
+      AddonManager.getInstallForFile(file, function (aInstall) {
         if (aInstall.error !== 0) {
           reject(lookupError(aInstall.error));
         }
         aInstall.addListener(listener);
         aInstall.install();
       });
     } else {
       AddonManager.addAddonListener(listener);
@@ -89,16 +89,16 @@ addon.install = function(path, temporary
  * If the addon is restartless it will be uninstalled right away.
  * Otherwise, Firefox must be restarted for the change to take effect.
  *
  * @param {string} id
  *     ID of the addon to uninstall.
  *
  * @return {Promise}
  */
-addon.uninstall = function(id) {
+addon.uninstall = function (id) {
   return new Promise(resolve => {
-    AddonManager.getAddonByID(id, function(addon) {
+    AddonManager.getAddonByID(id, function (addon) {
       addon.uninstall();
       resolve();
     });
   });
 };
--- a/testing/marionette/assert.js
+++ b/testing/marionette/assert.js
@@ -24,60 +24,60 @@ this.assert = {};
  * Asserts that the current browser is Firefox Desktop.
  *
  * @param {string=} msg
  *     Custom error message.
  *
  * @throws {UnsupportedOperationError}
  *     If current browser is not Firefox.
  */
-assert.firefox = function(msg = "") {
+assert.firefox = function (msg = "") {
   msg = msg || "Expected Firefox";
   assert.that(isFirefox, msg, UnsupportedOperationError)();
 };
 
 /**
  * Asserts that the current browser is Fennec, or Firefox for Android.
  *
  * @param {string=} msg
  *     Custom error message.
  *
  * @throws {UnsupportedOperationError}
  *     If current browser is not Fennec.
  */
-assert.fennec = function(msg = "") {
+assert.fennec = function (msg = "") {
   msg = msg || "Expected Fennec";
   assert.that(isFennec, msg, UnsupportedOperationError)();
 };
 
 /**
  * Asserts that the current browser is B2G.
  *
  * @param {string=} msg
  *     Custom error message.
  *
  * @throws {UnsupportedOperationError}
  *     If the current browser is not B2G.
  */
-assert.b2g = function(msg = "") {
+assert.b2g = function (msg = "") {
   msg = msg || "Expected B2G"
   assert.that(isB2G, msg, UnsupportedOperationError)();
 };
 
 /**
  * Asserts that the current browser is a mobile browser, that is either
  * B2G or Fennec.
  *
  * @param {string=} msg
  *     Custom error message.
  *
  * @throws {UnsupportedOperationError}
  *     If the current browser is not B2G or Fennec.
  */
-assert.mobile = function(msg = "") {
+assert.mobile = function (msg = "") {
   msg = msg || "Expected Fennec or B2G";
   assert.that(() => isFennec() || isB2G(), msg, UnsupportedOperationError)();
 };
 
 /**
  * Asserts that |obj| is defined.
  *
  * @param {?} obj
@@ -86,17 +86,17 @@ assert.mobile = function(msg = "") {
  *     Custom error message.
  *
  * @return {?}
  *     |obj| is returned unaltered.
  *
  * @throws {InvalidArgumentError}
  *     If |obj| is not defined.
  */
-assert.defined = function(obj, msg = "") {
+assert.defined = function (obj, msg = "") {
   msg = msg || error.pprint`Expected ${obj} to be defined`;
   return assert.that(o => typeof o != "undefined", msg)(obj);
 };
 
 /**
  * Asserts that |obj| is an integer.
  *
  * @param {?} obj
@@ -105,17 +105,17 @@ assert.defined = function(obj, msg = "")
  *     Custom error message.
  *
  * @return {number}
  *     |obj| is returned unaltered.
  *
  * @throws {InvalidArgumentError}
  *     If |obj| is not an integer.
  */
-assert.integer = function(obj, msg = "") {
+assert.integer = function (obj, msg = "") {
   msg = msg || error.pprint`Expected ${obj} to be an integer`;
   return assert.that(Number.isInteger, msg)(obj);
 };
 
 /**
  * Asserts that |obj| is a positive integer.
  *
  * @param {?} obj
@@ -124,17 +124,17 @@ assert.integer = function(obj, msg = "")
  *     Custom error message.
  *
  * @return {number}
  *     |obj| is returned unaltered.
  *
  * @throws {InvalidArgumentError}
  *     If |obj| is not a positive integer.
  */
-assert.positiveInteger = function(obj, msg = "") {
+assert.positiveInteger = function (obj, msg = "") {
   assert.integer(obj, msg);
   msg = msg || error.pprint`Expected ${obj} to be >= 0`;
   return assert.that(n => n >= 0, msg)(obj);
 };
 
 /**
  * Asserts that |obj| is a boolean.
  *
@@ -144,17 +144,17 @@ assert.positiveInteger = function(obj, m
  *     Custom error message.
  *
  * @return {boolean}
  *     |obj| is returned unaltered.
  *
  * @throws {InvalidArgumentError}
  *     If |obj| is not a boolean.
  */
-assert.boolean = function(obj, msg = "") {
+assert.boolean = function (obj, msg = "") {
   msg = msg || error.pprint`Expected ${obj} to be boolean`;
   return assert.that(b => typeof b == "boolean", msg)(obj);
 };
 
 /**
  * Asserts that |obj| is a string.
  *
  * @param {?} obj
@@ -163,17 +163,17 @@ assert.boolean = function(obj, msg = "")
  *     Custom error message.
  *
  * @return {string}
  *     |obj| is returned unaltered.
  *
  * @throws {InvalidArgumentError}
  *     If |obj| is not a string.
  */
-assert.string = function(obj, msg = "") {
+assert.string = function (obj, msg = "") {
   msg = msg || error.pprint`Expected ${obj} to be a string`;
   return assert.that(s => typeof s == "string", msg)(obj);
 };
 
 /**
  * Asserts that |obj| is an object.
  *
  * @param {?} obj
@@ -182,17 +182,17 @@ assert.string = function(obj, msg = "") 
  *     Custom error message.
  *
  * @return {Object}
  *     |obj| is returned unaltered.
  *
  * @throws {InvalidArgumentError}
  *     If |obj| is not an object.
  */
-assert.object = function(obj, msg = "") {
+assert.object = function (obj, msg = "") {
   msg = msg || error.pprint`Expected ${obj} to be an object`;
   return assert.that(o => typeof o == "object", msg)(obj);
 };
 
 /**
  * Returns a function that is used to assert the |predicate|.
  *
  * @param {function(?): boolean} predicate
@@ -204,17 +204,17 @@ assert.object = function(obj, msg = "") 
  * @param {Error=} error
  *     Custom error type by its class.
  *
  * @return {function(?): ?}
  *     Function that takes and returns the passed in value unaltered, and
  *     which may throw |error| with |message| if |predicate| evaluates
  *     to false.
  */
-assert.that = function(
+assert.that = function (
     predicate, message = "", error = InvalidArgumentError) {
   return obj => {
     if (!predicate(obj)) {
       throw new error(message);
     }
     return obj;
   };
 };
--- a/testing/marionette/atom.js
+++ b/testing/marionette/atom.js
@@ -11,182 +11,182 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
 this.EXPORTED_SYMBOLS = ["atom"];
 
 this.atom = {};
 
-atom.clearElement = function(element, window){return function(){function g(a){throw a;}var h=void 0,i=!0,k=null,l=!1;function n(a){return function(){return this[a]}}function o(a){return function(){return a}}var p,q=this;
+atom.clearElement = function (element, window){return function(){function g(a){throw a;}var h=void 0,i=!0,k=null,l=!1;function n(a){return function(){return this[a]}}function o(a){return function(){return a}}var p,q=this;
 function aa(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
 else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function r(a){return a!==h}function ba(a){var b=aa(a);return"array"==b||"object"==b&&"number"==typeof a.length}function t(a){return"string"==typeof a}function w(a){return"function"==aa(a)}function ca(a){a=aa(a);return"object"==a||"array"==a||"function"==a}var da="closure_uid_"+Math.floor(2147483648*Math.random()).toString(36),ea=0,fa=Date.now||function(){return+new Date};
 function x(a,b){function c(){}c.prototype=b.prototype;a.$=b.prototype;a.prototype=new c};function ga(a,b){for(var c=1;c<arguments.length;c++)var d=(""+arguments[c]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a}function ha(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}function ia(a){if(!ja.test(a))return a;-1!=a.indexOf("&")&&(a=a.replace(ka,"&amp;"));-1!=a.indexOf("<")&&(a=a.replace(la,"&lt;"));-1!=a.indexOf(">")&&(a=a.replace(ma,"&gt;"));-1!=a.indexOf('"')&&(a=a.replace(na,"&quot;"));return a}var ka=/&/g,la=/</g,ma=/>/g,na=/\"/g,ja=/[&<>\"]/;
 function oa(a,b){for(var c=0,d=ha(""+a).split("."),e=ha(""+b).split("."),f=Math.max(d.length,e.length),j=0;0==c&&j<f;j++){var m=d[j]||"",s=e[j]||"",O=RegExp("(\\d*)(\\D*)","g"),E=RegExp("(\\d*)(\\D*)","g");do{var u=O.exec(m)||["","",""],v=E.exec(s)||["","",""];if(0==u[0].length&&0==v[0].length)break;c=((0==u[1].length?0:parseInt(u[1],10))<(0==v[1].length?0:parseInt(v[1],10))?-1:(0==u[1].length?0:parseInt(u[1],10))>(0==v[1].length?0:parseInt(v[1],10))?1:0)||((0==u[2].length)<(0==v[2].length)?-1:(0==
-u[2].length)>(0==v[2].length)?1:0)||(u[2]<v[2]?-1:u[2]>v[2]?1:0)}while(0==c)}return c}var pa=2147483648*Math.random()|0,qa={};function ra(a){return qa[a]||(qa[a]=(""+a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()}))};var sa,ta;function ua(){return q.navigator?q.navigator.userAgent:k}var va,wa=q.navigator;va=wa&&wa.platform||"";sa=-1!=va.indexOf("Mac");ta=-1!=va.indexOf("Win");var xa=-1!=va.indexOf("Linux"),ya,za="",Aa=/rv\:([^\);]+)(\)|;)/.exec(ua());ya=za=Aa?Aa[1]:"";var Ba={};var Ca=window;function Da(a,b){for(var c in a)b.call(h,a[c],c,a)}function Ea(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};function y(a,b){this.code=a;this.message=b||"";this.name=Fa[a]||Fa[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}x(y,Error);
+u[2].length)>(0==v[2].length)?1:0)||(u[2]<v[2]?-1:u[2]>v[2]?1:0)}while(0==c)}return c}var pa=2147483648*Math.random()|0,qa={};function ra(a){return qa[a]||(qa[a]=(""+a).replace(/\-([a-z])/g,function (a,c){return c.toUpperCase()}))};var sa,ta;function ua(){return q.navigator?q.navigator.userAgent:k}var va,wa=q.navigator;va=wa&&wa.platform||"";sa=-1!=va.indexOf("Mac");ta=-1!=va.indexOf("Win");var xa=-1!=va.indexOf("Linux"),ya,za="",Aa=/rv\:([^\);]+)(\)|;)/.exec(ua());ya=za=Aa?Aa[1]:"";var Ba={};var Ca=window;function Da(a,b){for(var c in a)b.call(h,a[c],c,a)}function Ea(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};function y(a,b){this.code=a;this.message=b||"";this.name=Fa[a]||Fa[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}x(y,Error);
 var Fa={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"};
 y.prototype.toString=function(){return"["+this.name+"] "+this.message};function Ga(a){this.stack=Error().stack||"";a&&(this.message=""+a)}x(Ga,Error);Ga.prototype.name="CustomError";function Ha(a,b){b.unshift(a);Ga.call(this,ga.apply(k,b));b.shift()}x(Ha,Ga);Ha.prototype.name="AssertionError";function Ia(a,b,c){if(!a){var d=Array.prototype.slice.call(arguments,2),e="Assertion failed";if(b)var e=e+(": "+b),f=d;g(new Ha(""+e,f||[]))}}function Ja(a,b){g(new Ha("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1)))};function z(a){return a[a.length-1]}var Ka=Array.prototype;function A(a,b){if(t(a))return!t(b)||1!=b.length?-1:a.indexOf(b,0);for(var c=0;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1}function La(a,b){for(var c=a.length,d=t(a)?a.split(""):a,e=0;e<c;e++)e in d&&b.call(h,d[e],e,a)}function Ma(a,b){for(var c=a.length,d=Array(c),e=t(a)?a.split(""):a,f=0;f<c;f++)f in e&&(d[f]=b.call(h,e[f],f,a));return d}
 function Na(a,b,c){for(var d=a.length,e=t(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return i;return l}function Oa(a,b,c){for(var d=a.length,e=t(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return l;return i}function Pa(a,b){var c;a:{c=a.length;for(var d=t(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(h,d[e],e,a)){c=e;break a}c=-1}return 0>c?k:t(a)?a.charAt(c):a[c]}function Qa(a){return Ka.concat.apply(Ka,arguments)}
-function Ra(a){if("array"==aa(a))return Qa(a);for(var b=[],c=0,d=a.length;c<d;c++)b[c]=a[c];return b}function Sa(a,b,c){Ia(a.length!=k);return 2>=arguments.length?Ka.slice.call(a,b):Ka.slice.call(a,b,c)};var Ta;Ba["1.9.1"]||(Ba["1.9.1"]=0<=oa(ya,"1.9.1"));function Ua(a,b){var c;c=(c=a.className)&&"function"==typeof c.split?c.split(/\s+/):[];var d=Sa(arguments,1),e;e=c;for(var f=0,j=0;j<d.length;j++)0<=A(e,d[j])||(e.push(d[j]),f++);e=f==d.length;a.className=c.join(" ");return e};function B(a,b){this.x=r(a)?a:0;this.y=r(b)?b:0}B.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function Va(a,b){this.width=a;this.height=b}Va.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};Va.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};Va.prototype.scale=function(a){this.width*=a;this.height*=a;return this};var C=3;function Wa(a){return a?new Xa(D(a)):Ta||(Ta=new Xa)}function Ya(a,b){Da(b,function(b,d){"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:d in Za?a.setAttribute(Za[d],b):0==d.lastIndexOf("aria-",0)?a.setAttribute(d,b):a[d]=b})}var Za={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",rowspan:"rowSpan",valign:"vAlign",height:"height",width:"width",usemap:"useMap",frameborder:"frameBorder",maxlength:"maxLength",type:"type"};
+function Ra(a){if("array"==aa(a))return Qa(a);for(var b=[],c=0,d=a.length;c<d;c++)b[c]=a[c];return b}function Sa(a,b,c){Ia(a.length!=k);return 2>=arguments.length?Ka.slice.call(a,b):Ka.slice.call(a,b,c)};var Ta;Ba["1.9.1"]||(Ba["1.9.1"]=0<=oa(ya,"1.9.1"));function Ua(a,b){var c;c=(c=a.className)&&"function"==typeof c.split?c.split(/\s+/):[];var d=Sa(arguments,1),e;e=c;for(var f=0,j=0;j<d.length;j++)0<=A(e,d[j])||(e.push(d[j]),f++);e=f==d.length;a.className=c.join(" ");return e};function B(a,b){this.x=r(a)?a:0;this.y=r(b)?b:0}B.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function Va(a,b){this.width=a;this.height=b}Va.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};Va.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};Va.prototype.scale=function (a){this.width*=a;this.height*=a;return this};var C=3;function Wa(a){return a?new Xa(D(a)):Ta||(Ta=new Xa)}function Ya(a,b){Da(b,function (b,d){"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:d in Za?a.setAttribute(Za[d],b):0==d.lastIndexOf("aria-",0)?a.setAttribute(d,b):a[d]=b})}var Za={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",rowspan:"rowSpan",valign:"vAlign",height:"height",width:"width",usemap:"useMap",frameborder:"frameBorder",maxlength:"maxLength",type:"type"};
 function F(a){return a?a.parentWindow||a.defaultView:window}function $a(a,b,c){function d(c){c&&b.appendChild(t(c)?a.createTextNode(c):c)}for(var e=2;e<c.length;e++){var f=c[e];ba(f)&&!(ca(f)&&0<f.nodeType)?La(ab(f)?Ra(f):f,d):d(f)}}function bb(a){return a&&a.parentNode?a.parentNode.removeChild(a):k}
 function G(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a}
 function cb(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=1==a.nodeType,d=1==b.nodeType;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,f=b.parentNode;return e==f?db(a,b):!c&&G(e,b)?-1*eb(a,b):!d&&G(f,a)?eb(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=D(a);c=d.createRange();c.selectNode(a);c.collapse(i);d=d.createRange();d.selectNode(b);d.collapse(i);
 return c.compareBoundaryPoints(q.Range.START_TO_END,d)}function eb(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return db(d,a)}function db(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1}
 function fb(a){var b,c=arguments.length;if(c){if(1==c)return arguments[0]}else return k;var d=[],e=Infinity;for(b=0;b<c;b++){for(var f=[],j=arguments[b];j;)f.unshift(j),j=j.parentNode;d.push(f);e=Math.min(e,f.length)}f=k;for(b=0;b<e;b++){for(var j=d[0][b],m=1;m<c;m++)if(j!=d[m][b])return f;f=j}return f}function D(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function gb(a,b){var c=[];return hb(a,b,c,i)?c[0]:h}
 function hb(a,b,c,d){if(a!=k)for(a=a.firstChild;a;){if(b(a)&&(c.push(a),d)||hb(a,b,c,d))return i;a=a.nextSibling}return l}var ib={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},jb={IMG:" ",BR:"\n"};function kb(a,b,c){if(!(a.nodeName in ib))if(a.nodeType==C)c?b.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in jb)b.push(jb[a.nodeName]);else for(a=a.firstChild;a;)kb(a,b,c),a=a.nextSibling}
-function ab(a){if(a&&"number"==typeof a.length){if(ca(a))return"function"==typeof a.item||"string"==typeof a.item;if(w(a))return"function"==typeof a.item}return l}function lb(a,b){for(var a=a.parentNode,c=0;a;){if(b(a))return a;a=a.parentNode;c++}return k}function Xa(a){this.v=a||q.document||document}p=Xa.prototype;p.ea=n("v");p.z=function(a){return t(a)?this.v.getElementById(a):a};
-p.da=function(a,b,c){var d=this.v,e=arguments,f=e[1],j=d.createElement(e[0]);f&&(t(f)?j.className=f:"array"==aa(f)?Ua.apply(k,[j].concat(f)):Ya(j,f));2<e.length&&$a(d,j,e);return j};p.createElement=function(a){return this.v.createElement(a)};p.createTextNode=function(a){return this.v.createTextNode(a)};p.qa=function(){return this.v.parentWindow||this.v.defaultView};
-function mb(a){var b=a.v,a="CSS1Compat"==b.compatMode?b.documentElement:b.body,b=b.parentWindow||b.defaultView;return new B(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)}p.appendChild=function(a,b){a.appendChild(b)};p.removeNode=bb;p.contains=G;var H={};H.ya=function(){var a={Oa:"http://www.w3.org/2000/svg"};return function(b){return a[b]||k}}();H.ma=function(a,b,c){var d=D(a);if(!d.implementation.hasFeature("XPath","3.0"))return k;try{var e=d.createNSResolver?d.createNSResolver(d.documentElement):H.ya;return d.evaluate(b,a,e,c,k)}catch(f){"NS_ERROR_ILLEGAL_VALUE"!=f.name&&g(new y(32,"Unable to locate an element with the xpath expression "+b+" because of the following error:\n"+f))}};
-H.ka=function(a,b){(!a||1!=a.nodeType)&&g(new y(32,'The result of the xpath expression "'+b+'" is: '+a+". It should be an element."))};H.Ia=function(a,b){var c=function(){var c=H.ma(b,a,9);return c?c.singleNodeValue||k:b.selectSingleNode?(c=D(b),c.setProperty&&c.setProperty("SelectionLanguage","XPath"),b.selectSingleNode(a)):k}();c===k||H.ka(c,a);return c};
-H.Na=function(a,b){var c=function(){var c=H.ma(b,a,7);if(c){for(var e=c.snapshotLength,f=[],j=0;j<e;++j)f.push(c.snapshotItem(j));return f}return b.selectNodes?(c=D(b),c.setProperty&&c.setProperty("SelectionLanguage","XPath"),b.selectNodes(a)):[]}();La(c,function(b){H.ka(b,a)});return c};var nb,ob="",pb=/Firefox\/([0-9.]+)/.exec(ua());nb=ob=pb?pb[2]||pb[1]:"";var qb=k,rb=function(){var a=q.Components;if(!a)return l;try{if(!a.classes)return l}catch(b){return l}var c=a.classes,a=a.interfaces,d=c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator),e=c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo).version;qb=function(a){return 0<=d.Ka(e,""+a)};return i}();var I="StopIteration"in q?q.StopIteration:Error("StopIteration");function J(){}J.prototype.next=function(){g(I)};J.prototype.r=function(){return this};function sb(a){if(a instanceof J)return a;if("function"==typeof a.r)return a.r(l);if(ba(a)){var b=0,c=new J;c.next=function(){for(;;){b>=a.length&&g(I);if(b in a)return a[b++];b++}};return c}g(Error("Not implemented"))};function K(a,b,c,d,e){this.o=!!b;a&&L(this,a,d);this.depth=e!=h?e:this.q||0;this.o&&(this.depth*=-1);this.za=!c}x(K,J);p=K.prototype;p.p=k;p.q=0;p.ha=l;function L(a,b,c,d){if(a.p=b)a.q="number"==typeof c?c:1!=a.p.nodeType?0:a.o?-1:1;"number"==typeof d&&(a.depth=d)}
+function ab(a){if(a&&"number"==typeof a.length){if(ca(a))return"function"==typeof a.item||"string"==typeof a.item;if(w(a))return"function"==typeof a.item}return l}function lb(a,b){for(var a=a.parentNode,c=0;a;){if(b(a))return a;a=a.parentNode;c++}return k}function Xa(a){this.v=a||q.document||document}p=Xa.prototype;p.ea=n("v");p.z=function (a){return t(a)?this.v.getElementById(a):a};
+p.da=function (a,b,c){var d=this.v,e=arguments,f=e[1],j=d.createElement(e[0]);f&&(t(f)?j.className=f:"array"==aa(f)?Ua.apply(k,[j].concat(f)):Ya(j,f));2<e.length&&$a(d,j,e);return j};p.createElement=function (a){return this.v.createElement(a)};p.createTextNode=function (a){return this.v.createTextNode(a)};p.qa=function(){return this.v.parentWindow||this.v.defaultView};
+function mb(a){var b=a.v,a="CSS1Compat"==b.compatMode?b.documentElement:b.body,b=b.parentWindow||b.defaultView;return new B(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)}p.appendChild=function (a,b){a.appendChild(b)};p.removeNode=bb;p.contains=G;var H={};H.ya=function(){var a={Oa:"http://www.w3.org/2000/svg"};return function (b){return a[b]||k}}();H.ma=function (a,b,c){var d=D(a);if(!d.implementation.hasFeature("XPath","3.0"))return k;try{var e=d.createNSResolver?d.createNSResolver(d.documentElement):H.ya;return d.evaluate(b,a,e,c,k)}catch(f){"NS_ERROR_ILLEGAL_VALUE"!=f.name&&g(new y(32,"Unable to locate an element with the xpath expression "+b+" because of the following error:\n"+f))}};
+H.ka=function (a,b){(!a||1!=a.nodeType)&&g(new y(32,'The result of the xpath expression "'+b+'" is: '+a+". It should be an element."))};H.Ia=function (a,b){var c=function(){var c=H.ma(b,a,9);return c?c.singleNodeValue||k:b.selectSingleNode?(c=D(b),c.setProperty&&c.setProperty("SelectionLanguage","XPath"),b.selectSingleNode(a)):k}();c===k||H.ka(c,a);return c};
+H.Na=function (a,b){var c=function(){var c=H.ma(b,a,7);if(c){for(var e=c.snapshotLength,f=[],j=0;j<e;++j)f.push(c.snapshotItem(j));return f}return b.selectNodes?(c=D(b),c.setProperty&&c.setProperty("SelectionLanguage","XPath"),b.selectNodes(a)):[]}();La(c,function (b){H.ka(b,a)});return c};var nb,ob="",pb=/Firefox\/([0-9.]+)/.exec(ua());nb=ob=pb?pb[2]||pb[1]:"";var qb=k,rb=function(){var a=q.Components;if(!a)return l;try{if(!a.classes)return l}catch(b){return l}var c=a.classes,a=a.interfaces,d=c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator),e=c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo).version;qb=function (a){return 0<=d.Ka(e,""+a)};return i}();var I="StopIteration"in q?q.StopIteration:Error("StopIteration");function J(){}J.prototype.next=function(){g(I)};J.prototype.r=function(){return this};function sb(a){if(a instanceof J)return a;if("function"==typeof a.r)return a.r(l);if(ba(a)){var b=0,c=new J;c.next=function(){for(;;){b>=a.length&&g(I);if(b in a)return a[b++];b++}};return c}g(Error("Not implemented"))};function K(a,b,c,d,e){this.o=!!b;a&&L(this,a,d);this.depth=e!=h?e:this.q||0;this.o&&(this.depth*=-1);this.za=!c}x(K,J);p=K.prototype;p.p=k;p.q=0;p.ha=l;function L(a,b,c,d){if(a.p=b)a.q="number"==typeof c?c:1!=a.p.nodeType?0:a.o?-1:1;"number"==typeof d&&(a.depth=d)}
 p.next=function(){var a;if(this.ha){(!this.p||this.za&&0==this.depth)&&g(I);a=this.p;var b=this.o?-1:1;if(this.q==b){var c=this.o?a.lastChild:a.firstChild;c?L(this,c):L(this,a,-1*b)}else(c=this.o?a.previousSibling:a.nextSibling)?L(this,c):L(this,a.parentNode,-1*b);this.depth+=this.q*(this.o?-1:1)}else this.ha=i;(a=this.p)||g(I);return a};
-p.splice=function(a){var b=this.p,c=this.o?1:-1;this.q==c&&(this.q=-1*c,this.depth+=this.q*(this.o?-1:1));this.o=!this.o;K.prototype.next.call(this);this.o=!this.o;for(var c=ba(arguments[0])?arguments[0]:arguments,d=c.length-1;0<=d;d--)b.parentNode&&b.parentNode.insertBefore(c[d],b.nextSibling);bb(b)};function tb(a,b,c,d){K.call(this,a,b,c,k,d)}x(tb,K);tb.prototype.next=function(){do tb.$.next.call(this);while(-1==this.q);return this.p};function ub(a,b){var c=D(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,k))?c[b]||c.getPropertyValue(b):""}function vb(a,b){return ub(a,b)||(a.currentStyle?a.currentStyle[b]:k)||a.style&&a.style[b]}
+p.splice=function (a){var b=this.p,c=this.o?1:-1;this.q==c&&(this.q=-1*c,this.depth+=this.q*(this.o?-1:1));this.o=!this.o;K.prototype.next.call(this);this.o=!this.o;for(var c=ba(arguments[0])?arguments[0]:arguments,d=c.length-1;0<=d;d--)b.parentNode&&b.parentNode.insertBefore(c[d],b.nextSibling);bb(b)};function tb(a,b,c,d){K.call(this,a,b,c,k,d)}x(tb,K);tb.prototype.next=function(){do tb.$.next.call(this);while(-1==this.q);return this.p};function ub(a,b){var c=D(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,k))?c[b]||c.getPropertyValue(b):""}function vb(a,b){return ub(a,b)||(a.currentStyle?a.currentStyle[b]:k)||a.style&&a.style[b]}
 function wb(a){for(var b=D(a),c=vb(a,"position"),d="fixed"==c||"absolute"==c,a=a.parentNode;a&&a!=b;a=a.parentNode)if(c=vb(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return k}
 function xb(a){var b=new B;if(1==a.nodeType)if(a.getBoundingClientRect)a=a.getBoundingClientRect(),b.x=a.left,b.y=a.top;else{var c=mb(Wa(a));var d,e=D(a),f=vb(a,"position"),j=e.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==f&&(d=e.getBoxObjectFor(a))&&(0>d.screenX||0>d.screenY),f=new B(0,0),m=(e?9==e.nodeType?e:D(e):document).documentElement;if(a!=m)if(a.getBoundingClientRect)d=a.getBoundingClientRect(),a=mb(Wa(e)),f.x=d.left+a.x,f.y=d.top+a.y;else if(e.getBoxObjectFor&&!j)d=e.getBoxObjectFor(a),
 a=e.getBoxObjectFor(m),f.x=d.screenX-a.screenX,f.y=d.screenY-a.screenY;else{d=a;do f.x+=d.offsetLeft,f.y+=d.offsetTop,d!=a&&(f.x+=d.clientLeft||0,f.y+=d.clientTop||0),d=d.offsetParent;while(d&&d!=a);for(d=a;(d=wb(d))&&d!=e.body&&d!=m;)f.x-=d.scrollLeft,f.y-=d.scrollTop}b.x=f.x-c.x;b.y=f.y-c.y}else c=w(a.pa),d=a,a.targetTouches?d=a.targetTouches[0]:c&&a.pa().targetTouches&&(d=a.pa().targetTouches[0]),b.x=d.clientX,b.y=d.clientY;return b}
 function yb(a){var b=a.offsetWidth,c=a.offsetHeight;return!r(b)&&a.getBoundingClientRect?(a=a.getBoundingClientRect(),new Va(a.right-a.left,a.bottom-a.top)):new Va(b,c)};function M(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}var zb={"class":"className",readonly:"readOnly"},Ab=["checked","disabled","draggable","hidden"];function Bb(a,b){var c=zb[b]||b,d=a[c];if(!r(d)&&0<=A(Ab,c))return l;if(c="value"==b)if(c=M(a,"OPTION")){var e;c=b.toLowerCase();if(a.hasAttribute)e=a.hasAttribute(c);else try{e=a.attributes[c].specified}catch(f){e=l}c=!e}c&&(d=[],kb(a,d,l),d=d.join(""));return d}
 var Cb="async,autofocus,autoplay,checked,compact,complete,controls,declare,defaultchecked,defaultselected,defer,disabled,draggable,ended,formnovalidate,hidden,indeterminate,iscontenteditable,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,paused,pubdate,readonly,required,reversed,scoped,seamless,seeking,selected,spellcheck,truespeed,willvalidate".split(","),Db="BUTTON,INPUT,OPTGROUP,OPTION,SELECT,TEXTAREA".split(",");
 function Eb(a){var b=a.tagName.toUpperCase();return!(0<=A(Db,b))?i:Bb(a,"disabled")?l:a.parentNode&&1==a.parentNode.nodeType&&"OPTGROUP"==b||"OPTION"==b?Eb(a.parentNode):i}var Fb="text,search,tel,url,email,password,number".split(",");function Gb(a){return M(a,"TEXTAREA")?i:M(a,"INPUT")?0<=A(Fb,a.type.toLowerCase()):Hb(a)?i:l}
 function Hb(a){function b(a){return"inherit"==a.contentEditable?(a=Ib(a))?b(a):l:"true"==a.contentEditable}return!r(a.contentEditable)?l:r(a.isContentEditable)?a.isContentEditable:b(a)}function Ib(a){for(a=a.parentNode;a&&1!=a.nodeType&&9!=a.nodeType&&11!=a.nodeType;)a=a.parentNode;return M(a)?a:k}function Jb(a,b){b=ra(b);return ub(a,b)||Kb(a,b)}
 function Kb(a,b){var c=a.currentStyle||a.style,d=c[b];!r(d)&&w(c.getPropertyValue)&&(d=c.getPropertyValue(b));return"inherit"!=d?r(d)?d:k:(c=Ib(a))?Kb(c,b):k}function Lb(a){if(w(a.getBBox))try{var b=a.getBBox();if(b)return b}catch(c){}if("none"!=vb(a,"display"))a=yb(a);else{var b=a.style,d=b.display,e=b.visibility,f=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=yb(a);b.display=d;b.position=f;b.visibility=e}return a}
-function Mb(a,b){function c(a){if("none"==Jb(a,"display"))return l;a=Ib(a);return!a||c(a)}function d(a){var b=Lb(a);return 0<b.height&&0<b.width?i:Na(a.childNodes,function(a){return a.nodeType==C||M(a)&&d(a)})}function e(a){var b=Ib(a);if(b&&"hidden"==Jb(b,"overflow")){var c=Lb(b),d=xb(b),a=xb(a);return d.x+c.width<a.x||d.y+c.height<a.y?l:e(b)}return i}M(a)||g(Error("Argument to isShown must be of type Element"));if(M(a,"OPTION")||M(a,"OPTGROUP")){var f=lb(a,function(a){return M(a,"SELECT")});return!!f&&
-Mb(f,i)}if(M(a,"MAP")){if(!a.name)return l;f=D(a);f=f.evaluate?H.Ia('/descendant::*[@usemap = "#'+a.name+'"]',f):gb(f,function(b){var c;if(c=M(b))8==b.nodeType?b=k:(c="usemap","style"==c?(b=ha(b.style.cssText).toLowerCase(),b=";"==b.charAt(b.length-1)?b:b+";"):(b=b.getAttributeNode(c),b=!b?k:0<=A(Cb,c)?"true":b.specified?b.value:k)),c=b=="#"+a.name;return c});return!!f&&Mb(f,b)}return M(a,"AREA")?(f=lb(a,function(a){return M(a,"MAP")}),!!f&&Mb(f,b)):M(a,"INPUT")&&"hidden"==a.type.toLowerCase()||M(a,
-"NOSCRIPT")||"hidden"==Jb(a,"visibility")||!c(a)||!b&&0==Nb(a)||!d(a)||!e(a)?l:i}function Nb(a){var b=1,c=Jb(a,"opacity");c&&(b=Number(c));(a=Ib(a))&&(b*=Nb(a));return b};function N(){this.w=Ca.document.documentElement;this.ua=k;var a=D(this.w).activeElement;a&&Ob(this,a)}N.prototype.z=n("w");function Ob(a,b){a.w=b;a.ua=M(b,"OPTION")?lb(b,function(a){return M(a,"SELECT")}):k}
-function Pb(a,b,c,d,e,f){function j(a,c){var d={identifier:a,screenX:c.x,screenY:c.y,clientX:c.x,clientY:c.y,pageX:c.x,pageY:c.y};m.changedTouches.push(d);if(b==Qb||b==Rb)m.touches.push(d),m.targetTouches.push(d)}var m={touches:[],targetTouches:[],changedTouches:[],altKey:l,ctrlKey:l,shiftKey:l,metaKey:l,relatedTarget:k,scale:0,rotation:0};j(c,d);r(e)&&j(e,f);Sb(a.w,b,m)}rb&&rb&&(rb?qb(4):oa(nb,4));rb&&(rb?qb(4):oa(nb,4));function P(a,b,c){this.J=a;this.S=b;this.T=c}P.prototype.create=function(a){a=D(a).createEvent("HTMLEvents");a.initEvent(this.J,this.S,this.T);return a};P.prototype.toString=n("J");function Q(a,b,c){P.call(this,a,b,c)}x(Q,P);
-Q.prototype.create=function(a,b){var c=D(a),d=F(c),c=c.createEvent("MouseEvents"),e=1;this==Tb&&(e=b.wheelDelta/-40);this==Ub&&(e=b.wheelDelta);c.initMouseEvent(this.J,this.S,this.T,d,e,0,0,b.clientX,b.clientY,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,b.button,b.relatedTarget);return c};function Vb(a,b,c){P.call(this,a,b,c)}x(Vb,P);
-Vb.prototype.create=function(a,b){var c=D(a),d=F(c),e=b.charCode?0:b.keyCode,c=c.createEvent("KeyboardEvent");c.initKeyEvent(this.J,this.S,this.T,d,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,e,b.charCode);this.J==Wb&&b.preventDefault&&c.preventDefault();return c};function Xb(a,b,c){P.call(this,a,b,c)}x(Xb,P);
-Xb.prototype.create=function(a,b){function c(b){var c=Ma(b,function(b){return{identifier:b.identifier,screenX:b.screenX,screenY:b.screenY,clientX:b.clientX,clientY:b.clientY,pageX:b.pageX,pageY:b.pageY,target:a}});c.item=function(a){return c[a]};return c}var d=D(a),e=F(d),f=c(b.changedTouches),j=b.touches==b.changedTouches?f:c(b.touches),m=b.targetTouches==b.changedTouches?f:c(b.targetTouches),d=d.createEvent("MouseEvents");d.initMouseEvent(this.J,this.S,this.T,e,1,0,0,b.clientX,b.clientY,b.ctrlKey,
+function Mb(a,b){function c(a){if("none"==Jb(a,"display"))return l;a=Ib(a);return!a||c(a)}function d(a){var b=Lb(a);return 0<b.height&&0<b.width?i:Na(a.childNodes,function (a){return a.nodeType==C||M(a)&&d(a)})}function e(a){var b=Ib(a);if(b&&"hidden"==Jb(b,"overflow")){var c=Lb(b),d=xb(b),a=xb(a);return d.x+c.width<a.x||d.y+c.height<a.y?l:e(b)}return i}M(a)||g(Error("Argument to isShown must be of type Element"));if(M(a,"OPTION")||M(a,"OPTGROUP")){var f=lb(a,function (a){return M(a,"SELECT")});return!!f&&
+Mb(f,i)}if(M(a,"MAP")){if(!a.name)return l;f=D(a);f=f.evaluate?H.Ia('/descendant::*[@usemap = "#'+a.name+'"]',f):gb(f,function (b){var c;if(c=M(b))8==b.nodeType?b=k:(c="usemap","style"==c?(b=ha(b.style.cssText).toLowerCase(),b=";"==b.charAt(b.length-1)?b:b+";"):(b=b.getAttributeNode(c),b=!b?k:0<=A(Cb,c)?"true":b.specified?b.value:k)),c=b=="#"+a.name;return c});return!!f&&Mb(f,b)}return M(a,"AREA")?(f=lb(a,function (a){return M(a,"MAP")}),!!f&&Mb(f,b)):M(a,"INPUT")&&"hidden"==a.type.toLowerCase()||M(a,
+"NOSCRIPT")||"hidden"==Jb(a,"visibility")||!c(a)||!b&&0==Nb(a)||!d(a)||!e(a)?l:i}function Nb(a){var b=1,c=Jb(a,"opacity");c&&(b=Number(c));(a=Ib(a))&&(b*=Nb(a));return b};function N(){this.w=Ca.document.documentElement;this.ua=k;var a=D(this.w).activeElement;a&&Ob(this,a)}N.prototype.z=n("w");function Ob(a,b){a.w=b;a.ua=M(b,"OPTION")?lb(b,function (a){return M(a,"SELECT")}):k}
+function Pb(a,b,c,d,e,f){function j(a,c){var d={identifier:a,screenX:c.x,screenY:c.y,clientX:c.x,clientY:c.y,pageX:c.x,pageY:c.y};m.changedTouches.push(d);if(b==Qb||b==Rb)m.touches.push(d),m.targetTouches.push(d)}var m={touches:[],targetTouches:[],changedTouches:[],altKey:l,ctrlKey:l,shiftKey:l,metaKey:l,relatedTarget:k,scale:0,rotation:0};j(c,d);r(e)&&j(e,f);Sb(a.w,b,m)}rb&&rb&&(rb?qb(4):oa(nb,4));rb&&(rb?qb(4):oa(nb,4));function P(a,b,c){this.J=a;this.S=b;this.T=c}P.prototype.create=function (a){a=D(a).createEvent("HTMLEvents");a.initEvent(this.J,this.S,this.T);return a};P.prototype.toString=n("J");function Q(a,b,c){P.call(this,a,b,c)}x(Q,P);
+Q.prototype.create=function (a,b){var c=D(a),d=F(c),c=c.createEvent("MouseEvents"),e=1;this==Tb&&(e=b.wheelDelta/-40);this==Ub&&(e=b.wheelDelta);c.initMouseEvent(this.J,this.S,this.T,d,e,0,0,b.clientX,b.clientY,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,b.button,b.relatedTarget);return c};function Vb(a,b,c){P.call(this,a,b,c)}x(Vb,P);
+Vb.prototype.create=function (a,b){var c=D(a),d=F(c),e=b.charCode?0:b.keyCode,c=c.createEvent("KeyboardEvent");c.initKeyEvent(this.J,this.S,this.T,d,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,e,b.charCode);this.J==Wb&&b.preventDefault&&c.preventDefault();return c};function Xb(a,b,c){P.call(this,a,b,c)}x(Xb,P);
+Xb.prototype.create=function (a,b){function c(b){var c=Ma(b,function (b){return{identifier:b.identifier,screenX:b.screenX,screenY:b.screenY,clientX:b.clientX,clientY:b.clientY,pageX:b.pageX,pageY:b.pageY,target:a}});c.item=function (a){return c[a]};return c}var d=D(a),e=F(d),f=c(b.changedTouches),j=b.touches==b.changedTouches?f:c(b.touches),m=b.targetTouches==b.changedTouches?f:c(b.targetTouches),d=d.createEvent("MouseEvents");d.initMouseEvent(this.J,this.S,this.T,e,1,0,0,b.clientX,b.clientY,b.ctrlKey,
 b.altKey,b.shiftKey,b.metaKey,0,b.relatedTarget);d.touches=j;d.targetTouches=m;d.changedTouches=f;d.scale=b.scale;d.rotation=b.rotation;return d};
 var Yb=new P("change",i,l),Zb=new Q("click",i,i),$b=new Q("contextmenu",i,i),ac=new Q("dblclick",i,i),bc=new Q("mousedown",i,i),cc=new Q("mousemove",i,l),dc=new Q("mouseout",i,i),ec=new Q("mouseover",i,i),fc=new Q("mouseup",i,i),Tb=new Q("DOMMouseScroll",i,i),Ub=new Q("MozMousePixelScroll",i,i),Wb=new Vb("keypress",i,i),Rb=new Xb("touchmove",i,i),Qb=new Xb("touchstart",i,i);function Sb(a,b,c){b=b.create(a,c);"isTrusted"in b||(b.La=l);a.dispatchEvent(b)};function gc(a){if("function"==typeof a.L)return a.L();if(t(a))return a.split("");if(ba(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return Ea(a)};function hc(a,b){this.n={};this.ta={};var c=arguments.length;if(1<c){c%2&&g(Error("Uneven number of arguments"));for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else a&&this.aa(a)}p=hc.prototype;p.ia=0;p.L=function(){var a=[],b;for(b in this.n)":"==b.charAt(0)&&a.push(this.n[b]);return a};function ic(a){var b=[],c;for(c in a.n)if(":"==c.charAt(0)){var d=c.substring(1);b.push(a.ta[c]?Number(d):d)}return b}
-p.set=function(a,b){var c=":"+a;c in this.n||(this.ia++,"number"==typeof a&&(this.ta[c]=i));this.n[c]=b};p.aa=function(a){var b;if(a instanceof hc)b=ic(a),a=a.L();else{b=[];var c=0,d;for(d in a)b[c++]=d;a=Ea(a)}for(c=0;c<b.length;c++)this.set(b[c],a[c])};p.r=function(a){var b=0,c=ic(this),d=this.n,e=this.ia,f=this,j=new J;j.next=function(){for(;;){e!=f.ia&&g(Error("The map has changed since the iterator was created"));b>=c.length&&g(I);var j=c[b++];return a?j:d[":"+j]}};return j};function jc(a){this.n=new hc;a&&this.aa(a)}function kc(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+(a[da]||(a[da]=++ea)):b.substr(0,1)+a}p=jc.prototype;p.add=function(a){this.n.set(kc(a),a)};p.aa=function(a){for(var a=gc(a),b=a.length,c=0;c<b;c++)this.add(a[c])};p.contains=function(a){return":"+kc(a)in this.n.n};p.L=function(){return this.n.L()};p.r=function(){return this.n.r(l)};function lc(){N.call(this);Gb(this.z())&&Bb(this.z(),"readOnly");this.Ha=new jc}x(lc,N);var mc={};function R(a,b,c){ca(a)&&(a=a.c);a=new nc(a);if(b&&(!(b in mc)||c))mc[b]={key:a,shift:l},c&&(mc[c]={key:a,shift:i})}function nc(a){this.code=a}R(8);R(9);R(13);R(16);R(17);R(18);R(19);R(20);R(27);R(32," ");R(33);R(34);R(35);R(36);R(37);R(38);R(39);R(40);R(44);R(45);R(46);R(48,"0",")");R(49,"1","!");R(50,"2","@");R(51,"3","#");R(52,"4","$");R(53,"5","%");R(54,"6","^");R(55,"7","&");R(56,"8","*");
+p.set=function (a,b){var c=":"+a;c in this.n||(this.ia++,"number"==typeof a&&(this.ta[c]=i));this.n[c]=b};p.aa=function (a){var b;if(a instanceof hc)b=ic(a),a=a.L();else{b=[];var c=0,d;for(d in a)b[c++]=d;a=Ea(a)}for(c=0;c<b.length;c++)this.set(b[c],a[c])};p.r=function (a){var b=0,c=ic(this),d=this.n,e=this.ia,f=this,j=new J;j.next=function(){for(;;){e!=f.ia&&g(Error("The map has changed since the iterator was created"));b>=c.length&&g(I);var j=c[b++];return a?j:d[":"+j]}};return j};function jc(a){this.n=new hc;a&&this.aa(a)}function kc(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+(a[da]||(a[da]=++ea)):b.substr(0,1)+a}p=jc.prototype;p.add=function (a){this.n.set(kc(a),a)};p.aa=function (a){for(var a=gc(a),b=a.length,c=0;c<b;c++)this.add(a[c])};p.contains=function (a){return":"+kc(a)in this.n.n};p.L=function(){return this.n.L()};p.r=function(){return this.n.r(l)};function lc(){N.call(this);Gb(this.z())&&Bb(this.z(),"readOnly");this.Ha=new jc}x(lc,N);var mc={};function R(a,b,c){ca(a)&&(a=a.c);a=new nc(a);if(b&&(!(b in mc)||c))mc[b]={key:a,shift:l},c&&(mc[c]={key:a,shift:i})}function nc(a){this.code=a}R(8);R(9);R(13);R(16);R(17);R(18);R(19);R(20);R(27);R(32," ");R(33);R(34);R(35);R(36);R(37);R(38);R(39);R(40);R(44);R(45);R(46);R(48,"0",")");R(49,"1","!");R(50,"2","@");R(51,"3","#");R(52,"4","$");R(53,"5","%");R(54,"6","^");R(55,"7","&");R(56,"8","*");
 R(57,"9","(");R(65,"a","A");R(66,"b","B");R(67,"c","C");R(68,"d","D");R(69,"e","E");R(70,"f","F");R(71,"g","G");R(72,"h","H");R(73,"i","I");R(74,"j","J");R(75,"k","K");R(76,"l","L");R(77,"m","M");R(78,"n","N");R(79,"o","O");R(80,"p","P");R(81,"q","Q");R(82,"r","R");R(83,"s","S");R(84,"t","T");R(85,"u","U");R(86,"v","V");R(87,"w","W");R(88,"x","X");R(89,"y","Y");R(90,"z","Z");R(ta?{c:91,e:91,opera:219}:sa?{c:224,e:91,opera:17}:{c:0,e:91,opera:k});
 R(ta?{c:92,e:92,opera:220}:sa?{c:224,e:93,opera:17}:{c:0,e:92,opera:k});R(ta?{c:93,e:93,opera:0}:sa?{c:0,e:0,opera:16}:{c:93,e:k,opera:0});R({c:96,e:96,opera:48},"0");R({c:97,e:97,opera:49},"1");R({c:98,e:98,opera:50},"2");R({c:99,e:99,opera:51},"3");R({c:100,e:100,opera:52},"4");R({c:101,e:101,opera:53},"5");R({c:102,e:102,opera:54},"6");R({c:103,e:103,opera:55},"7");R({c:104,e:104,opera:56},"8");R({c:105,e:105,opera:57},"9");R({c:106,e:106,opera:xa?56:42},"*");R({c:107,e:107,opera:xa?61:43},"+");
-R({c:109,e:109,opera:xa?109:45},"-");R({c:110,e:110,opera:xa?190:78},".");R({c:111,e:111,opera:xa?191:47},"/");R(144);R(112);R(113);R(114);R(115);R(116);R(117);R(118);R(119);R(120);R(121);R(122);R(123);R({c:107,e:187,opera:61},"=","+");R({c:109,e:189,opera:109},"-","_");R(188,",","<");R(190,".",">");R(191,"/","?");R(192,"`","~");R(219,"[","{");R(220,"\\","|");R(221,"]","}");R({c:59,e:186,opera:59},";",":");R(222,"'",'"');lc.prototype.X=function(a){return this.Ha.contains(a)};function oc(a){return pc(a||arguments.callee.caller,[])}
+R({c:109,e:109,opera:xa?109:45},"-");R({c:110,e:110,opera:xa?190:78},".");R({c:111,e:111,opera:xa?191:47},"/");R(144);R(112);R(113);R(114);R(115);R(116);R(117);R(118);R(119);R(120);R(121);R(122);R(123);R({c:107,e:187,opera:61},"=","+");R({c:109,e:189,opera:109},"-","_");R(188,",","<");R(190,".",">");R(191,"/","?");R(192,"`","~");R(219,"[","{");R(220,"\\","|");R(221,"]","}");R({c:59,e:186,opera:59},";",":");R(222,"'",'"');lc.prototype.X=function (a){return this.Ha.contains(a)};function oc(a){return pc(a||arguments.callee.caller,[])}
 function pc(a,b){var c=[];if(0<=A(b,a))c.push("[...circular reference...]");else if(a&&50>b.length){c.push(qc(a)+"(");for(var d=a.arguments,e=0;e<d.length;e++){0<e&&c.push(", ");var f;f=d[e];switch(typeof f){case "object":f=f?"object":"null";break;case "string":break;case "number":f=""+f;break;case "boolean":f=f?"true":"false";break;case "function":f=(f=qc(f))?f:"[fn]";break;default:f=typeof f}40<f.length&&(f=f.substr(0,40)+"...");c.push(f)}b.push(a);c.push(")\n");try{c.push(pc(a.caller,b))}catch(j){c.push("[exception trying to get caller]\n")}}else a?
-c.push("[...long stack...]"):c.push("[end]");return c.join("")}function qc(a){if(rc[a])return rc[a];a=""+a;if(!rc[a]){var b=/function ([^\(]+)/.exec(a);rc[a]=b?b[1]:"[Anonymous]"}return rc[a]}var rc={};function sc(a,b,c,d,e){this.reset(a,b,c,d,e)}sc.prototype.oa=k;sc.prototype.na=k;var tc=0;sc.prototype.reset=function(a,b,c,d,e){"number"==typeof e||tc++;d||fa();this.N=a;this.Fa=b;delete this.oa;delete this.na};sc.prototype.va=function(a){this.N=a};function S(a){this.Ga=a}S.prototype.Y=k;S.prototype.N=k;S.prototype.ba=k;S.prototype.ra=k;function uc(a,b){this.name=a;this.value=b}uc.prototype.toString=n("name");var vc=new uc("WARNING",900),wc=new uc("CONFIG",700);S.prototype.getParent=n("Y");S.prototype.va=function(a){this.N=a};function xc(a){if(a.N)return a.N;if(a.Y)return xc(a.Y);Ja("Root logger has no level set.");return k}
-S.prototype.log=function(a,b,c){if(a.value>=xc(this).value){a=this.Ca(a,b,c);b="log:"+a.Fa;q.console&&(q.console.timeStamp?q.console.timeStamp(b):q.console.markTimeline&&q.console.markTimeline(b));q.msWriteProfilerMark&&q.msWriteProfilerMark(b);for(b=this;b;){var c=b,d=a;if(c.ra)for(var e=0,f=h;f=c.ra[e];e++)f(d);b=b.getParent()}}};
-S.prototype.Ca=function(a,b,c){var d=new sc(a,""+b,this.Ga);if(c){d.oa=c;var e;var f=arguments.callee.caller;try{var j;var m;c:{for(var s=["window","location","href"],O=q,E;E=s.shift();)if(O[E]!=k)O=O[E];else{m=k;break c}m=O}if(t(c))j={message:c,name:"Unknown error",lineNumber:"Not available",fileName:m,stack:"Not available"};else{var u,v,s=l;try{u=c.lineNumber||c.Ma||"Not available"}catch(md){u="Not available",s=i}try{v=c.fileName||c.filename||c.sourceURL||m}catch(nd){v="Not available",s=i}j=s||
+c.push("[...long stack...]"):c.push("[end]");return c.join("")}function qc(a){if(rc[a])return rc[a];a=""+a;if(!rc[a]){var b=/function ([^\(]+)/.exec(a);rc[a]=b?b[1]:"[Anonymous]"}return rc[a]}var rc={};function sc(a,b,c,d,e){this.reset(a,b,c,d,e)}sc.prototype.oa=k;sc.prototype.na=k;var tc=0;sc.prototype.reset=function (a,b,c,d,e){"number"==typeof e||tc++;d||fa();this.N=a;this.Fa=b;delete this.oa;delete this.na};sc.prototype.va=function (a){this.N=a};function S(a){this.Ga=a}S.prototype.Y=k;S.prototype.N=k;S.prototype.ba=k;S.prototype.ra=k;function uc(a,b){this.name=a;this.value=b}uc.prototype.toString=n("name");var vc=new uc("WARNING",900),wc=new uc("CONFIG",700);S.prototype.getParent=n("Y");S.prototype.va=function (a){this.N=a};function xc(a){if(a.N)return a.N;if(a.Y)return xc(a.Y);Ja("Root logger has no level set.");return k}
+S.prototype.log=function (a,b,c){if(a.value>=xc(this).value){a=this.Ca(a,b,c);b="log:"+a.Fa;q.console&&(q.console.timeStamp?q.console.timeStamp(b):q.console.markTimeline&&q.console.markTimeline(b));q.msWriteProfilerMark&&q.msWriteProfilerMark(b);for(b=this;b;){var c=b,d=a;if(c.ra)for(var e=0,f=h;f=c.ra[e];e++)f(d);b=b.getParent()}}};
+S.prototype.Ca=function (a,b,c){var d=new sc(a,""+b,this.Ga);if(c){d.oa=c;var e;var f=arguments.callee.caller;try{var j;var m;c:{for(var s=["window","location","href"],O=q,E;E=s.shift();)if(O[E]!=k)O=O[E];else{m=k;break c}m=O}if(t(c))j={message:c,name:"Unknown error",lineNumber:"Not available",fileName:m,stack:"Not available"};else{var u,v,s=l;try{u=c.lineNumber||c.Ma||"Not available"}catch(md){u="Not available",s=i}try{v=c.fileName||c.filename||c.sourceURL||m}catch(nd){v="Not available",s=i}j=s||
 !c.lineNumber||!c.fileName||!c.stack?{message:c.message,name:c.name,lineNumber:u,fileName:v,stack:c.stack||"Not available"}:c}e="Message: "+ia(j.message)+'\nUrl: <a href="view-source:'+j.fileName+'" target="_new">'+j.fileName+"</a>\nLine: "+j.lineNumber+"\n\nBrowser stack:\n"+ia(j.stack+"-> ")+"[end]\n\nJS stack traversal:\n"+ia(oc(f)+"-> ")}catch(kd){e="Exception trying to expose exception! You win, we lose. "+kd}d.na=e}return d};var yc={},zc=k;
-function Ac(a){zc||(zc=new S(""),yc[""]=zc,zc.va(wc));var b;if(!(b=yc[a])){b=new S(a);var c=a.lastIndexOf("."),d=a.substr(c+1),c=Ac(a.substr(0,c));c.ba||(c.ba={});c.ba[d]=b;b.Y=c;yc[a]=b}return b};function Bc(){}x(Bc,function(){});Ac("goog.dom.SavedRange");x(function(a){this.Ja="goog_"+pa++;this.Aa="goog_"+pa++;this.la=Wa(a.ea());a.R(this.la.da("SPAN",{id:this.Ja}),this.la.da("SPAN",{id:this.Aa}))},Bc);function T(){}function Cc(a){if(a.getSelection)return a.getSelection();var a=a.document,b=a.selection;if(b){try{var c=b.createRange();if(c.parentElement){if(c.parentElement().document!=a)return k}else if(!c.length||c.item(0).document!=a)return k}catch(d){return k}return b}return k}function Dc(a){for(var b=[],c=0,d=a.D();c<d;c++)b.push(a.A(c));return b}T.prototype.F=o(l);T.prototype.ea=function(){return D(this.b())};T.prototype.qa=function(){return F(this.ea())};
-T.prototype.containsNode=function(a,b){return this.u(Ec(Fc(a),h),b)};function U(a,b){K.call(this,a,b,i)}x(U,K);function V(){}x(V,T);V.prototype.u=function(a,b){var c=Dc(this),d=Dc(a);return(b?Na:Oa)(d,function(a){return Na(c,function(c){return c.u(a,b)})})};V.prototype.insertNode=function(a,b){if(b){var c=this.b();c.parentNode&&c.parentNode.insertBefore(a,c)}else c=this.g(),c.parentNode&&c.parentNode.insertBefore(a,c.nextSibling);return a};V.prototype.R=function(a,b){this.insertNode(a,i);this.insertNode(b,l)};function Gc(a,b,c,d,e){var f;if(a&&(this.f=a,this.i=b,this.d=c,this.h=d,1==a.nodeType&&"BR"!=a.tagName&&(a=a.childNodes,(b=a[b])?(this.f=b,this.i=0):(a.length&&(this.f=z(a)),f=i)),1==c.nodeType))(this.d=c.childNodes[d])?this.h=0:this.d=c;U.call(this,e?this.d:this.f,e);if(f)try{this.next()}catch(j){j!=I&&g(j)}}x(Gc,U);p=Gc.prototype;p.f=k;p.d=k;p.i=0;p.h=0;p.b=n("f");p.g=n("d");p.M=function(){return this.ha&&this.p==this.d&&(!this.h||1!=this.q)};p.next=function(){this.M()&&g(I);return Gc.$.next.call(this)};"ScriptEngine"in q&&"JScript"==q.ScriptEngine()&&(q.ScriptEngineMajorVersion(),q.ScriptEngineMinorVersion(),q.ScriptEngineBuildVersion());function Hc(){}Hc.prototype.u=function(a,b){var c=b&&!a.isCollapsed(),d=a.a;try{return c?0<=this.l(d,0,1)&&0>=this.l(d,1,0):0<=this.l(d,0,0)&&0>=this.l(d,1,1)}catch(e){g(e)}};Hc.prototype.containsNode=function(a,b){return this.u(Fc(a),b)};Hc.prototype.r=function(){return new Gc(this.b(),this.j(),this.g(),this.k())};function Ic(a){this.a=a}x(Ic,Hc);p=Ic.prototype;p.C=function(){return this.a.commonAncestorContainer};p.b=function(){return this.a.startContainer};p.j=function(){return this.a.startOffset};p.g=function(){return this.a.endContainer};p.k=function(){return this.a.endOffset};p.l=function(a,b,c){return this.a.compareBoundaryPoints(1==c?1==b?q.Range.START_TO_START:q.Range.START_TO_END:1==b?q.Range.END_TO_START:q.Range.END_TO_END,a)};p.isCollapsed=function(){return this.a.collapsed};
-p.select=function(a){this.Z(F(D(this.b())).getSelection(),a)};p.Z=function(a){a.removeAllRanges();a.addRange(this.a)};p.insertNode=function(a,b){var c=this.a.cloneRange();c.collapse(b);c.insertNode(a);c.detach();return a};
-p.R=function(a,b){var c=F(D(this.b()));if(c=(c=Cc(c||window))&&Jc(c))var d=c.b(),e=c.g(),f=c.j(),j=c.k();var m=this.a.cloneRange(),s=this.a.cloneRange();m.collapse(l);s.collapse(i);m.insertNode(b);s.insertNode(a);m.detach();s.detach();if(c){if(d.nodeType==C)for(;f>d.length;){f-=d.length;do d=d.nextSibling;while(d==a||d==b)}if(e.nodeType==C)for(;j>e.length;){j-=e.length;do e=e.nextSibling;while(e==a||e==b)}c=new Kc;c.G=Lc(d,f,e,j);"BR"==d.tagName&&(m=d.parentNode,f=A(m.childNodes,d),d=m);"BR"==e.tagName&&
-(m=e.parentNode,j=A(m.childNodes,e),e=m);c.G?(c.f=e,c.i=j,c.d=d,c.h=f):(c.f=d,c.i=f,c.d=e,c.h=j);c.select()}};p.collapse=function(a){this.a.collapse(a)};function W(a){this.a=a}x(W,Ic);function Fc(a){var b=D(a).createRange();if(a.nodeType==C)b.setStart(a,0),b.setEnd(a,a.length);else if(X(a)){for(var c,d=a;(c=d.firstChild)&&X(c);)d=c;b.setStart(d,0);for(d=a;(c=d.lastChild)&&X(c);)d=c;b.setEnd(d,1==d.nodeType?d.childNodes.length:d.length)}else c=a.parentNode,a=A(c.childNodes,a),b.setStart(c,a),b.setEnd(c,a+1);return new W(b)}
-W.prototype.Z=function(a,b){var c=b?this.g():this.b(),d=b?this.k():this.j(),e=b?this.b():this.g(),f=b?this.j():this.k();a.collapse(c,d);(c!=e||d!=f)&&a.extend(e,f)};function Mc(a){this.a=a}x(Mc,Hc);Ac("goog.dom.browserrange.IeRange");function Nc(a){var b=D(a).body.createTextRange();if(1==a.nodeType)b.moveToElementText(a),X(a)&&!a.childNodes.length&&b.collapse(l);else{for(var c=0,d=a;d=d.previousSibling;){var e=d.nodeType;if(e==C)c+=d.length;else if(1==e){b.moveToElementText(d);break}}d||b.moveToElementText(a.parentNode);b.collapse(!d);c&&b.move("character",c);b.moveEnd("character",a.length)}return b}p=Mc.prototype;p.O=k;p.f=k;p.d=k;p.i=-1;p.h=-1;
+function Ac(a){zc||(zc=new S(""),yc[""]=zc,zc.va(wc));var b;if(!(b=yc[a])){b=new S(a);var c=a.lastIndexOf("."),d=a.substr(c+1),c=Ac(a.substr(0,c));c.ba||(c.ba={});c.ba[d]=b;b.Y=c;yc[a]=b}return b};function Bc(){}x(Bc,function(){});Ac("goog.dom.SavedRange");x(function (a){this.Ja="goog_"+pa++;this.Aa="goog_"+pa++;this.la=Wa(a.ea());a.R(this.la.da("SPAN",{id:this.Ja}),this.la.da("SPAN",{id:this.Aa}))},Bc);function T(){}function Cc(a){if(a.getSelection)return a.getSelection();var a=a.document,b=a.selection;if(b){try{var c=b.createRange();if(c.parentElement){if(c.parentElement().document!=a)return k}else if(!c.length||c.item(0).document!=a)return k}catch(d){return k}return b}return k}function Dc(a){for(var b=[],c=0,d=a.D();c<d;c++)b.push(a.A(c));return b}T.prototype.F=o(l);T.prototype.ea=function(){return D(this.b())};T.prototype.qa=function(){return F(this.ea())};
+T.prototype.containsNode=function (a,b){return this.u(Ec(Fc(a),h),b)};function U(a,b){K.call(this,a,b,i)}x(U,K);function V(){}x(V,T);V.prototype.u=function (a,b){var c=Dc(this),d=Dc(a);return(b?Na:Oa)(d,function (a){return Na(c,function (c){return c.u(a,b)})})};V.prototype.insertNode=function (a,b){if(b){var c=this.b();c.parentNode&&c.parentNode.insertBefore(a,c)}else c=this.g(),c.parentNode&&c.parentNode.insertBefore(a,c.nextSibling);return a};V.prototype.R=function (a,b){this.insertNode(a,i);this.insertNode(b,l)};function Gc(a,b,c,d,e){var f;if(a&&(this.f=a,this.i=b,this.d=c,this.h=d,1==a.nodeType&&"BR"!=a.tagName&&(a=a.childNodes,(b=a[b])?(this.f=b,this.i=0):(a.length&&(this.f=z(a)),f=i)),1==c.nodeType))(this.d=c.childNodes[d])?this.h=0:this.d=c;U.call(this,e?this.d:this.f,e);if(f)try{this.next()}catch(j){j!=I&&g(j)}}x(Gc,U);p=Gc.prototype;p.f=k;p.d=k;p.i=0;p.h=0;p.b=n("f");p.g=n("d");p.M=function(){return this.ha&&this.p==this.d&&(!this.h||1!=this.q)};p.next=function(){this.M()&&g(I);return Gc.$.next.call(this)};"ScriptEngine"in q&&"JScript"==q.ScriptEngine()&&(q.ScriptEngineMajorVersion(),q.ScriptEngineMinorVersion(),q.ScriptEngineBuildVersion());function Hc(){}Hc.prototype.u=function (a,b){var c=b&&!a.isCollapsed(),d=a.a;try{return c?0<=this.l(d,0,1)&&0>=this.l(d,1,0):0<=this.l(d,0,0)&&0>=this.l(d,1,1)}catch(e){g(e)}};Hc.prototype.containsNode=function (a,b){return this.u(Fc(a),b)};Hc.prototype.r=function(){return new Gc(this.b(),this.j(),this.g(),this.k())};function Ic(a){this.a=a}x(Ic,Hc);p=Ic.prototype;p.C=function(){return this.a.commonAncestorContainer};p.b=function(){return this.a.startContainer};p.j=function(){return this.a.startOffset};p.g=function(){return this.a.endContainer};p.k=function(){return this.a.endOffset};p.l=function (a,b,c){return this.a.compareBoundaryPoints(1==c?1==b?q.Range.START_TO_START:q.Range.START_TO_END:1==b?q.Range.END_TO_START:q.Range.END_TO_END,a)};p.isCollapsed=function(){return this.a.collapsed};
+p.select=function (a){this.Z(F(D(this.b())).getSelection(),a)};p.Z=function (a){a.removeAllRanges();a.addRange(this.a)};p.insertNode=function (a,b){var c=this.a.cloneRange();c.collapse(b);c.insertNode(a);c.detach();return a};
+p.R=function (a,b){var c=F(D(this.b()));if(c=(c=Cc(c||window))&&Jc(c))var d=c.b(),e=c.g(),f=c.j(),j=c.k();var m=this.a.cloneRange(),s=this.a.cloneRange();m.collapse(l);s.collapse(i);m.insertNode(b);s.insertNode(a);m.detach();s.detach();if(c){if(d.nodeType==C)for(;f>d.length;){f-=d.length;do d=d.nextSibling;while(d==a||d==b)}if(e.nodeType==C)for(;j>e.length;){j-=e.length;do e=e.nextSibling;while(e==a||e==b)}c=new Kc;c.G=Lc(d,f,e,j);"BR"==d.tagName&&(m=d.parentNode,f=A(m.childNodes,d),d=m);"BR"==e.tagName&&
+(m=e.parentNode,j=A(m.childNodes,e),e=m);c.G?(c.f=e,c.i=j,c.d=d,c.h=f):(c.f=d,c.i=f,c.d=e,c.h=j);c.select()}};p.collapse=function (a){this.a.collapse(a)};function W(a){this.a=a}x(W,Ic);function Fc(a){var b=D(a).createRange();if(a.nodeType==C)b.setStart(a,0),b.setEnd(a,a.length);else if(X(a)){for(var c,d=a;(c=d.firstChild)&&X(c);)d=c;b.setStart(d,0);for(d=a;(c=d.lastChild)&&X(c);)d=c;b.setEnd(d,1==d.nodeType?d.childNodes.length:d.length)}else c=a.parentNode,a=A(c.childNodes,a),b.setStart(c,a),b.setEnd(c,a+1);return new W(b)}
+W.prototype.Z=function (a,b){var c=b?this.g():this.b(),d=b?this.k():this.j(),e=b?this.b():this.g(),f=b?this.j():this.k();a.collapse(c,d);(c!=e||d!=f)&&a.extend(e,f)};function Mc(a){this.a=a}x(Mc,Hc);Ac("goog.dom.browserrange.IeRange");function Nc(a){var b=D(a).body.createTextRange();if(1==a.nodeType)b.moveToElementText(a),X(a)&&!a.childNodes.length&&b.collapse(l);else{for(var c=0,d=a;d=d.previousSibling;){var e=d.nodeType;if(e==C)c+=d.length;else if(1==e){b.moveToElementText(d);break}}d||b.moveToElementText(a.parentNode);b.collapse(!d);c&&b.move("character",c);b.moveEnd("character",a.length)}return b}p=Mc.prototype;p.O=k;p.f=k;p.d=k;p.i=-1;p.h=-1;
 p.s=function(){this.O=this.f=this.d=k;this.i=this.h=-1};
 p.C=function(){if(!this.O){var a=this.a.text,b=this.a.duplicate(),c=a.replace(/ +$/,"");(c=a.length-c.length)&&b.moveEnd("character",-c);c=b.parentElement();b=b.htmlText.replace(/(\r\n|\r|\n)+/g," ").length;if(this.isCollapsed()&&0<b)return this.O=c;for(;b>c.outerHTML.replace(/(\r\n|\r|\n)+/g," ").length;)c=c.parentNode;for(;1==c.childNodes.length&&c.innerText==(c.firstChild.nodeType==C?c.firstChild.nodeValue:c.firstChild.innerText)&&X(c.firstChild);)c=c.firstChild;0==a.length&&(c=Oc(this,c));this.O=
 c}return this.O};function Oc(a,b){for(var c=b.childNodes,d=0,e=c.length;d<e;d++){var f=c[d];if(X(f)){var j=Nc(f),m=j.htmlText!=f.outerHTML;if(a.isCollapsed()&&m?0<=a.l(j,1,1)&&0>=a.l(j,1,0):a.a.inRange(j))return Oc(a,f)}}return b}p.b=function(){this.f||(this.f=Pc(this,1),this.isCollapsed()&&(this.d=this.f));return this.f};p.j=function(){0>this.i&&(this.i=Qc(this,1),this.isCollapsed()&&(this.h=this.i));return this.i};
-p.g=function(){if(this.isCollapsed())return this.b();this.d||(this.d=Pc(this,0));return this.d};p.k=function(){if(this.isCollapsed())return this.j();0>this.h&&(this.h=Qc(this,0),this.isCollapsed()&&(this.i=this.h));return this.h};p.l=function(a,b,c){return this.a.compareEndPoints((1==b?"Start":"End")+"To"+(1==c?"Start":"End"),a)};
+p.g=function(){if(this.isCollapsed())return this.b();this.d||(this.d=Pc(this,0));return this.d};p.k=function(){if(this.isCollapsed())return this.j();0>this.h&&(this.h=Qc(this,0),this.isCollapsed()&&(this.i=this.h));return this.h};p.l=function (a,b,c){return this.a.compareEndPoints((1==b?"Start":"End")+"To"+(1==c?"Start":"End"),a)};
 function Pc(a,b,c){c=c||a.C();if(!c||!c.firstChild)return c;for(var d=1==b,e=0,f=c.childNodes.length;e<f;e++){var j=d?e:f-e-1,m=c.childNodes[j],s;try{s=Fc(m)}catch(O){continue}var E=s.a;if(a.isCollapsed())if(X(m)){if(s.u(a))return Pc(a,b,m)}else{if(0==a.l(E,1,1)){a.i=a.h=j;break}}else{if(a.u(s)){if(!X(m)){d?a.i=j:a.h=j+1;break}return Pc(a,b,m)}if(0>a.l(E,1,0)&&0<a.l(E,0,1))return Pc(a,b,m)}}return c}
 function Qc(a,b){var c=1==b,d=c?a.b():a.g();if(1==d.nodeType){for(var d=d.childNodes,e=d.length,f=c?1:-1,j=c?0:e-1;0<=j&&j<e;j+=f){var m=d[j];if(!X(m)&&0==a.a.compareEndPoints((1==b?"Start":"End")+"To"+(1==b?"Start":"End"),Fc(m).a))return c?j:j+1}return-1==j?0:j}e=a.a.duplicate();f=Nc(d);e.setEndPoint(c?"EndToEnd":"StartToStart",f);e=e.text.length;return c?d.length-e:e}p.isCollapsed=function(){return 0==this.a.compareEndPoints("StartToEnd",this.a)};p.select=function(){this.a.select()};
-function Rc(a,b,c){var d;d=d||Wa(a.parentElement());var e;1!=b.nodeType&&(e=i,b=d.da("DIV",k,b));a.collapse(c);d=d||Wa(a.parentElement());var f=c=b.id;c||(c=b.id="goog_"+pa++);a.pasteHTML(b.outerHTML);(b=d.z(c))&&(f||b.removeAttribute("id"));if(e){a=b.firstChild;e=b;if((d=e.parentNode)&&11!=d.nodeType)if(e.removeNode)e.removeNode(l);else{for(;b=e.firstChild;)d.insertBefore(b,e);bb(e)}b=a}return b}p.insertNode=function(a,b){var c=Rc(this.a.duplicate(),a,b);this.s();return c};
-p.R=function(a,b){var c=this.a.duplicate(),d=this.a.duplicate();Rc(c,a,i);Rc(d,b,l);this.s()};p.collapse=function(a){this.a.collapse(a);a?(this.d=this.f,this.h=this.i):(this.f=this.d,this.i=this.h)};function Sc(a){this.a=a}x(Sc,Ic);Sc.prototype.Z=function(a){a.collapse(this.b(),this.j());(this.g()!=this.b()||this.k()!=this.j())&&a.extend(this.g(),this.k());0==a.rangeCount&&a.addRange(this.a)};function Tc(a){this.a=a}x(Tc,Ic);Tc.prototype.l=function(a,b,c){return Ba["528"]||(Ba["528"]=0<=oa(ya,"528"))?Tc.$.l.call(this,a,b,c):this.a.compareBoundaryPoints(1==c?1==b?q.Range.START_TO_START:q.Range.END_TO_START:1==b?q.Range.START_TO_END:q.Range.END_TO_END,a)};Tc.prototype.Z=function(a,b){a.removeAllRanges();b?a.setBaseAndExtent(this.g(),this.k(),this.b(),this.j()):a.setBaseAndExtent(this.b(),this.j(),this.g(),this.k())};function X(a){var b;a:if(1!=a.nodeType)b=l;else{switch(a.tagName){case "APPLET":case "AREA":case "BASE":case "BR":case "COL":case "FRAME":case "HR":case "IMG":case "INPUT":case "IFRAME":case "ISINDEX":case "LINK":case "NOFRAMES":case "NOSCRIPT":case "META":case "OBJECT":case "PARAM":case "SCRIPT":case "STYLE":b=l;break a}b=i}return b||a.nodeType==C};function Kc(){}x(Kc,T);function Ec(a,b){var c=new Kc;c.K=a;c.G=!!b;return c}p=Kc.prototype;p.K=k;p.f=k;p.i=k;p.d=k;p.h=k;p.G=l;p.fa=o("text");p.W=function(){return Y(this).a};p.s=function(){this.f=this.i=this.d=this.h=k};p.D=o(1);p.A=function(){return this};function Y(a){var b;if(!(b=a.K)){b=a.b();var c=a.j(),d=a.g(),e=a.k(),f=D(b).createRange();f.setStart(b,c);f.setEnd(d,e);b=a.K=new W(f)}return b}p.C=function(){return Y(this).C()};p.b=function(){return this.f||(this.f=Y(this).b())};
-p.j=function(){return this.i!=k?this.i:this.i=Y(this).j()};p.g=function(){return this.d||(this.d=Y(this).g())};p.k=function(){return this.h!=k?this.h:this.h=Y(this).k()};p.F=n("G");p.u=function(a,b){var c=a.fa();return"text"==c?Y(this).u(Y(a),b):"control"==c?(c=Uc(a),(b?Na:Oa)(c,function(a){return this.containsNode(a,b)},this)):l};p.isCollapsed=function(){return Y(this).isCollapsed()};p.r=function(){return new Gc(this.b(),this.j(),this.g(),this.k())};p.select=function(){Y(this).select(this.G)};
-p.insertNode=function(a,b){var c=Y(this).insertNode(a,b);this.s();return c};p.R=function(a,b){Y(this).R(a,b);this.s()};p.ga=function(){return new Vc(this)};p.collapse=function(a){a=this.F()?!a:a;this.K&&this.K.collapse(a);a?(this.d=this.f,this.h=this.i):(this.f=this.d,this.i=this.h);this.G=l};function Vc(a){a.F()?a.g():a.b();a.F()?a.k():a.j();a.F()?a.b():a.g();a.F()?a.j():a.k()}x(Vc,Bc);function Wc(){}x(Wc,V);p=Wc.prototype;p.a=k;p.m=k;p.Q=k;p.s=function(){this.Q=this.m=k};p.fa=o("control");p.W=function(){return this.a||document.body.createControlRange()};p.D=function(){return this.a?this.a.length:0};p.A=function(a){a=this.a.item(a);return Ec(Fc(a),h)};p.C=function(){return fb.apply(k,Uc(this))};p.b=function(){return Xc(this)[0]};p.j=o(0);p.g=function(){var a=Xc(this),b=z(a);return Pa(a,function(a){return G(a,b)})};p.k=function(){return this.g().childNodes.length};
-function Uc(a){if(!a.m&&(a.m=[],a.a))for(var b=0;b<a.a.length;b++)a.m.push(a.a.item(b));return a.m}function Xc(a){a.Q||(a.Q=Uc(a).concat(),a.Q.sort(function(a,c){return a.sourceIndex-c.sourceIndex}));return a.Q}p.isCollapsed=function(){return!this.a||!this.a.length};p.r=function(){return new Yc(this)};p.select=function(){this.a&&this.a.select()};p.ga=function(){return new Zc(this)};p.collapse=function(){this.a=k;this.s()};function Zc(a){this.m=Uc(a)}x(Zc,Bc);
-function Yc(a){a&&(this.m=Xc(a),this.f=this.m.shift(),this.d=z(this.m)||this.f);U.call(this,this.f,l)}x(Yc,U);p=Yc.prototype;p.f=k;p.d=k;p.m=k;p.b=n("f");p.g=n("d");p.M=function(){return!this.depth&&!this.m.length};p.next=function(){this.M()&&g(I);if(!this.depth){var a=this.m.shift();L(this,a,1,1);return a}return Yc.$.next.call(this)};function $c(){this.t=[];this.P=[];this.U=this.I=k}x($c,V);p=$c.prototype;p.Ea=Ac("goog.dom.MultiRange");p.s=function(){this.P=[];this.U=this.I=k};p.fa=o("mutli");p.W=function(){1<this.t.length&&this.Ea.log(vc,"getBrowserRangeObject called on MultiRange with more than 1 range",h);return this.t[0]};p.D=function(){return this.t.length};p.A=function(a){this.P[a]||(this.P[a]=Ec(new W(this.t[a]),h));return this.P[a]};
-p.C=function(){if(!this.U){for(var a=[],b=0,c=this.D();b<c;b++)a.push(this.A(b).C());this.U=fb.apply(k,a)}return this.U};function ad(a){a.I||(a.I=Dc(a),a.I.sort(function(a,c){var d=a.b(),e=a.j(),f=c.b(),j=c.j();return d==f&&e==j?0:Lc(d,e,f,j)?1:-1}));return a.I}p.b=function(){return ad(this)[0].b()};p.j=function(){return ad(this)[0].j()};p.g=function(){return z(ad(this)).g()};p.k=function(){return z(ad(this)).k()};p.isCollapsed=function(){return 0==this.t.length||1==this.t.length&&this.A(0).isCollapsed()};
-p.r=function(){return new bd(this)};p.select=function(){var a=Cc(this.qa());a.removeAllRanges();for(var b=0,c=this.D();b<c;b++)a.addRange(this.A(b).W())};p.ga=function(){return new cd(this)};p.collapse=function(a){if(!this.isCollapsed()){var b=a?this.A(0):this.A(this.D()-1);this.s();b.collapse(a);this.P=[b];this.I=[b];this.t=[b.W()]}};function cd(a){Ma(Dc(a),function(a){return a.ga()})}x(cd,Bc);function bd(a){a&&(this.H=Ma(ad(a),function(a){return sb(a)}));U.call(this,a?this.b():k,l)}x(bd,U);p=bd.prototype;
+function Rc(a,b,c){var d;d=d||Wa(a.parentElement());var e;1!=b.nodeType&&(e=i,b=d.da("DIV",k,b));a.collapse(c);d=d||Wa(a.parentElement());var f=c=b.id;c||(c=b.id="goog_"+pa++);a.pasteHTML(b.outerHTML);(b=d.z(c))&&(f||b.removeAttribute("id"));if(e){a=b.firstChild;e=b;if((d=e.parentNode)&&11!=d.nodeType)if(e.removeNode)e.removeNode(l);else{for(;b=e.firstChild;)d.insertBefore(b,e);bb(e)}b=a}return b}p.insertNode=function (a,b){var c=Rc(this.a.duplicate(),a,b);this.s();return c};
+p.R=function (a,b){var c=this.a.duplicate(),d=this.a.duplicate();Rc(c,a,i);Rc(d,b,l);this.s()};p.collapse=function (a){this.a.collapse(a);a?(this.d=this.f,this.h=this.i):(this.f=this.d,this.i=this.h)};function Sc(a){this.a=a}x(Sc,Ic);Sc.prototype.Z=function (a){a.collapse(this.b(),this.j());(this.g()!=this.b()||this.k()!=this.j())&&a.extend(this.g(),this.k());0==a.rangeCount&&a.addRange(this.a)};function Tc(a){this.a=a}x(Tc,Ic);Tc.prototype.l=function (a,b,c){return Ba["528"]||(Ba["528"]=0<=oa(ya,"528"))?Tc.$.l.call(this,a,b,c):this.a.compareBoundaryPoints(1==c?1==b?q.Range.START_TO_START:q.Range.END_TO_START:1==b?q.Range.START_TO_END:q.Range.END_TO_END,a)};Tc.prototype.Z=function (a,b){a.removeAllRanges();b?a.setBaseAndExtent(this.g(),this.k(),this.b(),this.j()):a.setBaseAndExtent(this.b(),this.j(),this.g(),this.k())};function X(a){var b;a:if(1!=a.nodeType)b=l;else{switch(a.tagName){case "APPLET":case "AREA":case "BASE":case "BR":case "COL":case "FRAME":case "HR":case "IMG":case "INPUT":case "IFRAME":case "ISINDEX":case "LINK":case "NOFRAMES":case "NOSCRIPT":case "META":case "OBJECT":case "PARAM":case "SCRIPT":case "STYLE":b=l;break a}b=i}return b||a.nodeType==C};function Kc(){}x(Kc,T);function Ec(a,b){var c=new Kc;c.K=a;c.G=!!b;return c}p=Kc.prototype;p.K=k;p.f=k;p.i=k;p.d=k;p.h=k;p.G=l;p.fa=o("text");p.W=function(){return Y(this).a};p.s=function(){this.f=this.i=this.d=this.h=k};p.D=o(1);p.A=function(){return this};function Y(a){var b;if(!(b=a.K)){b=a.b();var c=a.j(),d=a.g(),e=a.k(),f=D(b).createRange();f.setStart(b,c);f.setEnd(d,e);b=a.K=new W(f)}return b}p.C=function(){return Y(this).C()};p.b=function(){return this.f||(this.f=Y(this).b())};
+p.j=function(){return this.i!=k?this.i:this.i=Y(this).j()};p.g=function(){return this.d||(this.d=Y(this).g())};p.k=function(){return this.h!=k?this.h:this.h=Y(this).k()};p.F=n("G");p.u=function (a,b){var c=a.fa();return"text"==c?Y(this).u(Y(a),b):"control"==c?(c=Uc(a),(b?Na:Oa)(c,function (a){return this.containsNode(a,b)},this)):l};p.isCollapsed=function(){return Y(this).isCollapsed()};p.r=function(){return new Gc(this.b(),this.j(),this.g(),this.k())};p.select=function(){Y(this).select(this.G)};
+p.insertNode=function (a,b){var c=Y(this).insertNode(a,b);this.s();return c};p.R=function (a,b){Y(this).R(a,b);this.s()};p.ga=function(){return new Vc(this)};p.collapse=function (a){a=this.F()?!a:a;this.K&&this.K.collapse(a);a?(this.d=this.f,this.h=this.i):(this.f=this.d,this.i=this.h);this.G=l};function Vc(a){a.F()?a.g():a.b();a.F()?a.k():a.j();a.F()?a.b():a.g();a.F()?a.j():a.k()}x(Vc,Bc);function Wc(){}x(Wc,V);p=Wc.prototype;p.a=k;p.m=k;p.Q=k;p.s=function(){this.Q=this.m=k};p.fa=o("control");p.W=function(){return this.a||document.body.createControlRange()};p.D=function(){return this.a?this.a.length:0};p.A=function (a){a=this.a.item(a);return Ec(Fc(a),h)};p.C=function(){return fb.apply(k,Uc(this))};p.b=function(){return Xc(this)[0]};p.j=o(0);p.g=function(){var a=Xc(this),b=z(a);return Pa(a,function (a){return G(a,b)})};p.k=function(){return this.g().childNodes.length};
+function Uc(a){if(!a.m&&(a.m=[],a.a))for(var b=0;b<a.a.length;b++)a.m.push(a.a.item(b));return a.m}function Xc(a){a.Q||(a.Q=Uc(a).concat(),a.Q.sort(function (a,c){return a.sourceIndex-c.sourceIndex}));return a.Q}p.isCollapsed=function(){return!this.a||!this.a.length};p.r=function(){return new Yc(this)};p.select=function(){this.a&&this.a.select()};p.ga=function(){return new Zc(this)};p.collapse=function(){this.a=k;this.s()};function Zc(a){this.m=Uc(a)}x(Zc,Bc);
+function Yc(a){a&&(this.m=Xc(a),this.f=this.m.shift(),this.d=z(this.m)||this.f);U.call(this,this.f,l)}x(Yc,U);p=Yc.prototype;p.f=k;p.d=k;p.m=k;p.b=n("f");p.g=n("d");p.M=function(){return!this.depth&&!this.m.length};p.next=function(){this.M()&&g(I);if(!this.depth){var a=this.m.shift();L(this,a,1,1);return a}return Yc.$.next.call(this)};function $c(){this.t=[];this.P=[];this.U=this.I=k}x($c,V);p=$c.prototype;p.Ea=Ac("goog.dom.MultiRange");p.s=function(){this.P=[];this.U=this.I=k};p.fa=o("mutli");p.W=function(){1<this.t.length&&this.Ea.log(vc,"getBrowserRangeObject called on MultiRange with more than 1 range",h);return this.t[0]};p.D=function(){return this.t.length};p.A=function (a){this.P[a]||(this.P[a]=Ec(new W(this.t[a]),h));return this.P[a]};
+p.C=function(){if(!this.U){for(var a=[],b=0,c=this.D();b<c;b++)a.push(this.A(b).C());this.U=fb.apply(k,a)}return this.U};function ad(a){a.I||(a.I=Dc(a),a.I.sort(function (a,c){var d=a.b(),e=a.j(),f=c.b(),j=c.j();return d==f&&e==j?0:Lc(d,e,f,j)?1:-1}));return a.I}p.b=function(){return ad(this)[0].b()};p.j=function(){return ad(this)[0].j()};p.g=function(){return z(ad(this)).g()};p.k=function(){return z(ad(this)).k()};p.isCollapsed=function(){return 0==this.t.length||1==this.t.length&&this.A(0).isCollapsed()};
+p.r=function(){return new bd(this)};p.select=function(){var a=Cc(this.qa());a.removeAllRanges();for(var b=0,c=this.D();b<c;b++)a.addRange(this.A(b).W())};p.ga=function(){return new cd(this)};p.collapse=function (a){if(!this.isCollapsed()){var b=a?this.A(0):this.A(this.D()-1);this.s();b.collapse(a);this.P=[b];this.I=[b];this.t=[b.W()]}};function cd(a){Ma(Dc(a),function (a){return a.ga()})}x(cd,Bc);function bd(a){a&&(this.H=Ma(ad(a),function (a){return sb(a)}));U.call(this,a?this.b():k,l)}x(bd,U);p=bd.prototype;
 p.H=k;p.V=0;p.b=function(){return this.H[0].b()};p.g=function(){return z(this.H).g()};p.M=function(){return this.H[this.V].M()};p.next=function(){try{var a=this.H[this.V],b=a.next();L(this,a.p,a.q,a.depth);return b}catch(c){return(c!==I||this.H.length-1==this.V)&&g(c),this.V++,this.next()}};function Jc(a){var b,c=l;if(a.createRange)try{b=a.createRange()}catch(d){return k}else if(a.rangeCount){if(1<a.rangeCount){b=new $c;for(var c=0,e=a.rangeCount;c<e;c++)b.t.push(a.getRangeAt(c));return b}b=a.getRangeAt(0);c=Lc(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset)}else return k;b&&b.addElement?(a=new Wc,a.a=b):a=Ec(new W(b),c);return a}
-function Lc(a,b,c,d){if(a==c)return d<b;var e;if(1==a.nodeType&&b)if(e=a.childNodes[b])a=e,b=0;else if(G(a,c))return i;if(1==c.nodeType&&d)if(e=c.childNodes[d])c=e,d=0;else if(G(c,a))return l;return 0<(cb(a,c)||b-d)};function dd(){N.call(this);this.ja=k;this.B=new B(0,0);this.sa=l}x(dd,N);var Z={};Z[Zb]=[0,1,2,k];Z[$b]=[k,k,2,k];Z[fc]=[0,1,2,k];Z[dc]=[0,0,0,0];Z[cc]=[0,0,0,0];Z[ac]=Z[Zb];Z[bc]=Z[fc];Z[ec]=Z[dc];dd.prototype.move=function(a,b){var c=xb(a);this.B.x=b.x+c.x;this.B.y=b.y+c.y;a!=this.z()&&(c=this.z()===Ca.document.documentElement||this.z()===Ca.document.body,c=!this.sa&&c?k:this.z(),ed(this,dc,a),Ob(this,a),ed(this,ec,c));ed(this,cc)};
-function ed(a,b,c){a.sa=i;var d=a.B,e;b in Z?(e=Z[b][a.ja===k?3:a.ja],e===k&&g(new y(13,"Event does not permit the specified mouse button."))):e=0;Mb(a.w,i)&&Eb(a.w)&&(c&&!(ec==b||dc==b)&&g(new y(12,"Event type does not allow related target: "+b)),c={clientX:d.x,clientY:d.y,button:e,altKey:l,ctrlKey:l,shiftKey:l,metaKey:l,wheelDelta:0,relatedTarget:c||k},(a=a.w)&&Sb(a,b,c))};function fd(){N.call(this);this.B=new B(0,0);this.ca=new B(0,0)}x(fd,N);fd.prototype.xa=0;fd.prototype.wa=0;fd.prototype.move=function(a,b,c){this.X()||Ob(this,a);a=xb(a);this.B.x=b.x+a.x;this.B.y=b.y+a.y;r(c)&&(this.ca.x=c.x+a.x,this.ca.y=c.y+a.y);if(this.X()){b=Rb;this.X()||g(new y(13,"Should never fire event when touchscreen is not pressed."));var d,e;this.wa&&(d=this.wa,e=this.ca);Pb(this,b,this.xa,this.B,d,e)}};fd.prototype.X=function(){return!!this.xa};function gd(a,b){this.x=a;this.y=b}x(gd,B);gd.prototype.scale=function(a){this.x*=a;this.y*=a;return this};gd.prototype.add=function(a){this.x+=a.x;this.y+=a.y;return this};function hd(){N.call(this)}x(hd,N);(function(a){a.Ba=function(){return a.Da||(a.Da=new a)}})(hd);function id(a){(!Mb(a,i)||!Eb(a))&&g(new y(12,"Element is not currently interactable and may not be manipulated"));(!Gb(a)||Bb(a,"readOnly"))&&g(new y(12,"Element must be user-editable in order to clear it."));var b=hd.Ba();Ob(b,a);var b=b.ua||b.w,c=D(b).activeElement;if(b!=c){if(c&&w(c.blur))try{c.blur()}catch(d){g(d)}w(b.focus)&&b.focus()}a.value&&(a.value="",Sb(a,Yb));Hb(a)&&(a.innerHTML=" ")}var jd=["_"],$=q;!(jd[0]in $)&&$.execScript&&$.execScript("var "+jd[0]);
+function Lc(a,b,c,d){if(a==c)return d<b;var e;if(1==a.nodeType&&b)if(e=a.childNodes[b])a=e,b=0;else if(G(a,c))return i;if(1==c.nodeType&&d)if(e=c.childNodes[d])c=e,d=0;else if(G(c,a))return l;return 0<(cb(a,c)||b-d)};function dd(){N.call(this);this.ja=k;this.B=new B(0,0);this.sa=l}x(dd,N);var Z={};Z[Zb]=[0,1,2,k];Z[$b]=[k,k,2,k];Z[fc]=[0,1,2,k];Z[dc]=[0,0,0,0];Z[cc]=[0,0,0,0];Z[ac]=Z[Zb];Z[bc]=Z[fc];Z[ec]=Z[dc];dd.prototype.move=function (a,b){var c=xb(a);this.B.x=b.x+c.x;this.B.y=b.y+c.y;a!=this.z()&&(c=this.z()===Ca.document.documentElement||this.z()===Ca.document.body,c=!this.sa&&c?k:this.z(),ed(this,dc,a),Ob(this,a),ed(this,ec,c));ed(this,cc)};
+function ed(a,b,c){a.sa=i;var d=a.B,e;b in Z?(e=Z[b][a.ja===k?3:a.ja],e===k&&g(new y(13,"Event does not permit the specified mouse button."))):e=0;Mb(a.w,i)&&Eb(a.w)&&(c&&!(ec==b||dc==b)&&g(new y(12,"Event type does not allow related target: "+b)),c={clientX:d.x,clientY:d.y,button:e,altKey:l,ctrlKey:l,shiftKey:l,metaKey:l,wheelDelta:0,relatedTarget:c||k},(a=a.w)&&Sb(a,b,c))};function fd(){N.call(this);this.B=new B(0,0);this.ca=new B(0,0)}x(fd,N);fd.prototype.xa=0;fd.prototype.wa=0;fd.prototype.move=function (a,b,c){this.X()||Ob(this,a);a=xb(a);this.B.x=b.x+a.x;this.B.y=b.y+a.y;r(c)&&(this.ca.x=c.x+a.x,this.ca.y=c.y+a.y);if(this.X()){b=Rb;this.X()||g(new y(13,"Should never fire event when touchscreen is not pressed."));var d,e;this.wa&&(d=this.wa,e=this.ca);Pb(this,b,this.xa,this.B,d,e)}};fd.prototype.X=function(){return!!this.xa};function gd(a,b){this.x=a;this.y=b}x(gd,B);gd.prototype.scale=function (a){this.x*=a;this.y*=a;return this};gd.prototype.add=function (a){this.x+=a.x;this.y+=a.y;return this};function hd(){N.call(this)}x(hd,N);(function (a){a.Ba=function(){return a.Da||(a.Da=new a)}})(hd);function id(a){(!Mb(a,i)||!Eb(a))&&g(new y(12,"Element is not currently interactable and may not be manipulated"));(!Gb(a)||Bb(a,"readOnly"))&&g(new y(12,"Element must be user-editable in order to clear it."));var b=hd.Ba();Ob(b,a);var b=b.ua||b.w,c=D(b).activeElement;if(b!=c){if(c&&w(c.blur))try{c.blur()}catch(d){g(d)}w(b.focus)&&b.focus()}a.value&&(a.value="",Sb(a,Yb));Hb(a)&&(a.innerHTML=" ")}var jd=["_"],$=q;!(jd[0]in $)&&$.execScript&&$.execScript("var "+jd[0]);
 for(var ld;jd.length&&(ld=jd.shift());)!jd.length&&r(id)?$[ld]=id:$=$[ld]?$[ld]:$[ld]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
 
-atom.getElementAttribute = function(element, name, window){return function(){var f=null,g=!1,h=this;
+atom.getElementAttribute = function (element, name, window){return function(){var f=null,g=!1,h=this;
 function i(a){var c=typeof a;if("object"==c)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return c;var b=Object.prototype.toString.call(a);if("[object Window]"==b)return"object";if("[object Array]"==b||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==b||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==
 c&&"undefined"==typeof a.call)return"object";return c}function j(a,c){function b(){}b.prototype=c.prototype;a.f=c.prototype;a.prototype=new b};function k(a,c){for(var b=1;b<arguments.length;b++)var d=(""+arguments[b]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a}function l(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};var m,n="",o=/rv\:([^\);]+)(\)|;)/.exec(h.navigator?h.navigator.userAgent:f);m=n=o?o[1]:"";var p={};function q(a,c){this.code=a;this.message=c||"";this.name=r[a]||r[13];var b=Error(this.message);b.name=this.name;this.stack=b.stack||""}j(q,Error);
 var r={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"};
 q.prototype.toString=function(){return"["+this.name+"] "+this.message};function s(a){this.stack=Error().stack||"";a&&(this.message=""+a)}j(s,Error);s.prototype.name="CustomError";function t(a,c){c.unshift(a);s.call(this,k.apply(f,c));c.shift()}j(t,s);t.prototype.name="AssertionError";function u(a,c){if("string"==typeof a)return"string"!=typeof c||1!=c.length?-1:a.indexOf(c,0);for(var b=0;b<a.length;b++)if(b in a&&a[b]===c)return b;return-1};if(!p["1.9.1"]){for(var v=0,w=l(""+m).split("."),x=l("1.9.1").split("."),y=Math.max(w.length,x.length),z=0;0==v&&z<y;z++){var A=w[z]||"",B=x[z]||"",C=RegExp("(\\d*)(\\D*)","g"),D=RegExp("(\\d*)(\\D*)","g");do{var E=C.exec(A)||["","",""],F=D.exec(B)||["","",""];if(0==E[0].length&&0==F[0].length)break;v=((0==E[1].length?0:parseInt(E[1],10))<(0==F[1].length?0:parseInt(F[1],10))?-1:(0==E[1].length?0:parseInt(E[1],10))>(0==F[1].length?0:parseInt(F[1],10))?1:0)||((0==E[2].length)<(0==F[2].length)?-1:(0==
 E[2].length)>(0==F[2].length)?1:0)||(E[2]<F[2]?-1:E[2]>F[2]?1:0)}while(0==v)}p["1.9.1"]=0<=v};var G={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},H={IMG:" ",BR:"\n"};function I(a,c,b){if(!(a.nodeName in G))if(3==a.nodeType)b?c.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):c.push(a.nodeValue);else if(a.nodeName in H)c.push(H[a.nodeName]);else for(a=a.firstChild;a;)I(a,c,b),a=a.nextSibling};(function(){var a=h.Components;if(!a)return g;try{if(!a.classes)return g}catch(c){return g}var b=a.classes,a=a.interfaces;b["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);b["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();var J="StopIteration"in h?h.StopIteration:Error("StopIteration");function K(){}K.prototype.next=function(){throw J;};function L(a,c,b,d,e){this.a=!!c;a&&M(this,a,d);this.depth=void 0!=e?e:this.c||0;this.a&&(this.depth*=-1);this.e=!b}j(L,K);L.prototype.b=f;L.prototype.c=0;L.prototype.d=g;function M(a,c,b){if(a.b=c)a.c="number"==typeof b?b:1!=a.b.nodeType?0:a.a?-1:1}
 L.prototype.next=function(){var a;if(this.d){if(!this.b||this.e&&0==this.depth)throw J;a=this.b;var c=this.a?-1:1;if(this.c==c){var b=this.a?a.lastChild:a.firstChild;b?M(this,b):M(this,a,-1*c)}else(b=this.a?a.previousSibling:a.nextSibling)?M(this,b):M(this,a.parentNode,-1*c);this.depth+=this.c*(this.a?-1:1)}else this.d=!0;a=this.b;if(!this.b)throw J;return a};
-L.prototype.splice=function(a){var c=this.b,b=this.a?1:-1;this.c==b&&(this.c=-1*b,this.depth+=this.c*(this.a?-1:1));this.a=!this.a;L.prototype.next.call(this);this.a=!this.a;for(var b=arguments[0],d=i(b),b="array"==d||"object"==d&&"number"==typeof b.length?arguments[0]:arguments,d=b.length-1;0<=d;d--)c.parentNode&&c.parentNode.insertBefore(b[d],c.nextSibling);c&&c.parentNode&&c.parentNode.removeChild(c)};function N(a,c,b,d){L.call(this,a,c,b,f,d)}j(N,L);N.prototype.next=function(){do N.f.next.call(this);while(-1==this.c);return this.b};function O(a,c){return!!a&&1==a.nodeType&&(!c||a.tagName.toUpperCase()==c)}function P(a){return O(a,"OPTION")?!0:O(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):g}var Q={"class":"className",readonly:"readOnly"},R=["checked","disabled","draggable","hidden"];
+L.prototype.splice=function (a){var c=this.b,b=this.a?1:-1;this.c==b&&(this.c=-1*b,this.depth+=this.c*(this.a?-1:1));this.a=!this.a;L.prototype.next.call(this);this.a=!this.a;for(var b=arguments[0],d=i(b),b="array"==d||"object"==d&&"number"==typeof b.length?arguments[0]:arguments,d=b.length-1;0<=d;d--)c.parentNode&&c.parentNode.insertBefore(b[d],c.nextSibling);c&&c.parentNode&&c.parentNode.removeChild(c)};function N(a,c,b,d){L.call(this,a,c,b,f,d)}j(N,L);N.prototype.next=function(){do N.f.next.call(this);while(-1==this.c);return this.b};function O(a,c){return!!a&&1==a.nodeType&&(!c||a.tagName.toUpperCase()==c)}function P(a){return O(a,"OPTION")?!0:O(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):g}var Q={"class":"className",readonly:"readOnly"},R=["checked","disabled","draggable","hidden"];
 function S(a,c){var b=Q[c]||c,d=a[b];if(void 0===d&&0<=u(R,b))return g;if(b="value"==c)if(b=O(a,"OPTION")){var e;b=c.toLowerCase();if(a.hasAttribute)e=a.hasAttribute(b);else try{e=a.attributes[b].specified}catch(Y){e=g}b=!e}b&&(d=[],I(a,d,g),d=d.join(""));return d}var T="async,autofocus,autoplay,checked,compact,complete,controls,declare,defaultchecked,defaultselected,defer,disabled,draggable,ended,formnovalidate,hidden,indeterminate,iscontenteditable,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,paused,pubdate,readonly,required,reversed,scoped,seamless,seeking,selected,spellcheck,truespeed,willvalidate".split(",");
 function U(a,c){if(8==a.nodeType)return f;c=c.toLowerCase();if("style"==c){var b=l(a.style.cssText).toLowerCase();return b=";"==b.charAt(b.length-1)?b:b+";"}b=a.getAttributeNode(c);return!b?f:0<=u(T,c)?"true":b.specified?b.value:f};function V(a,c){var b=f,d=c.toLowerCase();if("style"==c.toLowerCase()){if((b=a.style)&&"string"!=typeof b)b=b.cssText;return b}if("selected"==d||"checked"==d&&P(a)){if(!P(a))throw new q(15,"Element is not selectable");var e="selected",d=a.type&&a.type.toLowerCase();if("checkbox"==d||"radio"==d)e="checked";return S(a,e)?"true":f}b=O(a,"A");if(O(a,"IMG")&&"src"==d||b&&"href"==d)return(b=U(a,d))&&(b=S(a,d)),b;try{e=S(a,c)}catch(Y){}if(!(d=e==f))d=i(e),d="object"==d||"array"==d||"function"==d;b=d?U(a,
 c):e;return b!=f?b.toString():f}var W=["_"],X=h;!(W[0]in X)&&X.execScript&&X.execScript("var "+W[0]);for(var Z;W.length&&(Z=W.shift());)!W.length&&void 0!==V?X[Z]=V:X=X[Z]?X[Z]:X[Z]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
 
-atom.getElementText = function(element, window){return function(){var g=void 0,h=!0,i=null,j=!1,k=this;
+atom.getElementText = function (element, window){return function(){var g=void 0,h=!0,i=null,j=!1,k=this;
 function l(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
-else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function m(a){return"string"==typeof a}function n(a,b){function c(){}c.prototype=b.prototype;a.h=b.prototype;a.prototype=new c};function o(a){var b=a.length-1;return 0<=b&&a.indexOf(" ",b)==b}function aa(a,b){for(var c=1;c<arguments.length;c++)var d=(""+arguments[c]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a}function p(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}var q={};function ba(a){return q[a]||(q[a]=(""+a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()}))};var s,ca="",u=/rv\:([^\);]+)(\)|;)/.exec(k.navigator?k.navigator.userAgent:i);s=ca=u?u[1]:"";var v={};var da=window;function w(a,b){this.code=a;this.message=b||"";this.name=x[a]||x[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}n(w,Error);
+else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function m(a){return"string"==typeof a}function n(a,b){function c(){}c.prototype=b.prototype;a.h=b.prototype;a.prototype=new c};function o(a){var b=a.length-1;return 0<=b&&a.indexOf(" ",b)==b}function aa(a,b){for(var c=1;c<arguments.length;c++)var d=(""+arguments[c]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a}function p(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}var q={};function ba(a){return q[a]||(q[a]=(""+a).replace(/\-([a-z])/g,function (a,c){return c.toUpperCase()}))};var s,ca="",u=/rv\:([^\);]+)(\)|;)/.exec(k.navigator?k.navigator.userAgent:i);s=ca=u?u[1]:"";var v={};var da=window;function w(a,b){this.code=a;this.message=b||"";this.name=x[a]||x[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}n(w,Error);
 var x={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"};
 w.prototype.toString=function(){return"["+this.name+"] "+this.message};function y(a){this.stack=Error().stack||"";a&&(this.message=""+a)}n(y,Error);y.prototype.name="CustomError";function z(a,b){b.unshift(a);y.call(this,aa.apply(i,b));b.shift()}n(z,y);z.prototype.name="AssertionError";function ea(a,b){for(var c=a.length,d=m(a)?a.split(""):a,e=0;e<c;e++)e in d&&b.call(g,d[e],e,a)}function fa(a,b){for(var c=a.length,d=m(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(g,d[e],e,a))return h;return j}function A(a,b){var c;a:if(m(a))c=!m(b)||1!=b.length?-1:a.indexOf(b,0);else{for(c=0;c<a.length;c++)if(c in a&&a[c]===b)break a;c=-1}return 0<=c};var B;
 if(!v["1.9.1"]){for(var C=0,D=p(""+s).split("."),E=p("1.9.1").split("."),ga=Math.max(D.length,E.length),F=0;0==C&&F<ga;F++){var ha=D[F]||"",ia=E[F]||"",ja=RegExp("(\\d*)(\\D*)","g"),ka=RegExp("(\\d*)(\\D*)","g");do{var G=ja.exec(ha)||["","",""],H=ka.exec(ia)||["","",""];if(0==G[0].length&&0==H[0].length)break;C=((0==G[1].length?0:parseInt(G[1],10))<(0==H[1].length?0:parseInt(H[1],10))?-1:(0==G[1].length?0:parseInt(G[1],10))>(0==H[1].length?0:parseInt(H[1],10))?1:0)||((0==G[2].length)<(0==H[2].length)?-1:
 (0==G[2].length)>(0==H[2].length)?1:0)||(G[2]<H[2]?-1:G[2]>H[2]?1:0)}while(0==C)}v["1.9.1"]=0<=C};function I(a,b){this.x=a!==g?a:0;this.y=b!==g?b:0}I.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function J(a,b){this.width=a;this.height=b}J.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};var K=3;function L(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function la(a,b){var c=[];return M(a,b,c,h)?c[0]:g}function M(a,b,c,d){if(a!=i)for(a=a.firstChild;a;){if(b(a)&&(c.push(a),d)||M(a,b,c,d))return h;a=a.nextSibling}return j}function ma(a,b){for(var a=a.parentNode,c=0;a;){if(b(a))return a;a=a.parentNode;c++}return i}function N(a){this.g=a||k.document||document}
-function na(a){var b=a.g,a="CSS1Compat"==b.compatMode?b.documentElement:b.body,b=b.parentWindow||b.defaultView;return new I(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)};var oa=function(){var a={i:"http://www.w3.org/2000/svg"};return function(b){return a[b]||i}}();
+function na(a){var b=a.g,a="CSS1Compat"==b.compatMode?b.documentElement:b.body,b=b.parentWindow||b.defaultView;return new I(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)};var oa=function(){var a={i:"http://www.w3.org/2000/svg"};return function (b){return a[b]||i}}();
 function pa(a,b){var c=function(){var c;a:{var e=L(b);if(e.implementation.hasFeature("XPath","3.0")){try{var f=e.createNSResolver?e.createNSResolver(e.documentElement):oa;c=e.evaluate(a,b,f,9,i);break a}catch(r){if("NS_ERROR_ILLEGAL_VALUE"!=r.name)throw new w(32,"Unable to locate an element with the xpath expression "+a+" because of the following error:\n"+r);}c=g}else c=i}return c?c.singleNodeValue||i:b.selectSingleNode?(c=L(b),c.setProperty&&c.setProperty("SelectionLanguage","XPath"),b.selectSingleNode(a)):
 i}();if(c!==i&&(!c||1!=c.nodeType))throw new w(32,'The result of the xpath expression "'+a+'" is: '+c+". It should be an element.");return c};(function(){var a=k.Components;if(!a)return j;try{if(!a.classes)return j}catch(b){return j}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return h})();var P="StopIteration"in k?k.StopIteration:Error("StopIteration");function qa(){}qa.prototype.next=function(){throw P;};function Q(a,b,c,d,e){this.a=!!b;a&&R(this,a,d);this.depth=e!=g?e:this.c||0;this.a&&(this.depth*=-1);this.f=!c}n(Q,qa);Q.prototype.b=i;Q.prototype.c=0;Q.prototype.e=j;function R(a,b,c){if(a.b=b)a.c="number"==typeof c?c:1!=a.b.nodeType?0:a.a?-1:1}
 Q.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&0==this.depth)throw P;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?R(this,c):R(this,a,-1*b)}else(c=this.a?a.previousSibling:a.nextSibling)?R(this,c):R(this,a.parentNode,-1*b);this.depth+=this.c*(this.a?-1:1)}else this.e=h;a=this.b;if(!this.b)throw P;return a};
-Q.prototype.splice=function(a){var b=this.b,c=this.a?1:-1;this.c==c&&(this.c=-1*c,this.depth+=this.c*(this.a?-1:1));this.a=!this.a;Q.prototype.next.call(this);this.a=!this.a;for(var c=arguments[0],d=l(c),c="array"==d||"object"==d&&"number"==typeof c.length?arguments[0]:arguments,d=c.length-1;0<=d;d--)b.parentNode&&b.parentNode.insertBefore(c[d],b.nextSibling);b&&b.parentNode&&b.parentNode.removeChild(b)};function S(a,b,c,d){Q.call(this,a,b,c,i,d)}n(S,Q);S.prototype.next=function(){do S.h.next.call(this);while(-1==this.c);return this.b};function ra(a,b){var c=L(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,i))?c[b]||c.getPropertyValue(b):""}function T(a,b){return ra(a,b)||(a.currentStyle?a.currentStyle[b]:i)||a.style&&a.style[b]}
+Q.prototype.splice=function (a){var b=this.b,c=this.a?1:-1;this.c==c&&(this.c=-1*c,this.depth+=this.c*(this.a?-1:1));this.a=!this.a;Q.prototype.next.call(this);this.a=!this.a;for(var c=arguments[0],d=l(c),c="array"==d||"object"==d&&"number"==typeof c.length?arguments[0]:arguments,d=c.length-1;0<=d;d--)b.parentNode&&b.parentNode.insertBefore(c[d],b.nextSibling);b&&b.parentNode&&b.parentNode.removeChild(b)};function S(a,b,c,d){Q.call(this,a,b,c,i,d)}n(S,Q);S.prototype.next=function(){do S.h.next.call(this);while(-1==this.c);return this.b};function ra(a,b){var c=L(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,i))?c[b]||c.getPropertyValue(b):""}function T(a,b){return ra(a,b)||(a.currentStyle?a.currentStyle[b]:i)||a.style&&a.style[b]}
 function sa(a){for(var b=L(a),c=T(a,"position"),d="fixed"==c||"absolute"==c,a=a.parentNode;a&&a!=b;a=a.parentNode)if(c=T(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return i}
 function ta(a){var b=new I;if(1==a.nodeType)if(a.getBoundingClientRect)a=a.getBoundingClientRect(),b.x=a.left,b.y=a.top;else{var c=na(a?new N(L(a)):B||(B=new N));var d,e=L(a),f=T(a,"position"),r=e.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==f&&(d=e.getBoxObjectFor(a))&&(0>d.screenX||0>d.screenY),f=new I(0,0),t=(e?9==e.nodeType?e:L(e):document).documentElement;if(a!=t)if(a.getBoundingClientRect)d=a.getBoundingClientRect(),a=na(e?new N(L(e)):B||(B=new N)),f.x=d.left+a.x,f.y=d.top+a.y;else if(e.getBoxObjectFor&&
 !r)d=e.getBoxObjectFor(a),a=e.getBoxObjectFor(t),f.x=d.screenX-a.screenX,f.y=d.screenY-a.screenY;else{d=a;do f.x+=d.offsetLeft,f.y+=d.offsetTop,d!=a&&(f.x+=d.clientLeft||0,f.y+=d.clientTop||0),d=d.offsetParent;while(d&&d!=a);for(d=a;(d=sa(d))&&d!=e.body&&d!=t;)f.x-=d.scrollLeft,f.y-=d.scrollTop}b.x=f.x-c.x;b.y=f.y-c.y}else c="function"==l(a.d),d=a,a.targetTouches?d=a.targetTouches[0]:c&&a.d().targetTouches&&(d=a.d().targetTouches[0]),b.x=d.clientX,b.y=d.clientY;return b}
 function ua(a){var b=a.offsetWidth,c=a.offsetHeight;return b===g&&a.getBoundingClientRect?(a=a.getBoundingClientRect(),new J(a.right-a.left,a.bottom-a.top)):new J(b,c)};function U(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}var va="async,autofocus,autoplay,checked,compact,complete,controls,declare,defaultchecked,defaultselected,defer,disabled,draggable,ended,formnovalidate,hidden,indeterminate,iscontenteditable,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,paused,pubdate,readonly,required,reversed,scoped,seamless,seeking,selected,spellcheck,truespeed,willvalidate".split(",");
 function V(a){for(a=a.parentNode;a&&1!=a.nodeType&&9!=a.nodeType&&11!=a.nodeType;)a=a.parentNode;return U(a)?a:i}function W(a,b){b=ba(b);return ra(a,b)||wa(a,b)}function wa(a,b){var c=a.currentStyle||a.style,d=c[b];d===g&&"function"==l(c.getPropertyValue)&&(d=c.getPropertyValue(b));return"inherit"!=d?d!==g?d:i:(c=V(a))?wa(c,b):i}
 function xa(a){if("function"==l(a.getBBox))try{var b=a.getBBox();if(b)return b}catch(c){}if("none"!=T(a,"display"))a=ua(a);else{var b=a.style,d=b.display,e=b.visibility,f=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=ua(a);b.display=d;b.position=f;b.visibility=e}return a}
-function X(a,b){function c(a){if("none"==W(a,"display"))return j;a=V(a);return!a||c(a)}function d(a){var b=xa(a);return 0<b.height&&0<b.width?h:fa(a.childNodes,function(a){return a.nodeType==K||U(a)&&d(a)})}function e(a){var b=V(a);if(b&&"hidden"==W(b,"overflow")){var c=xa(b),d=ta(b),a=ta(a);return d.x+c.width<a.x||d.y+c.height<a.y?j:e(b)}return h}if(!U(a))throw Error("Argument to isShown must be of type Element");if(U(a,"OPTION")||U(a,"OPTGROUP")){var f=ma(a,function(a){return U(a,"SELECT")});return!!f&&
-X(f,h)}if(U(a,"MAP")){if(!a.name)return j;f=L(a);f=f.evaluate?pa('/descendant::*[@usemap = "#'+a.name+'"]',f):la(f,function(b){var c;if(c=U(b))8==b.nodeType?b=i:(c="usemap","style"==c?(b=p(b.style.cssText).toLowerCase(),b=";"==b.charAt(b.length-1)?b:b+";"):(b=b.getAttributeNode(c),b=!b?i:A(va,c)?"true":b.specified?b.value:i)),c=b=="#"+a.name;return c});return!!f&&X(f,b)}return U(a,"AREA")?(f=ma(a,function(a){return U(a,"MAP")}),!!f&&X(f,b)):U(a,"INPUT")&&"hidden"==a.type.toLowerCase()||U(a,"NOSCRIPT")||
+function X(a,b){function c(a){if("none"==W(a,"display"))return j;a=V(a);return!a||c(a)}function d(a){var b=xa(a);return 0<b.height&&0<b.width?h:fa(a.childNodes,function (a){return a.nodeType==K||U(a)&&d(a)})}function e(a){var b=V(a);if(b&&"hidden"==W(b,"overflow")){var c=xa(b),d=ta(b),a=ta(a);return d.x+c.width<a.x||d.y+c.height<a.y?j:e(b)}return h}if(!U(a))throw Error("Argument to isShown must be of type Element");if(U(a,"OPTION")||U(a,"OPTGROUP")){var f=ma(a,function (a){return U(a,"SELECT")});return!!f&&
+X(f,h)}if(U(a,"MAP")){if(!a.name)return j;f=L(a);f=f.evaluate?pa('/descendant::*[@usemap = "#'+a.name+'"]',f):la(f,function (b){var c;if(c=U(b))8==b.nodeType?b=i:(c="usemap","style"==c?(b=p(b.style.cssText).toLowerCase(),b=";"==b.charAt(b.length-1)?b:b+";"):(b=b.getAttributeNode(c),b=!b?i:A(va,c)?"true":b.specified?b.value:i)),c=b=="#"+a.name;return c});return!!f&&X(f,b)}return U(a,"AREA")?(f=ma(a,function (a){return U(a,"MAP")}),!!f&&X(f,b)):U(a,"INPUT")&&"hidden"==a.type.toLowerCase()||U(a,"NOSCRIPT")||
 "hidden"==W(a,"visibility")||!c(a)||!b&&0==ya(a)||!d(a)||!e(a)?j:h}function za(a){return a.replace(/^[^\S\xa0]+|[^\S\xa0]+$/g,"")}
-function Aa(a,b){if(U(a,"BR"))b.push("");else{var c=U(a,"TD"),d=W(a,"display"),e=!c&&!A(Ba,d);e&&!/^[\s\xa0]*$/.test(b[b.length-1]||"")&&b.push("");var f=X(a),r=i,t=i;f&&(r=W(a,"white-space"),t=W(a,"text-transform"));ea(a.childNodes,function(a){a.nodeType==K&&f?Ca(a,b,r,t):U(a)&&Aa(a,b)});var O=b[b.length-1]||"";if((c||"table-cell"==d)&&O&&!o(O))b[b.length-1]+=" ";e&&!/^[\s\xa0]*$/.test(O)&&b.push("")}}var Ba="inline,inline-block,inline-table,none,table-cell,table-column,table-column-group".split(",");
-function Ca(a,b,c,d){a=a.nodeValue.replace(/\u200b/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[\ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(/(^|\s)(\S)/g,function(a,b,c){return b+c.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";o(c)&&0==a.lastIndexOf(" ",0)&&(a=a.substr(1));b.push(c+a)}
+function Aa(a,b){if(U(a,"BR"))b.push("");else{var c=U(a,"TD"),d=W(a,"display"),e=!c&&!A(Ba,d);e&&!/^[\s\xa0]*$/.test(b[b.length-1]||"")&&b.push("");var f=X(a),r=i,t=i;f&&(r=W(a,"white-space"),t=W(a,"text-transform"));ea(a.childNodes,function (a){a.nodeType==K&&f?Ca(a,b,r,t):U(a)&&Aa(a,b)});var O=b[b.length-1]||"";if((c||"table-cell"==d)&&O&&!o(O))b[b.length-1]+=" ";e&&!/^[\s\xa0]*$/.test(O)&&b.push("")}}var Ba="inline,inline-block,inline-table,none,table-cell,table-column,table-column-group".split(",");
+function Ca(a,b,c,d){a=a.nodeValue.replace(/\u200b/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[\ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(/(^|\s)(\S)/g,function (a,b,c){return b+c.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";o(c)&&0==a.lastIndexOf(" ",0)&&(a=a.substr(1));b.push(c+a)}
 function ya(a){var b=1,c=W(a,"opacity");c&&(b=Number(c));(a=V(a))&&(b*=ya(a));return b};function Da(a){var b;a:{for(b=a;b;){if(b.tagName&&"head"==b.tagName.toLowerCase()){b=h;break a}try{b=b.parentNode}catch(c){break}}b=j}if(b)return b=L(a),"TITLE"==a.tagName.toUpperCase()&&(b?b.parentWindow||b.defaultView:window)==da.top?p(b.title):"";b=[];Aa(a,b);var d=b,a=d.length;b=Array(a);for(var d=m(d)?d.split(""):d,e=0;e<a;e++)e in d&&(b[e]=za.call(g,d[e]));return za(b.join("\n")).replace(/\xa0/g," ")}var Y=["_"],Z=k;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);
 for(var $;Y.length&&($=Y.shift());)!Y.length&&Da!==g?Z[$]=Da:Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
 
-atom.isElementEnabled = function(element, window){return function(){var e=this;function f(a,c){function b(){}b.prototype=c.prototype;a.d=c.prototype;a.prototype=new b};function g(a,c){for(var b=1;b<arguments.length;b++)var d=(""+arguments[b]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a};var h,i="",j=/rv\:([^\);]+)(\)|;)/.exec(e.navigator?e.navigator.userAgent:null);h=i=j?j[1]:"";var k={};function l(a,c){this.code=a;this.message=c||"";this.name=m[a]||m[13];var b=Error(this.message);b.name=this.name;this.stack=b.stack||""}f(l,Error);
+atom.isElementEnabled = function (element, window){return function(){var e=this;function f(a,c){function b(){}b.prototype=c.prototype;a.d=c.prototype;a.prototype=new b};function g(a,c){for(var b=1;b<arguments.length;b++)var d=(""+arguments[b]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a};var h,i="",j=/rv\:([^\);]+)(\)|;)/.exec(e.navigator?e.navigator.userAgent:null);h=i=j?j[1]:"";var k={};function l(a,c){this.code=a;this.message=c||"";this.name=m[a]||m[13];var b=Error(this.message);b.name=this.name;this.stack=b.stack||""}f(l,Error);
 var m={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"};
 l.prototype.toString=function(){return"["+this.name+"] "+this.message};function n(a){this.stack=Error().stack||"";a&&(this.message=""+a)}f(n,Error);n.prototype.name="CustomError";function o(a,c){c.unshift(a);n.call(this,g.apply(null,c));c.shift()}f(o,n);o.prototype.name="AssertionError";function p(a,c){var b;a:if("string"==typeof a)b="string"!=typeof c||1!=c.length?-1:a.indexOf(c,0);else{for(b=0;b<a.length;b++)if(b in a&&a[b]===c)break a;b=-1}return 0<=b};if(!k["1.9.1"]){for(var q=0,r=(""+h).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),s="1.9.1".replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),t=Math.max(r.length,s.length),u=0;0==q&&u<t;u++){var v=r[u]||"",w=s[u]||"",x=RegExp("(\\d*)(\\D*)","g"),z=RegExp("(\\d*)(\\D*)","g");do{var A=x.exec(v)||["","",""],B=z.exec(w)||["","",""];if(0==A[0].length&&0==B[0].length)break;q=((0==A[1].length?0:parseInt(A[1],10))<(0==B[1].length?0:parseInt(B[1],10))?-1:(0==A[1].length?0:parseInt(A[1],10))>(0==B[1].length?
-0:parseInt(B[1],10))?1:0)||((0==A[2].length)<(0==B[2].length)?-1:(0==A[2].length)>(0==B[2].length)?1:0)||(A[2]<B[2]?-1:A[2]>B[2]?1:0)}while(0==q)}k["1.9.1"]=0<=q};(function(){var a=e.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(c){return!1}var b=a.classes,a=a.interfaces;b["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);b["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function C(a,c,b,d,y){this.b=!!c;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=y?y:this.c||0;this.b&&(this.depth*=-1)}f(C,function(){});C.prototype.a=null;C.prototype.c=0;f(function(a,c,b,d){C.call(this,a,c,0,null,d)},C);var D={"class":"className",readonly:"readOnly"},E=["checked","disabled","draggable","hidden"],F="BUTTON,INPUT,OPTGROUP,OPTION,SELECT,TEXTAREA".split(",");function G(a){var c=a.tagName.toUpperCase();if(p(F,c)){var b;b=D.disabled||"disabled";var d=a[b];b=void 0===d&&p(E,b)?!1:d;a=b?!1:a.parentNode&&1==a.parentNode.nodeType&&"OPTGROUP"==c||"OPTION"==c?G(a.parentNode):!0}else a=!0;return a};var H=G,I=["_"],J=e;!(I[0]in J)&&J.execScript&&J.execScript("var "+I[0]);for(var K;I.length&&(K=I.shift());)!I.length&&void 0!==H?J[K]=H:J=J[K]?J[K]:J[K]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
+0:parseInt(B[1],10))?1:0)||((0==A[2].length)<(0==B[2].length)?-1:(0==A[2].length)>(0==B[2].length)?1:0)||(A[2]<B[2]?-1:A[2]>B[2]?1:0)}while(0==q)}k["1.9.1"]=0<=q};(function(){var a=e.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(c){return!1}var b=a.classes,a=a.interfaces;b["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);b["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function C(a,c,b,d,y){this.b=!!c;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=y?y:this.c||0;this.b&&(this.depth*=-1)}f(C,function(){});C.prototype.a=null;C.prototype.c=0;f(function (a,c,b,d){C.call(this,a,c,0,null,d)},C);var D={"class":"className",readonly:"readOnly"},E=["checked","disabled","draggable","hidden"],F="BUTTON,INPUT,OPTGROUP,OPTION,SELECT,TEXTAREA".split(",");function G(a){var c=a.tagName.toUpperCase();if(p(F,c)){var b;b=D.disabled||"disabled";var d=a[b];b=void 0===d&&p(E,b)?!1:d;a=b?!1:a.parentNode&&1==a.parentNode.nodeType&&"OPTGROUP"==c||"OPTION"==c?G(a.parentNode):!0}else a=!0;return a};var H=G,I=["_"],J=e;!(I[0]in J)&&J.execScript&&J.execScript("var "+I[0]);for(var K;I.length&&(K=I.shift());)!I.length&&void 0!==H?J[K]=H:J=J[K]?J[K]:J[K]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
 
-atom.isElementSelected = function(element, window){return function(){var f=!1,g=this;function h(a,b){function c(){}c.prototype=b.prototype;a.d=b.prototype;a.prototype=new c};function i(a,b){for(var c=1;c<arguments.length;c++)var d=(""+arguments[c]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a};var k,l="",m=/rv\:([^\);]+)(\)|;)/.exec(g.navigator?g.navigator.userAgent:null);k=l=m?m[1]:"";var n={};function o(a,b){this.code=a;this.message=b||"";this.name=p[a]||p[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}h(o,Error);
+atom.isElementSelected = function (element, window){return function(){var f=!1,g=this;function h(a,b){function c(){}c.prototype=b.prototype;a.d=b.prototype;a.prototype=new c};function i(a,b){for(var c=1;c<arguments.length;c++)var d=(""+arguments[c]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a};var k,l="",m=/rv\:([^\);]+)(\)|;)/.exec(g.navigator?g.navigator.userAgent:null);k=l=m?m[1]:"";var n={};function o(a,b){this.code=a;this.message=b||"";this.name=p[a]||p[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}h(o,Error);
 var p={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"};
 o.prototype.toString=function(){return"["+this.name+"] "+this.message};function q(a){this.stack=Error().stack||"";a&&(this.message=""+a)}h(q,Error);q.prototype.name="CustomError";function r(a,b){b.unshift(a);q.call(this,i.apply(null,b));b.shift()}h(r,q);r.prototype.name="AssertionError";if(!n["1.9.1"]){for(var s=0,t=(""+k).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),u="1.9.1".replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),v=Math.max(t.length,u.length),w=0;0==s&&w<v;w++){var x=t[w]||"",y=u[w]||"",z=RegExp("(\\d*)(\\D*)","g"),A=RegExp("(\\d*)(\\D*)","g");do{var B=z.exec(x)||["","",""],C=A.exec(y)||["","",""];if(0==B[0].length&&0==C[0].length)break;s=((0==B[1].length?0:parseInt(B[1],10))<(0==C[1].length?0:parseInt(C[1],10))?-1:(0==B[1].length?0:parseInt(B[1],10))>(0==C[1].length?
-0:parseInt(C[1],10))?1:0)||((0==B[2].length)<(0==C[2].length)?-1:(0==B[2].length)>(0==C[2].length)?1:0)||(B[2]<C[2]?-1:B[2]>C[2]?1:0)}while(0==s)}n["1.9.1"]=0<=s};var D={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},E={IMG:" ",BR:"\n"};function F(a,b,c){if(!(a.nodeName in D))if(3==a.nodeType)c?b.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in E)b.push(E[a.nodeName]);else for(a=a.firstChild;a;)F(a,b,c),a=a.nextSibling};(function(){var a=g.Components;if(!a)return f;try{if(!a.classes)return f}catch(b){return f}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function G(a,b,c,d,e){this.b=!!b;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=e?e:this.c||0;this.b&&(this.depth*=-1)}h(G,function(){});G.prototype.a=null;G.prototype.c=0;h(function(a,b,c,d){G.call(this,a,b,0,null,d)},G);function H(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}function I(a){return H(a,"OPTION")?!0:H(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):f}var J={"class":"className",readonly:"readOnly"},K=["checked","disabled","draggable","hidden"];function L(a){if(I(a)){if(!I(a))throw new o(15,"Element is not selectable");var b="selected",c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";var c=b,d=J[c]||c,b=a[d],e;if(e=void 0===b){b:if("string"==typeof K)d="string"!=typeof d||1!=d.length?-1:K.indexOf(d,0);else{for(e=0;e<K.length;e++)if(e in K&&K[e]===d){d=e;break b}d=-1}e=0<=d}if(e)a=f;else{if(d="value"==c)if(d=H(a,"OPTION")){var j;c=c.toLowerCase();if(a.hasAttribute)j=a.hasAttribute(c);else try{j=a.attributes[c].specified}catch(P){j=
+0:parseInt(C[1],10))?1:0)||((0==B[2].length)<(0==C[2].length)?-1:(0==B[2].length)>(0==C[2].length)?1:0)||(B[2]<C[2]?-1:B[2]>C[2]?1:0)}while(0==s)}n["1.9.1"]=0<=s};var D={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},E={IMG:" ",BR:"\n"};function F(a,b,c){if(!(a.nodeName in D))if(3==a.nodeType)c?b.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in E)b.push(E[a.nodeName]);else for(a=a.firstChild;a;)F(a,b,c),a=a.nextSibling};(function(){var a=g.Components;if(!a)return f;try{if(!a.classes)return f}catch(b){return f}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function G(a,b,c,d,e){this.b=!!b;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=e?e:this.c||0;this.b&&(this.depth*=-1)}h(G,function(){});G.prototype.a=null;G.prototype.c=0;h(function (a,b,c,d){G.call(this,a,b,0,null,d)},G);function H(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}function I(a){return H(a,"OPTION")?!0:H(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):f}var J={"class":"className",readonly:"readOnly"},K=["checked","disabled","draggable","hidden"];function L(a){if(I(a)){if(!I(a))throw new o(15,"Element is not selectable");var b="selected",c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";var c=b,d=J[c]||c,b=a[d],e;if(e=void 0===b){b:if("string"==typeof K)d="string"!=typeof d||1!=d.length?-1:K.indexOf(d,0);else{for(e=0;e<K.length;e++)if(e in K&&K[e]===d){d=e;break b}d=-1}e=0<=d}if(e)a=f;else{if(d="value"==c)if(d=H(a,"OPTION")){var j;c=c.toLowerCase();if(a.hasAttribute)j=a.hasAttribute(c);else try{j=a.attributes[c].specified}catch(P){j=
 f}d=!j}d&&(j=[],F(a,j,f),b=j.join(""));a=b}a=!!a}else a=f;return a}var M=["_"],N=g;!(M[0]in N)&&N.execScript&&N.execScript("var "+M[0]);for(var O;M.length&&(O=M.shift());)!M.length&&void 0!==L?N[O]=L:N=N[O]?N[O]:N[O]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
 
-atom.isElementDisplayed = function(element, window){return function(){function h(a){return function(){return a}}var k=this;
+atom.isElementDisplayed = function (element, window){return function(){function h(a){return function(){return a}}var k=this;
 function m(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
 else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function n(a){return"string"==typeof a};function q(a){var b=0,c=String(r).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");a=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");for(var d=Math.max(c.length,a.length),e=0;0==b&&e<d;e++){var f=c[e]||"",g=a[e]||"",w=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var l=w.exec(f)||["","",""],v=p.exec(g)||["","",""];if(0==l[0].length&&0==v[0].length)break;b=((0==l[1].length?0:parseInt(l[1],10))<(0==v[1].length?0:parseInt(v[1],10))?-1:(0==l[1].length?0:parseInt(l[1],10))>(0==v[1].length?
-0:parseInt(v[1],10))?1:0)||((0==l[2].length)<(0==v[2].length)?-1:(0==l[2].length)>(0==v[2].length)?1:0)||(l[2]<v[2]?-1:l[2]>v[2]?1:0)}while(0==b)}return b}function aa(a){return String(a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()})};var s=Array.prototype;function t(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)e in d&&b.call(void 0,d[e],e,a)}function ba(a,b){if(a.reduce)return a.reduce(b,"");var c="";t(a,function(d,e){c=b.call(void 0,c,d,e,a)});return c}function ca(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a))return!0;return!1}
+0:parseInt(v[1],10))?1:0)||((0==l[2].length)<(0==v[2].length)?-1:(0==l[2].length)>(0==v[2].length)?1:0)||(l[2]<v[2]?-1:l[2]>v[2]?1:0)}while(0==b)}return b}function aa(a){return String(a).replace(/\-([a-z])/g,function (a,c){return c.toUpperCase()})};var s=Array.prototype;function t(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)e in d&&b.call(void 0,d[e],e,a)}function ba(a,b){if(a.reduce)return a.reduce(b,"");var c="";t(a,function (d,e){c=b.call(void 0,c,d,e,a)});return c}function ca(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a))return!0;return!1}
 function da(a,b){var c;a:if(n(a))c=n(b)&&1==b.length?a.indexOf(b,0):-1;else{for(c=0;c<a.length;c++)if(c in a&&a[c]===b)break a;c=-1}return 0<=c}function ea(a,b,c){return 2>=arguments.length?s.slice.call(a,b):s.slice.call(a,b,c)};var u={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",
 darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",
 ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",
 lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",
 moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",
 seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};var fa="background-color border-top-color border-right-color border-bottom-color border-left-color color outline-color".split(" "),ga=/#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/;function ha(a){if(!x.test(a))throw Error("'"+a+"' is not a valid hex color");4==a.length&&(a=a.replace(ga,"#$1$1$2$2$3$3"));return a.toLowerCase()}var x=/^#(?:[0-9a-f]{3}){1,2}$/i,ia=/^(?:rgba)?\((\d{1,3}),\s?(\d{1,3}),\s?(\d{1,3}),\s?(0|1|0\.\d*)\)$/i;
-function ja(a){var b=a.match(ia);if(b){a=Number(b[1]);var c=Number(b[2]),d=Number(b[3]),b=Number(b[4]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=d&&255>=d&&0<=b&&1>=b)return[a,c,d,b]}return[]}var ka=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;function la(a){var b=a.match(ka);if(b){a=Number(b[1]);var c=Number(b[2]),b=Number(b[3]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=b&&255>=b)return[a,c,b]}return[]};function y(a,b){this.code=a;this.state=z[a]||ma;this.message=b||"";var c=this.state.replace(/((?:^|\s+)[a-z])/g,function(a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")}),d=c.length-5;if(0>d||c.indexOf("Error",d)!=d)c+="Error";this.name=c;c=Error(this.message);c.name=this.name;this.stack=c.stack||""}(function(){var a=Error;function b(){}b.prototype=a.prototype;y.I=a.prototype;y.prototype=new b})();
+function ja(a){var b=a.match(ia);if(b){a=Number(b[1]);var c=Number(b[2]),d=Number(b[3]),b=Number(b[4]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=d&&255>=d&&0<=b&&1>=b)return[a,c,d,b]}return[]}var ka=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;function la(a){var b=a.match(ka);if(b){a=Number(b[1]);var c=Number(b[2]),b=Number(b[3]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=b&&255>=b)return[a,c,b]}return[]};function y(a,b){this.code=a;this.state=z[a]||ma;this.message=b||"";var c=this.state.replace(/((?:^|\s+)[a-z])/g,function (a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")}),d=c.length-5;if(0>d||c.indexOf("Error",d)!=d)c+="Error";this.name=c;c=Error(this.message);c.name=this.name;this.stack=c.stack||""}(function(){var a=Error;function b(){}b.prototype=a.prototype;y.I=a.prototype;y.prototype=new b})();
 var ma="unknown error",z={15:"element not selectable",11:"element not visible",31:"ime engine activation failed",30:"ime not available",24:"invalid cookie domain",29:"invalid element coordinates",12:"invalid element state",32:"invalid selector",51:"invalid selector",52:"invalid selector",17:"javascript error",405:"unsupported operation",34:"move target out of bounds",27:"no such alert",7:"no such element",8:"no such frame",23:"no such window",28:"script timeout",33:"session not created",10:"stale element reference",
 0:"success",21:"timeout",25:"unable to set cookie",26:"unexpected alert open"};z[13]=ma;z[9]="unknown command";y.prototype.toString=function(){return this.name+": "+this.message};var r,na="",oa=/rv\:([^\);]+)(\)|;)/.exec(k.navigator?k.navigator.userAgent:null);r=na=oa?oa[1]:"";var A={};var B;A["1.9.1"]||(A["1.9.1"]=0<=q("1.9.1"));function C(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}C.prototype.toString=function(){return"("+this.x+", "+this.y+")"};C.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};C.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};C.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};D.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};var pa=3;function E(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a}
 function qa(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=1==a.nodeType,d=1==b.nodeType;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,f=b.parentNode;return e==f?ra(a,b):!c&&E(e,b)?-1*sa(a,b):!d&&E(f,a)?sa(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=F(a);c=d.createRange();c.selectNode(a);c.collapse(!0);d=d.createRange();d.selectNode(b);d.collapse(!0);
 return c.compareBoundaryPoints(k.Range.START_TO_END,d)}function sa(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return ra(d,a)}function ra(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1}function F(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function ta(a,b){a=a.parentNode;for(var c=0;a;){if(b(a))return a;a=a.parentNode;c++}return null}function G(a){this.p=a||k.document||document}
 function ua(a){var b=a.p;a="CSS1Compat"==b.compatMode?b.documentElement:b.body;b=b.parentWindow||b.defaultView;return new C(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)}G.prototype.contains=E;function H(a){var b=null,c=a.nodeType;1==c&&(b=a.textContent,b=void 0==b||null==b?a.innerText:b,b=void 0==b||null==b?"":b);if("string"!=typeof b)if(9==c||1==c){a=9==c?a.documentElement:a.firstChild;for(var c=0,d=[],b="";a;){do 1!=a.nodeType&&(b+=a.nodeValue),d[c++]=a;while(a=a.firstChild);for(;c&&!(a=d[--c].nextSibling););}}else b=a.nodeValue;return""+b}
 function I(a,b,c){if(null===b)return!0;try{if(!a.getAttribute)return!1}catch(d){return!1}return null==c?!!a.getAttribute(b):a.getAttribute(b,2)==c}function J(a,b,c,d,e){return va.call(null,a,b,n(c)?c:null,n(d)?d:null,e||new K)}
-function va(a,b,c,d,e){b.getElementsByName&&d&&"name"==c?(b=b.getElementsByName(d),t(b,function(b){a.matches(b)&&e.add(b)})):b.getElementsByClassName&&d&&"class"==c?(b=b.getElementsByClassName(d),t(b,function(b){b.className==d&&a.matches(b)&&e.add(b)})):b.getElementsByTagName&&(b=b.getElementsByTagName(a.getName()),t(b,function(a){I(a,c,d)&&e.add(a)}));return e}function wa(a,b,c,d,e){for(b=b.firstChild;b;b=b.nextSibling)I(b,c,d)&&a.matches(b)&&e.add(b);return e};function K(){this.d=this.c=null;this.g=0}function xa(a){this.m=a;this.next=this.i=null}K.prototype.unshift=function(a){a=new xa(a);a.next=this.c;this.d?this.c.i=a:this.c=this.d=a;this.c=a;this.g++};K.prototype.add=function(a){a=new xa(a);a.i=this.d;this.c?this.d.next=a:this.c=this.d=a;this.d=a;this.g++};function ya(a){return(a=a.c)?a.m:null}function L(a){return new za(a,!1)}function za(a,b){this.F=a;this.j=(this.n=b)?a.d:a.c;this.r=null}
+function va(a,b,c,d,e){b.getElementsByName&&d&&"name"==c?(b=b.getElementsByName(d),t(b,function (b){a.matches(b)&&e.add(b)})):b.getElementsByClassName&&d&&"class"==c?(b=b.getElementsByClassName(d),t(b,function (b){b.className==d&&a.matches(b)&&e.add(b)})):b.getElementsByTagName&&(b=b.getElementsByTagName(a.getName()),t(b,function (a){I(a,c,d)&&e.add(a)}));return e}function wa(a,b,c,d,e){for(b=b.firstChild;b;b=b.nextSibling)I(b,c,d)&&a.matches(b)&&e.add(b);return e};function K(){this.d=this.c=null;this.g=0}function xa(a){this.m=a;this.next=this.i=null}K.prototype.unshift=function (a){a=new xa(a);a.next=this.c;this.d?this.c.i=a:this.c=this.d=a;this.c=a;this.g++};K.prototype.add=function (a){a=new xa(a);a.i=this.d;this.c?this.d.next=a:this.c=this.d=a;this.d=a;this.g++};function ya(a){return(a=a.c)?a.m:null}function L(a){return new za(a,!1)}function za(a,b){this.F=a;this.j=(this.n=b)?a.d:a.c;this.r=null}
 za.prototype.next=function(){var a=this.j;if(null==a)return null;var b=this.r=a;this.j=this.n?a.i:a.next;return b.m};function M(a,b,c,d,e){b=b.evaluate(d);c=c.evaluate(d);var f;if(b instanceof K&&c instanceof K){e=L(b);for(d=e.next();d;d=e.next())for(b=L(c),f=b.next();f;f=b.next())if(a(H(d),H(f)))return!0;return!1}if(b instanceof K||c instanceof K){b instanceof K?e=b:(e=c,c=b);e=L(e);b=typeof c;for(d=e.next();d;d=e.next()){switch(b){case "number":d=+H(d);break;case "boolean":d=!!H(d);break;case "string":d=H(d);break;default:throw Error("Illegal primitive type for comparison.");}if(a(d,c))return!0}return!1}return e?
-"boolean"==typeof b||"boolean"==typeof c?a(!!b,!!c):"number"==typeof b||"number"==typeof c?a(+b,+c):a(b,c):a(+b,+c)}function Aa(a,b,c,d){this.s=a;this.H=b;this.o=c;this.q=d}Aa.prototype.toString=function(){return this.s};var Ba={};function N(a,b,c,d){if(a in Ba)throw Error("Binary operator already created: "+a);a=new Aa(a,b,c,d);Ba[a.toString()]=a}N("div",6,1,function(a,b,c){return a.b(c)/b.b(c)});N("mod",6,1,function(a,b,c){return a.b(c)%b.b(c)});N("*",6,1,function(a,b,c){return a.b(c)*b.b(c)});
-N("+",5,1,function(a,b,c){return a.b(c)+b.b(c)});N("-",5,1,function(a,b,c){return a.b(c)-b.b(c)});N("<",4,2,function(a,b,c){return M(function(a,b){return a<b},a,b,c)});N(">",4,2,function(a,b,c){return M(function(a,b){return a>b},a,b,c)});N("<=",4,2,function(a,b,c){return M(function(a,b){return a<=b},a,b,c)});N(">=",4,2,function(a,b,c){return M(function(a,b){return a>=b},a,b,c)});N("=",3,2,function(a,b,c){return M(function(a,b){return a==b},a,b,c,!0)});
-N("!=",3,2,function(a,b,c){return M(function(a,b){return a!=b},a,b,c,!0)});N("and",2,2,function(a,b,c){return a.f(c)&&b.f(c)});N("or",1,2,function(a,b,c){return a.f(c)||b.f(c)});function Ca(a,b,c,d,e,f,g,w,p){this.h=a;this.o=b;this.D=c;this.C=d;this.B=e;this.q=f;this.A=g;this.w=void 0!==w?w:g;this.G=!!p}Ca.prototype.toString=function(){return this.h};var Da={};function O(a,b,c,d,e,f,g,w){if(a in Da)throw Error("Function already created: "+a+".");Da[a]=new Ca(a,b,c,d,!1,e,f,g,w)}O("boolean",2,!1,!1,function(a,b){return b.f(a)},1);O("ceiling",1,!1,!1,function(a,b){return Math.ceil(b.b(a))},1);
-O("concat",3,!1,!1,function(a,b){var c=ea(arguments,1);return ba(c,function(b,c){return b+c.a(a)})},2,null);O("contains",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return-1!=b.indexOf(a)},2);O("count",1,!1,!1,function(a,b){return b.evaluate(a).g},1,1,!0);O("false",2,!1,!1,h(!1),0);O("floor",1,!1,!1,function(a,b){return Math.floor(b.b(a))},1);
-O("id",4,!1,!1,function(a,b){var c=a.e(),d=9==c.nodeType?c:c.ownerDocument,c=b.a(a).split(/\s+/),e=[];t(c,function(a){(a=d.getElementById(a))&&!da(e,a)&&e.push(a)});e.sort(qa);var f=new K;t(e,function(a){f.add(a)});return f},1);O("lang",2,!1,!1,h(!1),1);O("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.u()},0);O("local-name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);
-O("name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);O("namespace-uri",3,!0,!1,h(""),0,1,!0);O("normalize-space",3,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);O("not",2,!1,!1,function(a,b){return!b.f(a)},1);O("number",1,!1,!0,function(a,b){return b?b.b(a):+H(a.e())},0,1);O("position",1,!0,!1,function(a){return a.v()},0);O("round",1,!1,!1,function(a,b){return Math.round(b.b(a))},1);
-O("starts-with",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return 0==b.lastIndexOf(a,0)},2);O("string",3,!1,!0,function(a,b){return b?b.a(a):H(a.e())},0,1);O("string-length",1,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).length},0,1);
-O("substring",3,!1,!1,function(a,b,c,d){c=c.b(a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?d.b(a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=b.a(a);if(Infinity==d)return a.substring(e);b=Math.round(d);return a.substring(e,c+b)},2,3);O("substring-after",3,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2);
-O("substring-before",3,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);a=b.indexOf(a);return-1==a?"":b.substring(0,a)},2);O("sum",1,!1,!1,function(a,b){for(var c=L(b.evaluate(a)),d=0,e=c.next();e;e=c.next())d+=+H(e);return d},1,1,!0);O("translate",3,!1,!1,function(a,b,c,d){b=b.a(a);c=c.a(a);var e=d.a(a);a=[];for(d=0;d<c.length;d++){var f=c.charAt(d);f in a||(a[f]=e.charAt(d))}c="";for(d=0;d<b.length;d++)f=b.charAt(d),c+=f in a?a[f]:f;return c},3);O("true",2,!1,!1,h(!0),0);function Ea(a,b,c,d){this.h=a;this.t=b;this.n=c;this.J=d}Ea.prototype.toString=function(){return this.h};var Fa={};function P(a,b,c,d){if(a in Fa)throw Error("Axis already created: "+a);Fa[a]=new Ea(a,b,c,!!d)}P("ancestor",function(a,b){for(var c=new K,d=b;d=d.parentNode;)a.matches(d)&&c.unshift(d);return c},!0);P("ancestor-or-self",function(a,b){var c=new K,d=b;do a.matches(d)&&c.unshift(d);while(d=d.parentNode);return c},!0);
-P("attribute",function(a,b){var c=new K,d=a.getName(),e=b.attributes;if(e)if("*"==d)for(var d=0,f;f=e[d];d++)c.add(f);else(f=e.getNamedItem(d))&&c.add(f);return c},!1);P("child",function(a,b,c,d,e){return wa.call(null,a,b,n(c)?c:null,n(d)?d:null,e||new K)},!1,!0);P("descendant",J,!1,!0);P("descendant-or-self",function(a,b,c,d){var e=new K;I(b,c,d)&&a.matches(b)&&e.add(b);return J(a,b,c,d,e)},!1,!0);
-P("following",function(a,b,c,d){var e=new K;do for(var f=b;f=f.nextSibling;)I(f,c,d)&&a.matches(f)&&e.add(f),e=J(a,f,c,d,e);while(b=b.parentNode);return e},!1,!0);P("following-sibling",function(a,b){for(var c=new K,d=b;d=d.nextSibling;)a.matches(d)&&c.add(d);return c},!1);P("namespace",function(){return new K},!1);P("parent",function(a,b){var c=new K;if(9==b.nodeType)return c;if(2==b.nodeType)return c.add(b.ownerElement),c;var d=b.parentNode;a.matches(d)&&c.add(d);return c},!1);
-P("preceding",function(a,b,c,d){var e=new K,f=[];do f.unshift(b);while(b=b.parentNode);for(var g=1,w=f.length;g<w;g++){var p=[];for(b=f[g];b=b.previousSibling;)p.unshift(b);for(var l=0,v=p.length;l<v;l++)b=p[l],I(b,c,d)&&a.matches(b)&&e.add(b),e=J(a,b,c,d,e)}return e},!0,!0);P("preceding-sibling",function(a,b){for(var c=new K,d=b;d=d.previousSibling;)a.matches(d)&&c.unshift(d);return c},!0);P("self",function(a,b){var c=new K;a.matches(b)&&c.add(b);return c},!1);var Ga=function(){var a={K:"http://www.w3.org/2000/svg"};return function(b){return a[b]||null}}();
+"boolean"==typeof b||"boolean"==typeof c?a(!!b,!!c):"number"==typeof b||"number"==typeof c?a(+b,+c):a(b,c):a(+b,+c)}function Aa(a,b,c,d){this.s=a;this.H=b;this.o=c;this.q=d}Aa.prototype.toString=function(){return this.s};var Ba={};function N(a,b,c,d){if(a in Ba)throw Error("Binary operator already created: "+a);a=new Aa(a,b,c,d);Ba[a.toString()]=a}N("div",6,1,function (a,b,c){return a.b(c)/b.b(c)});N("mod",6,1,function (a,b,c){return a.b(c)%b.b(c)});N("*",6,1,function (a,b,c){return a.b(c)*b.b(c)});
+N("+",5,1,function (a,b,c){return a.b(c)+b.b(c)});N("-",5,1,function (a,b,c){return a.b(c)-b.b(c)});N("<",4,2,function (a,b,c){return M(function (a,b){return a<b},a,b,c)});N(">",4,2,function (a,b,c){return M(function (a,b){return a>b},a,b,c)});N("<=",4,2,function (a,b,c){return M(function (a,b){return a<=b},a,b,c)});N(">=",4,2,function (a,b,c){return M(function (a,b){return a>=b},a,b,c)});N("=",3,2,function (a,b,c){return M(function (a,b){return a==b},a,b,c,!0)});
+N("!=",3,2,function (a,b,c){return M(function (a,b){return a!=b},a,b,c,!0)});N("and",2,2,function (a,b,c){return a.f(c)&&b.f(c)});N("or",1,2,function (a,b,c){return a.f(c)||b.f(c)});function Ca(a,b,c,d,e,f,g,w,p){this.h=a;this.o=b;this.D=c;this.C=d;this.B=e;this.q=f;this.A=g;this.w=void 0!==w?w:g;this.G=!!p}Ca.prototype.toString=function(){return this.h};var Da={};function O(a,b,c,d,e,f,g,w){if(a in Da)throw Error("Function already created: "+a+".");Da[a]=new Ca(a,b,c,d,!1,e,f,g,w)}O("boolean",2,!1,!1,function (a,b){return b.f(a)},1);O("ceiling",1,!1,!1,function (a,b){return Math.ceil(b.b(a))},1);
+O("concat",3,!1,!1,function (a,b){var c=ea(arguments,1);return ba(c,function (b,c){return b+c.a(a)})},2,null);O("contains",2,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);return-1!=b.indexOf(a)},2);O("count",1,!1,!1,function (a,b){return b.evaluate(a).g},1,1,!0);O("false",2,!1,!1,h(!1),0);O("floor",1,!1,!1,function (a,b){return Math.floor(b.b(a))},1);
+O("id",4,!1,!1,function (a,b){var c=a.e(),d=9==c.nodeType?c:c.ownerDocument,c=b.a(a).split(/\s+/),e=[];t(c,function (a){(a=d.getElementById(a))&&!da(e,a)&&e.push(a)});e.sort(qa);var f=new K;t(e,function (a){f.add(a)});return f},1);O("lang",2,!1,!1,h(!1),1);O("last",1,!0,!1,function (a){if(1!=arguments.length)throw Error("Function last expects ()");return a.u()},0);O("local-name",3,!1,!0,function (a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);
+O("name",3,!1,!0,function (a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);O("namespace-uri",3,!0,!1,h(""),0,1,!0);O("normalize-space",3,!1,!0,function (a,b){return(b?b.a(a):H(a.e())).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);O("not",2,!1,!1,function (a,b){return!b.f(a)},1);O("number",1,!1,!0,function (a,b){return b?b.b(a):+H(a.e())},0,1);O("position",1,!0,!1,function (a){return a.v()},0);O("round",1,!1,!1,function (a,b){return Math.round(b.b(a))},1);
+O("starts-with",2,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);return 0==b.lastIndexOf(a,0)},2);O("string",3,!1,!0,function (a,b){return b?b.a(a):H(a.e())},0,1);O("string-length",1,!1,!0,function (a,b){return(b?b.a(a):H(a.e())).length},0,1);
+O("substring",3,!1,!1,function (a,b,c,d){c=c.b(a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?d.b(a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=b.a(a);if(Infinity==d)return a.substring(e);b=Math.round(d);return a.substring(e,c+b)},2,3);O("substring-after",3,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2);
+O("substring-before",3,!1,!1,function (a,b,c){b=b.a(a);a=c.a(a);a=b.indexOf(a);return-1==a?"":b.substring(0,a)},2);O("sum",1,!1,!1,function (a,b){for(var c=L(b.evaluate(a)),d=0,e=c.next();e;e=c.next())d+=+H(e);return d},1,1,!0);O("translate",3,!1,!1,function (a,b,c,d){b=b.a(a);c=c.a(a);var e=d.a(a);a=[];for(d=0;d<c.length;d++){var f=c.charAt(d);f in a||(a[f]=e.charAt(d))}c="";for(d=0;d<b.length;d++)f=b.charAt(d),c+=f in a?a[f]:f;return c},3);O("true",2,!1,!1,h(!0),0);function Ea(a,b,c,d){this.h=a;this.t=b;this.n=c;this.J=d}Ea.prototype.toString=function(){return this.h};var Fa={};function P(a,b,c,d){if(a in Fa)throw Error("Axis already created: "+a);Fa[a]=new Ea(a,b,c,!!d)}P("ancestor",function (a,b){for(var c=new K,d=b;d=d.parentNode;)a.matches(d)&&c.unshift(d);return c},!0);P("ancestor-or-self",function (a,b){var c=new K,d=b;do a.matches(d)&&c.unshift(d);while(d=d.parentNode);return c},!0);
+P("attribute",function (a,b){var c=new K,d=a.getName(),e=b.attributes;if(e)if("*"==d)for(var d=0,f;f=e[d];d++)c.add(f);else(f=e.getNamedItem(d))&&c.add(f);return c},!1);P("child",function (a,b,c,d,e){return wa.call(null,a,b,n(c)?c:null,n(d)?d:null,e||new K)},!1,!0);P("descendant",J,!1,!0);P("descendant-or-self",function (a,b,c,d){var e=new K;I(b,c,d)&&a.matches(b)&&e.add(b);return J(a,b,c,d,e)},!1,!0);
+P("following",function (a,b,c,d){var e=new K;do for(var f=b;f=f.nextSibling;)I(f,c,d)&&a.matches(f)&&e.add(f),e=J(a,f,c,d,e);while(b=b.parentNode);return e},!1,!0);P("following-sibling",function (a,b){for(var c=new K,d=b;d=d.nextSibling;)a.matches(d)&&c.add(d);return c},!1);P("namespace",function(){return new K},!1);P("parent",function (a,b){var c=new K;if(9==b.nodeType)return c;if(2==b.nodeType)return c.add(b.ownerElement),c;var d=b.parentNode;a.matches(d)&&c.add(d);return c},!1);
+P("preceding",function (a,b,c,d){var e=new K,f=[];do f.unshift(b);while(b=b.parentNode);for(var g=1,w=f.length;g<w;g++){var p=[];for(b=f[g];b=b.previousSibling;)p.unshift(b);for(var l=0,v=p.length;l<v;l++)b=p[l],I(b,c,d)&&a.matches(b)&&e.add(b),e=J(a,b,c,d,e)}return e},!0,!0);P("preceding-sibling",function (a,b){for(var c=new K,d=b;d=d.previousSibling;)a.matches(d)&&c.unshift(d);return c},!0);P("self",function (a,b){var c=new K;a.matches(b)&&c.add(b);return c},!1);var Ga=function(){var a={K:"http://www.w3.org/2000/svg"};return function (b){return a[b]||null}}();
 function Ha(a,b){var c=function(){var c;a:{var e=F(b);try{var f=e.createNSResolver?e.createNSResolver(e.documentElement):Ga;c=e.evaluate(a,b,f,9,null);break a}catch(g){if("NS_ERROR_ILLEGAL_VALUE"!=g.name)throw new y(32,"Unable to locate an element with the xpath expression "+a+" because of the following error:\n"+g);}c=void 0}return c?c.singleNodeValue||null:b.selectSingleNode?(c=F(b),c.setProperty&&c.setProperty("SelectionLanguage","XPath"),b.selectSingleNode(a)):null}();if(null!==c&&(!c||1!=c.nodeType))throw new y(32,
-'The result of the xpath expression "'+a+'" is: '+c+". It should be an element.");return c};(function(){var a=k.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(b){return!1}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function Q(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}Q.prototype.toString=function(){return"("+this.left+", "+this.top+" - "+this.width+"w x "+this.height+"h)"};Q.prototype.contains=function(a){return a instanceof Q?this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};
+'The result of the xpath expression "'+a+'" is: '+c+". It should be an element.");return c};(function(){var a=k.Components;if(!a)return!1;try{if(!a.classes)return!1}catch(b){return!1}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function Q(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}Q.prototype.toString=function(){return"("+this.left+", "+this.top+" - "+this.width+"w x "+this.height+"h)"};Q.prototype.contains=function (a){return a instanceof Q?this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};
 Q.prototype.ceil=function(){this.left=Math.ceil(this.left);this.top=Math.ceil(this.top);this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};Q.prototype.floor=function(){this.left=Math.floor(this.left);this.top=Math.floor(this.top);this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};
 Q.prototype.round=function(){this.left=Math.round(this.left);this.top=Math.round(this.top);this.width=Math.round(this.width);this.height=Math.round(this.height);return this};function Ia(a,b){var c=F(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,null))?c[b]||c.getPropertyValue(b)||"":""}function R(a,b){return Ia(a,b)||(a.currentStyle?a.currentStyle[b]:null)||a.style&&a.style[b]}function Ja(a){var b;try{b=a.getBoundingClientRect()}catch(c){return{left:0,top:0,right:0,bottom:0}}return b}
 function Ka(a){var b=F(a),c=R(a,"position"),d="fixed"==c||"absolute"==c;for(a=a.parentNode;a&&a!=b;a=a.parentNode)if(c=R(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return null}
 function La(a){if(1==a.nodeType){var b;if(a.getBoundingClientRect)b=Ja(a),b=new C(b.left,b.top);else{b=ua(a?new G(F(a)):B||(B=new G));var c,d=F(a),e=R(a,"position"),f=d.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==e&&(c=d.getBoxObjectFor(a))&&(0>c.screenX||0>c.screenY),e=new C(0,0),g=(d?F(d):document).documentElement;if(a!=g)if(a.getBoundingClientRect)c=Ja(a),d=ua(d?new G(F(d)):B||(B=new G)),e.x=c.left+d.x,e.y=c.top+d.y;else if(d.getBoxObjectFor&&!f)c=d.getBoxObjectFor(a),d=d.getBoxObjectFor(g),
 e.x=c.screenX-d.screenX,e.y=c.screenY-d.screenY;else{c=a;do e.x+=c.offsetLeft,e.y+=c.offsetTop,c!=a&&(e.x+=c.clientLeft||0,e.y+=c.clientTop||0),c=c.offsetParent;while(c&&c!=a);for(c=a;(c=Ka(c))&&c!=d.body&&c!=g;)e.x-=c.scrollLeft,e.y-=c.scrollTop}b=new C(e.x-b.x,e.y-b.y)}A[12]||(A[12]=0<=q(12))?a=b:((c=R(a,"-moz-transform"))||(c=R(a,"transform")),a=c?(a=c.match(Ma))?new C(parseFloat(a[1]),parseFloat(a[2])):new C(0,0):new C(0,0),a=new C(b.x+a.x,b.y+a.y));return a}b="function"==m(a.k);c=a;a.targetTouches?
 c=a.targetTouches[0]:b&&a.k().targetTouches&&(c=a.k().targetTouches[0]);return new C(c.clientX,c.clientY)}var Ma=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;function S(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}function T(a){for(a=a.parentNode;a&&1!=a.nodeType&&9!=a.nodeType&&11!=a.nodeType;)a=a.parentNode;return S(a)?a:null}
 function U(a,b){var c=aa(b);if("float"==c||"cssFloat"==c||"styleFloat"==c)c="cssFloat";c=Ia(a,c)||Na(a,c);if(null===c)c=null;else if(da(fa,b)&&(x.test("#"==c.charAt(0)?c:"#"+c)||la(c).length||u&&u[c.toLowerCase()]||ja(c).length)){var d=ja(c);if(!d.length){a:if(d=la(c),!d.length){d=(d=u[c.toLowerCase()])?d:"#"==c.charAt(0)?c:"#"+c;if(x.test(d)&&(d=ha(d),d=ha(d),d=[parseInt(d.substr(1,2),16),parseInt(d.substr(3,2),16),parseInt(d.substr(5,2),16)],d.length))break a;d=[]}3==d.length&&d.push(1)}c=4!=d.length?
 c:"rgba("+d.join(", ")+")"}return c}function Na(a,b){var c=a.currentStyle||a.style,d=c[b];void 0===d&&"function"==m(c.getPropertyValue)&&(d=c.getPropertyValue(b));return"inherit"!=d?void 0!==d?d:null:(c=T(a))?Na(c,b):null}
-function V(a,b){function c(a){if("none"==U(a,"display"))return!1;a=T(a);return!a||c(a)}function d(a){if(a.hasAttribute){if(a.hasAttribute("hidden"))return!1}else return!0;a=T(a);return!a||d(a)}function e(a){var b=W(a);return 0<b.height&&0<b.width?!0:S(a,"PATH")&&(0<b.height||0<b.width)?(a=U(a,"stroke-width"),!!a&&0<parseInt(a,10)):"hidden"!=U(a,"overflow")&&ca(a.childNodes,function(a){return a.nodeType==pa||S(a)&&e(a)})}function f(a){var b=U(a,"-o-transform")||U(a,"-webkit-transform")||U(a,"-ms-transform")||
-U(a,"-moz-transform")||U(a,"transform");if(b&&"none"!==b)return b=La(a),a=W(a),0<=b.x+a.width&&0<=b.y+a.height?!0:!1;a=T(a);return!a||f(a)}if(!S(a))throw Error("Argument to isShown must be of type Element");if(S(a,"OPTION")||S(a,"OPTGROUP")){var g=ta(a,function(a){return S(a,"SELECT")});return!!g&&V(g,!0)}return(g=Oa(a))?!!g.l&&0<g.rect.width&&0<g.rect.height&&V(g.l,b):S(a,"INPUT")&&"hidden"==a.type.toLowerCase()||S(a,"NOSCRIPT")||"hidden"==U(a,"visibility")||!c(a)||!b&&0==Pa(a)||!d(a)||!e(a)||Qa(a)==
+function V(a,b){function c(a){if("none"==U(a,"display"))return!1;a=T(a);return!a||c(a)}function d(a){if(a.hasAttribute){if(a.hasAttribute("hidden"))return!1}else return!0;a=T(a);return!a||d(a)}function e(a){var b=W(a);return 0<b.height&&0<b.width?!0:S(a,"PATH")&&(0<b.height||0<b.width)?(a=U(a,"stroke-width"),!!a&&0<parseInt(a,10)):"hidden"!=U(a,"overflow")&&ca(a.childNodes,function (a){return a.nodeType==pa||S(a)&&e(a)})}function f(a){var b=U(a,"-o-transform")||U(a,"-webkit-transform")||U(a,"-ms-transform")||
+U(a,"-moz-transform")||U(a,"transform");if(b&&"none"!==b)return b=La(a),a=W(a),0<=b.x+a.width&&0<=b.y+a.height?!0:!1;a=T(a);return!a||f(a)}if(!S(a))throw Error("Argument to isShown must be of type Element");if(S(a,"OPTION")||S(a,"OPTGROUP")){var g=ta(a,function (a){return S(a,"SELECT")});return!!g&&V(g,!0)}return(g=Oa(a))?!!g.l&&0<g.rect.width&&0<g.rect.height&&V(g.l,b):S(a,"INPUT")&&"hidden"==a.type.toLowerCase()||S(a,"NOSCRIPT")||"hidden"==U(a,"visibility")||!c(a)||!b&&0==Pa(a)||!d(a)||!e(a)||Qa(a)==
 X?!1:f(a)}var X="hidden";
 function Qa(a){function b(a){var b=a;if("visible"==w)if(a==f)b=g;else if(a==g)return{x:"visible",y:"visible"};b={x:U(b,"overflow-x"),y:U(b,"overflow-y")};a==f&&(b.x="hidden"==b.x?"hidden":"auto",b.y="hidden"==b.y?"hidden":"auto");return b}function c(a){var b=U(a,"position");if("fixed"==b)return f;for(a=T(a);a&&a!=f&&(0==U(a,"display").lastIndexOf("inline",0)||"absolute"==b&&"static"==U(a,"position"));)a=T(a);return a}var d=W(a),e=F(a),f=e.documentElement,g=e.body||f,w=U(f,"overflow");for(a=c(a);a;a=
 c(a)){var p=W(a),e=b(a),l=d.left>=p.left+p.width,p=d.top>=p.top+p.height;if(l&&"hidden"==e.x||p&&"hidden"==e.y)return X;if(l&&"visible"!=e.x||p&&"visible"!=e.y)return Qa(a)==X?X:"scroll"}return"none"}
 function W(a){var b=Oa(a);if(b)return b.rect;if("function"==m(a.getBBox))try{var c=a.getBBox();return new Q(c.x,c.y,c.width,c.height)}catch(d){if("NS_ERROR_FAILURE"===d.name||-1!=d.message.indexOf("Component returned failure code: 0x80004005"))return new Q(0,0,0,0);throw d;}else{if(S(a,"HTML"))return a=((F(a)?F(a).parentWindow||F(a).defaultView:window)||window).document,a="CSS1Compat"==a.compatMode?a.documentElement:a.body,a=new D(a.clientWidth,a.clientHeight),new Q(0,0,a.width,a.height);b=La(a);
 return new Q(b.x,b.y,a.offsetWidth,a.offsetHeight)}}
 function Oa(a){var b=S(a,"MAP");if(!b&&!S(a,"AREA"))return null;var c=b?a:S(a.parentNode,"MAP")?a.parentNode:null,d=null,e=null;if(c&&c.name&&(d=Ha('/descendant::*[@usemap = "#'+c.name+'"]',F(c)))&&(e=W(d),!b&&"default"!=a.shape.toLowerCase())){var f=Ra(a);a=Math.min(Math.max(f.left,0),e.width);b=Math.min(Math.max(f.top,0),e.height);c=Math.min(f.width,e.width-a);f=Math.min(f.height,e.height-b);e=new Q(a+e.left,b+e.top,c,f)}return{l:d,rect:e||new Q(0,0,0,0)}}
 function Ra(a){var b=a.shape.toLowerCase();a=a.coords.split(",");if("rect"==b&&4==a.length){var b=a[0],c=a[1];return new Q(b,c,a[2]-b,a[3]-c)}if("circle"==b&&3==a.length)return b=a[2],new Q(a[0]-b,a[1]-b,2*b,2*b);if("poly"==b&&2<a.length){for(var b=a[0],c=a[1],d=b,e=c,f=2;f+1<a.length;f+=2)b=Math.min(b,a[f]),d=Math.max(d,a[f]),c=Math.min(c,a[f+1]),e=Math.max(e,a[f+1]);return new Q(b,c,d-b,e-c)}return new Q(0,0,0,0)}
 function Pa(a){var b=1,c=U(a,"opacity");c&&(b=Number(c));(a=T(a))&&(b*=Pa(a));return b};var Sa=V,Y=["_"],Z=k;Y[0]in Z||!Z.execScript||Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)Y.length||void 0===Sa?Z=Z[$]?Z[$]:Z[$]={}:Z[$]=Sa;; return this._.apply(null,arguments);}.apply({navigator:typeof window!=undefined?window.navigator:null,document:typeof window!=undefined?window.document:null}, arguments);}
--- a/testing/marionette/capture.js
+++ b/testing/marionette/capture.js
@@ -24,17 +24,17 @@ this.capture = {};
  *     The node to take a screenshot of.
  * @param {Array.<Node>=} highlights
  *     Optional array of nodes, around which a border will be marked to
  *     highlight them in the screenshot.
  *
  * @return {HTMLCanvasElement}
  *     The canvas element where the element has been painted on.
  */
-capture.element = function(node, highlights=[]) {
+capture.element = function (node, highlights=[]) {
   let doc = node.ownerDocument;
   let win = doc.defaultView;
   let rect = node.getBoundingClientRect();
 
   return capture.canvas(
       doc,
       rect.left,
       rect.top,
@@ -52,17 +52,17 @@ capture.element = function(node, highlig
  *     and a window for determining the offset of the viewport.
  * @param {Array.<Node>=} highlights
  *     Optional array of nodes, around which a border will be marked to
  *     highlight them in the screenshot.
  *
  * @return {HTMLCanvasElement}
  *     The canvas element where the viewport has been painted on.
  */
-capture.viewport = function(document, highlights=[]) {
+capture.viewport = function (document, highlights=[]) {
   let win = document.defaultView;
   let docEl = document.documentElement;
 
   return capture.canvas(
       document,
       win.pageXOffset,
       win.pageYOffset,
       docEl.clientWidth,
@@ -87,31 +87,31 @@ capture.viewport = function(document, hi
  * @param {Array.<Node>=} highlights
  *     Optional array of nodes, around which a border will be marked to
  *     highlight them in the screenshot.
  *
  * @return {HTMLCanvasElement}
  *     The canvas on which the selection from the window's framebuffer
  *     has been painted on.
  */
-capture.canvas = function(document, left, top, width, height, highlights=[]) {
+capture.canvas = function (document, left, top, width, height, highlights=[]) {
   let win = document.defaultView;
 
   let canvas = document.createElementNS(XHTML_NS, "canvas");
   canvas.width = width;
   canvas.height = height;
 
   let ctx = canvas.getContext(CONTEXT_2D);
   ctx.drawWindow(win, left, top, width, height, BG_COLOUR);
   ctx = capture.highlight_(ctx, highlights, top, left);
 
   return canvas;
 };
 
-capture.highlight_ = function(context, highlights, top=0, left=0) {
+capture.highlight_ = function (context, highlights, top=0, left=0) {
   if (!highlights) {
     return;
   }
 
   context.lineWidth = "2";
   context.strokeStyle = "red";
   context.save();
 
@@ -134,31 +134,31 @@ capture.highlight_ = function(context, h
  * Encode the contents of an HTMLCanvasElement to a Base64 encoded string.
  *
  * @param {HTMLCanvasElement} canvas
  *     The canvas to encode.
  *
  * @return {string}
  *     A Base64 encoded string.
  */
-capture.toBase64 = function(canvas) {
+capture.toBase64 = function (canvas) {
   let u = canvas.toDataURL(PNG_MIME);
   return u.substring(u.indexOf(",") + 1);
 };
 
 /**
 * Hash the contents of an HTMLCanvasElement to a SHA-256 hex digest.
 *
 * @param {HTMLCanvasElement} canvas
 *     The canvas to encode.
 *
 * @return {string}
 *     A hex digest of the SHA-256 hash of the base64 encoded string.
 */
-capture.toHash = function(canvas) {
+capture.toHash = function (canvas) {
   let u = capture.toBase64(canvas);
   let buffer = new TextEncoder("utf-8").encode(u);
   return crypto.subtle.digest("SHA-256", buffer).then(hash => hex(hash));
 };
 
 /**
 * Convert buffer into to hex.
 *
--- a/testing/marionette/cert.js
+++ b/testing/marionette/cert.js
@@ -48,17 +48,17 @@ this.cert = {
  * is not null, this functions acts as a NOOP.
  *
  * @param {cert.Override} service
  *     Service generator that registers and unregisters the XPCOM service.
  *
  * @throws {Components.Exception}
  *     If unable to register or initialise |service|.
  */
-cert.installOverride = function(service) {
+cert.installOverride = function (service) {
   if (this.currentOverride) {
     return;
   }
 
   service.register();
   cert.currentOverride = service;
 };
 
@@ -97,17 +97,17 @@ cert.InsecureSweepingOverride = function
   const DESC = "All-encompassing cert service that matches on a bitflag";
 
   // This needs to be an old-style class with a function constructor
   // and prototype assignment because... XPCOM.  Any attempt at
   // modernisation will be met with cryptic error messages which will
   // make your life miserable.
   let service = function() {};
   service.prototype = {
-    hasMatchingOverride: function(
+    hasMatchingOverride: function (
         aHostName, aPort, aCert, aOverrideBits, aIsTemporary) {
       aIsTemporary.value = false;
       aOverrideBits.value =
           cert.Error.Untrusted | cert.Error.Mismatch | cert.Error.Time;
 
       return true;
     },
 
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -53,17 +53,17 @@ MarionetteComponent.prototype = {
     {category: "command-line-handler", entry: "b-marionette"},
     {category: "profile-after-change", service: true}
   ],
   enabled: false,
   finalUiStartup: false,
   server: null,
 };
 
-MarionetteComponent.prototype.setupLogger_ = function(level) {
+MarionetteComponent.prototype.setupLogger_ = function (level) {
   let log = Log.repository.getLogger("Marionette");
   log.level = level;
   log.addAppender(new Log.DumpAppender());
   return log;
 };
 
 MarionetteComponent.prototype.determineLoggingLevel_ = function() {
   let level = Log.Level.Info;
@@ -93,32 +93,32 @@ MarionetteComponent.prototype.determineL
   return level;
 };
 
 MarionetteComponent.prototype.onSocketAccepted = function(
     socket, transport) {
   this.logger.info("onSocketAccepted for Marionette dummy socket");
 };
 
-MarionetteComponent.prototype.onStopListening = function(socket, status) {
+MarionetteComponent.prototype.onStopListening = function (socket, status) {
   this.logger.info(`onStopListening for Marionette dummy socket, code ${status}`);
   socket.close();
 };
 
 /** Check cmdLine argument for {@code --marionette}. */
-MarionetteComponent.prototype.handle = function(cmdLine) {
+MarionetteComponent.prototype.handle = function (cmdLine) {
   // if the CLI is there then lets do work otherwise nothing to see
   if (cmdLine.handleFlag("marionette", false)) {
     this.enabled = true;
     this.logger.debug("Marionette enabled via command-line flag");
     this.init();
   }
 };
 
-MarionetteComponent.prototype.observe = function(subj, topic, data) {
+MarionetteComponent.prototype.observe = function (subj, topic, data) {
   switch (topic) {
     case "profile-after-change":
       this.maybeReadPrefsFromEnvironment();
       // Using final-ui-startup as the xpcom category doesn't seem to work,
       // so we wait for that by adding an observer here.
       this.observerService.addObserver(this, "final-ui-startup", false);
 #ifdef ENABLE_MARIONETTE
       this.enabled = Preferences.get(ENABLED_PREF, false);
@@ -167,17 +167,17 @@ MarionetteComponent.prototype.maybeReadP
     if (prefs) {
       for (let prefName of Object.keys(prefs)) {
         Preferences.set("marionette." + prefName, prefs[prefName]);
       }
     }
   }
 }
 
-MarionetteComponent.prototype.suppressSafeModeDialog_ = function(win) {
+MarionetteComponent.prototype.suppressSafeModeDialog_ = function (win) {
   // Wait for the modal dialog to finish loading.
   win.addEventListener("load", function onload() {
     win.removeEventListener("load", onload);
 
     if (win.document.getElementById("safeModeDialog")) {
       // Accept the dialog to start in safe-mode
       win.setTimeout(() => {
         win.document.documentElement.getButton("accept").click();
--- a/testing/marionette/dispatcher.js
+++ b/testing/marionette/dispatcher.js
@@ -26,17 +26,17 @@ const logger = Log.repository.getLogger(
  *
  * @param {number} connId
  *     Unique identifier of the connection this dispatcher should handle.
  * @param {DebuggerTransport} transport
  *     Debugger transport connection to the client.
  * @param {function(): GeckoDriver} driverFactory
  *     A factory function that produces a GeckoDriver.
  */
-this.Dispatcher = function(connId, transport, driverFactory) {
+this.Dispatcher = function (connId, transport, driverFactory) {
   this.connId = connId;
   this.conn = transport;
 
   // transport hooks are Dispatcher#onPacket
   // and Dispatcher#onClosed
   this.conn.hooks = this;
 
   // callback for when connection is closed
@@ -50,17 +50,17 @@ this.Dispatcher = function(connId, trans
   // lookup of commands sent by server to client by message ID
   this.commands_ = new Map();
 };
 
 /**
  * Debugger transport callback that cleans up
  * after a connection is closed.
  */
-Dispatcher.prototype.onClosed = function(reason) {
+Dispatcher.prototype.onClosed = function (reason) {
   this.driver.sessionTearDown();
   if (this.onclose) {
     this.onclose(this);
   }
 };
 
 /**
  * Callback that receives data packets from the client.
@@ -69,17 +69,17 @@ Dispatcher.prototype.onClosed = function
  * to the client and run its callback, if any.  In case of a Command,
  * the corresponding is executed.
  *
  * @param {Array.<number, number, ?, ?>} data
  *     A four element array where the elements, in sequence, signifies
  *     message type, message ID, method name or error, and parameters
  *     or result.
  */
-Dispatcher.prototype.onPacket = function(data) {
+Dispatcher.prototype.onPacket = function (data) {
   let msg = Message.fromMsg(data);
   msg.origin = MessageOrigin.Client;
   this.log_(msg);
 
   if (msg instanceof Response) {
     let cmd = this.commands_.get(msg.id);
     this.commands_.delete(msg.id);
     cmd.onresponse(msg);
@@ -104,17 +104,17 @@ Dispatcher.prototype.onPacket = function
  *
  * Errors thrown in commands are marshaled and sent back, and if they
  * are not WebDriverError instances, they are additionally propagated and
  * reported to {@code Components.utils.reportError}.
  *
  * @param {Command} cmd
  *     The requested command to execute.
  */
-Dispatcher.prototype.execute = function(cmd) {
+Dispatcher.prototype.execute = function (cmd) {
   let resp = new Response(cmd.id, this.send.bind(this));
   let sendResponse = () => resp.sendConditionally(resp => !resp.sent);
   let sendError = resp.sendError.bind(resp);
 
   let req = Task.spawn(function*() {
     let fn = this.driver.commands[cmd.name];
     if (typeof fn == "undefined") {
       throw new UnknownCommandError(cmd.name);
@@ -129,17 +129,17 @@ Dispatcher.prototype.execute = function(
         resp.body = rv;
       }
     }
   }.bind(this));
 
   req.then(sendResponse, sendError).catch(error.report);
 };
 
-Dispatcher.prototype.sendError = function(err, cmdId) {
+Dispatcher.prototype.sendError = function (err, cmdId) {
   let resp = new Response(cmdId, this.send.bind(this));
   resp.sendError(err);
 };
 
 // Convenience methods:
 
 /**
  * When a client connects we send across a JSON Object defining the
@@ -165,17 +165,17 @@ Dispatcher.prototype.sayHello = function
  * that is used to distinguish the asynchronous responses.
  *
  * Whilst responses to commands are synchronous and must be sent in the
  * correct order.
  *
  * @param {Command,Response} msg
  *     The command or response to send.
  */
-Dispatcher.prototype.send = function(msg) {
+Dispatcher.prototype.send = function (msg) {
   msg.origin = MessageOrigin.Server;
   if (msg instanceof Command) {
     this.commands_.set(msg.id, msg);
     this.sendToEmulator(msg);
   } else if (msg instanceof Response) {
     this.sendToClient(msg);
   }
 };
@@ -183,41 +183,41 @@ Dispatcher.prototype.send = function(msg
 // Low-level methods:
 
 /**
  * Send given response to the client over the debugger transport socket.
  *
  * @param {Response} resp
  *     The response to send back to the client.
  */
-Dispatcher.prototype.sendToClient = function(resp) {
+Dispatcher.prototype.sendToClient = function (resp) {
   this.driver.responseCompleted();
   this.sendMessage(resp);
 };
 
 /**
  * Marshal message to the Marionette message format and send it.
  *
  * @param {Command,Response} msg
  *     The message to send.
  */
-Dispatcher.prototype.sendMessage = function(msg) {
+Dispatcher.prototype.sendMessage = function (msg) {
   this.log_(msg);
   let payload = msg.toMsg();
   this.sendRaw(payload);
 };
 
 /**
  * Send the given payload over the debugger transport socket to the
  * connected client.
  *
  * @param {Object} payload
  *     The payload to ship.
  */
-Dispatcher.prototype.sendRaw = function(payload) {
+Dispatcher.prototype.sendRaw = function (payload) {
   this.conn.send(payload);
 };
 
-Dispatcher.prototype.log_ = function(msg) {
+Dispatcher.prototype.log_ = function (msg) {
   let a = (msg.origin == MessageOrigin.Client ? " -> " : " <- ");
   let s = JSON.stringify(msg.toMsg());
   logger.trace(this.connId + a + s);
 };
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -73,17 +73,17 @@ Services.obs.addObserver(function () {
   delayedBrowserStarted = true;
 }, BROWSER_STARTUP_FINISHED, false);
 
 this.Context = {
   CHROME: "chrome",
   CONTENT: "content",
 };
 
-this.Context.fromString = function(s) {
+this.Context.fromString = function (s) {
   s = s.toUpperCase();
   if (s in this) {
     return this[s];
   }
   return null;
 };
 
 /**
@@ -95,17 +95,17 @@ this.Context.fromString = function(s) {
  * documentation refers to the contents of the {@code cmd.parameters}
  * object.
  *
  * @param {string} appName
  *     Description of the product, for example "B2G" or "Firefox".
  * @param {MarionetteServer} server
  *     The instance of Marionette server.
  */
-this.GeckoDriver = function(appName, server) {
+this.GeckoDriver = function (appName, server) {
   this.appName = appName;
   this._server = server;
 
   this.sessionId = null;
   this.wins = new browser.Windows();
   this.browsers = {};
   // points to current browser
   this.curBrowser = null;
@@ -212,17 +212,17 @@ GeckoDriver.prototype.switchToGlobalMess
  *
  * @param {string} name
  *     Suffix of the targetted message listener ({@code Marionette:<suffix>}).
  * @param {Object=} msg
  *     JSON serialisable object to send to the listener.
  * @param {number=} cmdId
  *     Command ID to ensure synchronisity.
  */
-GeckoDriver.prototype.sendAsync = function(name, msg, cmdId) {
+GeckoDriver.prototype.sendAsync = function (name, msg, cmdId) {
   let curRemoteFrame = this.curBrowser.frameManager.currentRemoteFrame;
   name = "Marionette:" + name;
 
   // TODO(ato): When proxy.AsyncMessageChannel
   // is used for all chrome <-> content communication
   // this can be removed.
   if (cmdId) {
     msg.command_id = cmdId;
@@ -269,17 +269,17 @@ GeckoDriver.prototype.getCurrentWindow =
     } else {
       return this.curBrowser.window;
     }
   } else {
     return this.curFrame;
   }
 };
 
-GeckoDriver.prototype.addFrameCloseListener = function(action) {
+GeckoDriver.prototype.addFrameCloseListener = function (action) {
   let win = this.getCurrentWindow();
   this.mozBrowserClose = e => {
     if (e.target.id == this.oopFrameId) {
       win.removeEventListener("mozbrowserclose", this.mozBrowserClose, true);
       this.switchToGlobalMessageManager();
       throw new NoSuchWindowError("The window closed during action: " + action);
     }
   };
@@ -290,17 +290,17 @@ GeckoDriver.prototype.addFrameCloseListe
  * Create a new browsing context for window and add to known browsers.
  *
  * @param {nsIDOMWindow} win
  *     Window for which we will create a browsing context.
  *
  * @return {string}
  *     Returns the unique server-assigned ID of the window.
  */
-GeckoDriver.prototype.addBrowser = function(win) {
+GeckoDriver.prototype.addBrowser = function (win) {
   let bc = new browser.Context(win, this);
   let winId = win.QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
   winId = winId + ((this.appName == "B2G") ? "-b2g" : "");
   this.browsers[winId] = bc;
   this.curBrowser = this.browsers[winId];
   if (!this.wins.has(winId)) {
     // add this to seenItems so we can guarantee
@@ -316,34 +316,34 @@ GeckoDriver.prototype.addBrowser = funct
  * frame script will be loaded into it.  If isNewSession is true, we will
  * switch focus to the start frame when it registers.
  *
  * @param {nsIDOMWindow} win
  *     Window whose browser we need to access.
  * @param {boolean=false} isNewSession
  *     True if this is the first time we're talking to this browser.
  */
-GeckoDriver.prototype.startBrowser = function(win, isNewSession = false) {
+GeckoDriver.prototype.startBrowser = function (win, isNewSession = false) {
   this.mainFrame = win;
   this.curFrame = null;
   this.addBrowser(win);
   this.curBrowser.isNewSession = isNewSession;
   this.curBrowser.startSession(isNewSession, win, this.whenBrowserStarted.bind(this));
 };
 
 /**
  * Callback invoked after a new session has been started in a browser.
  * Loads the Marionette frame script into the browser if needed.
  *
  * @param {nsIDOMWindow} win
  *     Window whose browser we need to access.
  * @param {boolean} isNewSession
  *     True if this is the first time we're talking to this browser.
  */
-GeckoDriver.prototype.whenBrowserStarted = function(win, isNewSession) {
+GeckoDriver.prototype.whenBrowserStarted = function (win, isNewSession) {
   let mm = win.window.messageManager;
   if (mm) {
     if (!isNewSession) {
       // Loading the frame script corresponds to a situation we need to
       // return to the server. If the messageManager is a message broadcaster
       // with no children, we don't have a hope of coming back from this call,
       // so send the ack here. Otherwise, make a note of how many child scripts
       // will be loaded so we known when it's safe to return.
@@ -375,17 +375,17 @@ GeckoDriver.prototype.whenBrowserStarted
 /**
  * Recursively get all labeled text.
  *
  * @param {nsIDOMElement} el
  *     The parent element.
  * @param {Array.<string>} lines
  *      Array that holds the text lines.
  */
-GeckoDriver.prototype.getVisibleText = function(el, lines) {
+GeckoDriver.prototype.getVisibleText = function (el, lines) {
   try {
     if (atom.isElementDisplayed(el, this.getCurrentWindow())) {
       if (el.value) {
         lines.push(el.value);
       }
       for (let child in el.childNodes) {
         this.getVisibleText(el.childNodes[child], lines);
       }
@@ -396,17 +396,17 @@ GeckoDriver.prototype.getVisibleText = f
     }
   }
 };
 
 /**
  * Handles registration of new content listener browsers.  Depending on
  * their type they are either accepted or ignored.
  */
-GeckoDriver.prototype.registerBrowser = function(id, be) {
+GeckoDriver.prototype.registerBrowser = function (id, be) {
   let nullPrevious = this.curBrowser.curFrameId === null;
   let listenerWindow = Services.wm.getOuterWindowWithId(id);
 
   // go in here if we're already in a remote frame
   if (this.curBrowser.frameManager.currentRemoteFrame !== null &&
       (!listenerWindow || this.mm == this.curBrowser.frameManager
           .currentRemoteFrame.messageManager.get())) {
     // The outerWindowID from an OOP frame will not be meaningful to
@@ -586,31 +586,31 @@ GeckoDriver.prototype.newSession = funct
  * Capabilities informs the client of which WebDriver features are
  * supported by Firefox and Marionette.  They are immutable for the
  * length of the session.
  *
  * The return value is an immutable map of string keys
  * ("capabilities") to values, which may be of types boolean,
  * numerical or string.
  */
-GeckoDriver.prototype.getSessionCapabilities = function(cmd, resp) {
+GeckoDriver.prototype.getSessionCapabilities = function (cmd, resp) {
   resp.body.capabilities = this.sessionCapabilities;
 };
 
 /**
  * Update the sessionCapabilities object with the keys that have been
  * passed in when a new session is created.
  *
  * This is not a public API, only available when a new session is
  * created.
  *
  * @param {Object} newCaps
  *     Key/value dictionary to overwrite session's current capabilities.
  */
-GeckoDriver.prototype.setSessionCapabilities = function(newCaps) {
+GeckoDriver.prototype.setSessionCapabilities = function (newCaps) {
   const copy = (from, to={}) => {
     let errors = [];
 
     // Remove any duplicates between required and desired in favour of the
     // required capabilities
     if (from !== null && from.desiredCapabilities) {
       for (let cap in from.requiredCapabilities) {
         if (from.desiredCapabilities[cap]) {
@@ -662,17 +662,17 @@ GeckoDriver.prototype.setSessionCapabili
   // clone, overwrite, and set
   let caps = copy(this.sessionCapabilities);
   caps = copy(newCaps, caps);
   logger.config("Changing capabilities: " + JSON.stringify(caps));
 
   this.sessionCapabilities = caps;
 };
 
-GeckoDriver.prototype.setUpProxy = function(proxy) {
+GeckoDriver.prototype.setUpProxy = function (proxy) {
   logger.config("User-provided proxy settings: " + JSON.stringify(proxy));
 
   assert.object(proxy);
   if (!proxy.hasOwnProperty("proxyType")) {
     throw new InvalidArgumentError();
   }
   switch (proxy.proxyType.toUpperCase()) {
     case "MANUAL":
@@ -721,47 +721,47 @@ GeckoDriver.prototype.setUpProxy = funct
 /**
  * Log message.  Accepts user defined log-level.
  *
  * @param {string} value
  *     Log message.
  * @param {string} level
  *     Arbitrary log level.
  */
-GeckoDriver.prototype.log = function(cmd, resp) {
+GeckoDriver.prototype.log = function (cmd, resp) {
   // if level is null, we want to use ContentLogger#send's default
   this.marionetteLog.log(
       cmd.parameters.value,
       cmd.parameters.level || undefined);
 };
 
 /** Return all logged messages. */
-GeckoDriver.prototype.getLogs = function(cmd, resp) {
+GeckoDriver.prototype.getLogs = function (cmd, resp) {
   resp.body = this.marionetteLog.get();
 };
 
 /**
  * Sets the context of the subsequent commands to be either "chrome" or
  * "content".
  *
  * @param {string} value
  *     Name of the context to be switched to.  Must be one of "chrome" or
  *     "content".
  */
-GeckoDriver.prototype.setContext = function(cmd, resp) {
+GeckoDriver.prototype.setContext = function (cmd, resp) {
   let val = cmd.parameters.value;
   let ctx = Context.fromString(val);
   if (ctx === null) {
     throw new WebDriverError(`Invalid context: ${val}`);
   }
   this.context = ctx;
 };
 
 /** Gets the context of the server, either "chrome" or "content". */
-GeckoDriver.prototype.getContext = function(cmd, resp) {
+GeckoDriver.prototype.getContext = function (cmd, resp) {
   resp.body.value = this.context.toString();
 };
 
 /**
  * Executes a JavaScript function in the context of the current browsing
  * context, if in content space, or in chrome space otherwise, and returns
  * the return value of the function.
  *
@@ -877,34 +877,34 @@ GeckoDriver.prototype.executeScript = fu
  *     JavaScript notion of null or undefined.
  *
  * @throws ScriptTimeoutError
  *     If the script was interrupted due to reaching the {@code
  *     scriptTimeout} or default timeout.
  * @throws JavaScriptError
  *     If an Error was thrown whilst evaluating the script.
  */
-GeckoDriver.prototype.executeAsyncScript = function(cmd, resp) {
+GeckoDriver.prototype.executeAsyncScript = function (cmd, resp) {
   let {script, args, scriptTimeout} = cmd.parameters;
   scriptTimeout = scriptTimeout || this.scriptTimeout;
 
   let opts = {
     sandboxName: cmd.parameters.sandbox,
     newSandbox: !!(typeof cmd.parameters.newSandbox == "undefined") ||
         cmd.parameters.newSandbox,
     filename: cmd.parameters.filename,
     line: cmd.parameters.line,
     debug: cmd.parameters.debug_script,
     async: true,
   };
 
   resp.body.value = yield this.execute_(script, args, scriptTimeout, opts);
 };
 
-GeckoDriver.prototype.execute_ = function(script, args, timeout, opts = {}) {
+GeckoDriver.prototype.execute_ = function (script, args, timeout, opts = {}) {
   switch (this.context) {
     case Context.CONTENT:
       // evaluate in content with lasting side-effects
       if (!opts.sandboxName) {
         return this.listener.execute(script, args, timeout, opts);
 
       // evaluate in content with sandbox
       } else {
@@ -927,17 +927,17 @@ GeckoDriver.prototype.execute_ = functio
 };
 
 /**
  * Execute pure JavaScript.  Used to execute simpletest harness tests,
  * which are like mochitests only injected using Marionette.
  *
  * Scripts are expected to call the {@code finish} global when done.
  */
-GeckoDriver.prototype.executeJSScript = function(cmd, resp) {
+GeckoDriver.prototype.executeJSScript = function (cmd, resp) {
   let {script, args, scriptTimeout} = cmd.parameters;
   scriptTimeout = scriptTimeout || this.scriptTimeout;
 
   let opts = {
     filename: cmd.parameters.filename,
     line: cmd.parameters.line,
     async: cmd.parameters.async,
   };
@@ -1060,49 +1060,49 @@ GeckoDriver.prototype.pageLoadPromise = 
  *
  * On Desktop this returns a string representation of the URL of the
  * current top level browsing context.  This is equivalent to
  * document.location.href.
  *
  * When in the context of the chrome, this returns the canonical URL
  * of the current resource.
  */
-GeckoDriver.prototype.getCurrentUrl = function(cmd) {
+GeckoDriver.prototype.getCurrentUrl = function (cmd) {
   switch (this.context) {
     case Context.CHROME:
       return this.getCurrentWindow().location.href;
 
     case Context.CONTENT:
       let isB2G = this.appName == "B2G";
       return this.listener.getCurrentUrl(isB2G);
   }
 };
 
 /** Gets the current title of the window. */
-GeckoDriver.prototype.getTitle = function*(cmd, resp) {
+GeckoDriver.prototype.getTitle = function* (cmd, resp) {
   switch (this.context) {
     case Context.CHROME:
       let win = this.getCurrentWindow();
       resp.body.value = win.document.documentElement.getAttribute("title");
       break;
 
     case Context.CONTENT:
       resp.body.value = yield this.listener.getTitle();
       break;
   }
 };
 
 /** Gets the current type of the window. */
-GeckoDriver.prototype.getWindowType = function(cmd, resp) {
+GeckoDriver.prototype.getWindowType = function (cmd, resp) {
   let win = this.getCurrentWindow();
   resp.body.value = win.document.documentElement.getAttribute("windowtype");
 };
 
 /** Gets the page source of the content document. */
-GeckoDriver.prototype.getPageSource = function*(cmd, resp) {
+GeckoDriver.prototype.getPageSource = function* (cmd, resp) {
   switch (this.context) {
     case Context.CHROME:
       let win = this.getCurrentWindow();
       let s = new win.XMLSerializer();
       resp.body.value = s.serializeToString(win.document);
       break;
 
     case Context.CONTENT:
@@ -1132,17 +1132,17 @@ GeckoDriver.prototype.refresh = function
  *
  * Return an opaque server-assigned identifier to this window that
  * uniquely identifies it within this Marionette instance.  This can
  * be used to switch to this window at a later point.
  *
  * @return {string}
  *     Unique window handle.
  */
-GeckoDriver.prototype.getWindowHandle = function(cmd, resp) {
+GeckoDriver.prototype.getWindowHandle = function (cmd, resp) {
   // curFrameId always holds the current tab.
   if (this.curBrowser.curFrameId && this.appName != "B2G") {
     resp.body.value = this.curBrowser.curFrameId;
     return;
   }
 
   for (let i in this.browsers) {
     if (this.curBrowser == this.browsers[i]) {
@@ -1187,17 +1187,17 @@ GeckoDriver.prototype.getIdForBrowser = 
  * corresponds to the set of open tabs.
  *
  * Each window handle is assigned by the server and is guaranteed unique,
  * however the return array does not have a specified ordering.
  *
  * @return {Array.<string>}
  *     Unique window handles.
  */
-GeckoDriver.prototype.getWindowHandles = function(cmd, resp) {
+GeckoDriver.prototype.getWindowHandles = function (cmd, resp) {
   let hs = [];
   let winEn = Services.wm.getEnumerator(null);
   while (winEn.hasMoreElements()) {
     let win = winEn.getNext();
     if (win.gBrowser && this.appName != "B2G") {
       let tabbrowser = win.gBrowser;
       for (let i = 0; i < tabbrowser.browsers.length; ++i) {
         let winId = this.getIdForBrowser(tabbrowser.getBrowserAtIndex(i));
@@ -1223,33 +1223,33 @@ GeckoDriver.prototype.getWindowHandles =
  *
  * Return an opaque server-assigned identifier to this window that
  * uniquely identifies it within this Marionette instance.  This can
  * be used to switch to this window at a later point.
  *
  * @return {string}
  *     Unique window handle.
  */
-GeckoDriver.prototype.getChromeWindowHandle = function(cmd, resp) {
+GeckoDriver.prototype.getChromeWindowHandle = function (cmd, resp) {
   for (let i in this.browsers) {
     if (this.curBrowser == this.browsers[i]) {
       resp.body.value = i;
       return;
     }
   }
 };
 
 /**
  * Returns identifiers for each open chrome window for tests interested in
  * managing a set of chrome windows and tabs separately.
  *
  * @return {Array.<string>}
  *     Unique window handles.
  */
-GeckoDriver.prototype.getChromeWindowHandles = function(cmd, resp) {
+GeckoDriver.prototype.getChromeWindowHandles = function (cmd, resp) {
   let hs = [];
   let winEn = Services.wm.getEnumerator(null);
   while (winEn.hasMoreElements()) {
     let foundWin = winEn.getNext();
     let winId = foundWin.QueryInterface(Ci.nsIInterfaceRequestor)
         .getInterface(Ci.nsIDOMWindowUtils)
         .outerWindowID;
     winId = winId + ((this.appName == "B2G") ? "-b2g" : "");
@@ -1259,34 +1259,34 @@ GeckoDriver.prototype.getChromeWindowHan
 };
 
 /**
  * Get the current window position.
  *
  * @return {Object.<string, number>}
  *     Object with |x| and |y| coordinates.
  */
-GeckoDriver.prototype.getWindowPosition = function(cmd, resp) {
+GeckoDriver.prototype.getWindowPosition = function (cmd, resp) {
   return this.curBrowser.position;
 };
 
 /**
  * Set the window position of the browser on the OS Window Manager
  *
  * @param {number} x
  *     X coordinate of the top/left of the window that it will be
  *     moved to.
  * @param {number} y
  *     Y coordinate of the top/left of the window that it will be
  *     moved to.
  *
  * @return {Object.<string, number>}
  *     Object with |x| and |y| coordinates.
  */
-GeckoDriver.prototype.setWindowPosition = function(cmd, resp) {
+GeckoDriver.prototype.setWindowPosition = function (cmd, resp) {
   if (this.appName != "Firefox") {
     throw new UnsupportedOperationError("Unable to set the window position on mobile");
   }
 
   let {x, y} = cmd.parameters;
   assert.positiveInteger(x);
   assert.positiveInteger(y);
 
@@ -1298,29 +1298,29 @@ GeckoDriver.prototype.setWindowPosition 
 
 /**
  * Switch current top-level browsing context by name or server-assigned ID.
  * Searches for windows by name, then ID.  Content windows take precedence.
  *
  * @param {string} name
  *     Target name or ID of the window to switch to.
  */
-GeckoDriver.prototype.switchToWindow = function*(cmd, resp) {
+GeckoDriver.prototype.switchToWindow = function* (cmd, resp) {
   let switchTo = cmd.parameters.name;
   let isMobile = this.appName == "Fennec";
   let found;
 
-  let getOuterWindowId = function(win) {
+  let getOuterWindowId = function (win) {
     let rv = win.QueryInterface(Ci.nsIInterfaceRequestor)
         .getInterface(Ci.nsIDOMWindowUtils)
         .outerWindowID;
     return rv;
   };
 
-  let byNameOrId = function(name, outerId, contentWindowId) {
+  let byNameOrId = function (name, outerId, contentWindowId) {
     return switchTo == name ||
         switchTo == contentWindowId ||
         switchTo == outerId;
   };
 
   let winEn = Services.wm.getEnumerator(null);
   while (winEn.hasMoreElements()) {
     let win = winEn.getNext();
@@ -1372,17 +1372,17 @@ GeckoDriver.prototype.switchToWindow = f
         this.curBrowser.switchToTab(found.tabIndex, found.win);
       }
     }
   } else {
     throw new NoSuchWindowError(`Unable to locate window: ${switchTo}`);
   }
 };
 
-GeckoDriver.prototype.getActiveFrame = function(cmd, resp) {
+GeckoDriver.prototype.getActiveFrame = function (cmd, resp) {
   switch (this.context) {
     case Context.CHROME:
       // no frame means top-level
       resp.body.value = null;
       if (this.curFrame) {
         let elRef = this.curBrowser.seenEls
             .add(this.curFrame.frameElement);
         let el = element.makeWebElement(elRef);
@@ -1408,17 +1408,17 @@ GeckoDriver.prototype.switchToParentFram
  * Switch to a given frame within the current window.
  *
  * @param {Object} element
  *     A web element reference to the element to switch to.
  * @param {(string|number)} id
  *     If element is not defined, then this holds either the id, name,
  *     or index of the frame to switch to.
  */
-GeckoDriver.prototype.switchToFrame = function*(cmd, resp) {
+GeckoDriver.prototype.switchToFrame = function* (cmd, resp) {
   let {id, element, focus} = cmd.parameters;
 
   const otherErrorsExpr = /about:.+(error)|(blocked)\?/;
   const checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 
   let curWindow = this.getCurrentWindow();
 
   let checkLoad = function() {
@@ -1565,17 +1565,17 @@ GeckoDriver.prototype.switchToFrame = fu
           this.curBrowser.frameManager.switchToFrame(winId, frameId);
 
       yield registerBrowsers;
       yield browserListening;
     }
   }
 };
 
-GeckoDriver.prototype.getTimeouts = function(cmd, resp) {
+GeckoDriver.prototype.getTimeouts = function (cmd, resp) {
   return {
     "implicit": this.searchTimeout,
     "script": this.scriptTimeout,
     "page load": this.pageTimeout,
   };
 };
 
 /**
@@ -1584,17 +1584,17 @@ GeckoDriver.prototype.getTimeouts = func
  * @param {Object.<string, number>}
  *     Dictionary of timeout types and their new value, where all timeout
  *     types are optional.
  *
  * @throws {InvalidArgumentError}
  *     If timeout type key is unknown, or the value provided with it is
  *     not an integer.
  */
-GeckoDriver.prototype.setTimeouts = function(cmd, resp) {
+GeckoDriver.prototype.setTimeouts = function (cmd, resp) {
   // backwards compatibility with old API
   // that accepted a dictionary {type: <string>, ms: <number>}
   let timeouts = {};
   if (typeof cmd.parameters == "object" &&
       "type" in cmd.parameters &&
       "ms" in cmd.parameters) {
     logger.warn("Using deprecated data structure for setting timeouts");
     timeouts = {[cmd.parameters.type]: parseInt(cmd.parameters.ms)};
@@ -2169,17 +2169,17 @@ GeckoDriver.prototype.deleteCookie = fun
 };
 
 /**
  * Close the current window, ending the session if it's the last
  * window currently open.
  *
  * On B2G this method is a noop and will return immediately.
  */
-GeckoDriver.prototype.close = function(cmd, resp) {
+GeckoDriver.prototype.close = function (cmd, resp) {
   // can't close windows on B2G
   if (this.appName == "B2G") {
     return;
   }
 
   let nwins = 0;
   let winEn = Services.wm.getEnumerator(null);
   while (winEn.hasMoreElements()) {
@@ -2215,17 +2215,17 @@ GeckoDriver.prototype.close = function(c
 };
 
 /**
  * Close the currently selected chrome window, ending the session if it's the last
  * window currently open.
  *
  * On B2G this method is a noop and will return immediately.
  */
-GeckoDriver.prototype.closeChromeWindow = function(cmd, resp) {
+GeckoDriver.prototype.closeChromeWindow = function (cmd, resp) {
   // can't close windows on B2G
   if (this.appName == "B2G") {
     return;
   }
 
   // Get the total number of windows
   let nwins = 0;
   let winEn = Services.wm.getEnumerator(null);
@@ -2253,17 +2253,17 @@ GeckoDriver.prototype.closeChromeWindow 
  *
  * If it is a desktop environment, it will close all listeners.
  *
  * If it is a B2G environment, it will make the main content listener
  * sleep, and close all other listeners.  The main content listener
  * persists after disconnect (it's the homescreen), and can safely
  * be reused.
  */
-GeckoDriver.prototype.sessionTearDown = function(cmd, resp) {
+GeckoDriver.prototype.sessionTearDown = function (cmd, resp) {
   if (this.curBrowser !== null) {
     if (this.appName == "B2G") {
       globalMessageManager.broadcastAsyncMessage(
           "Marionette:sleepSession" + this.curBrowser.mainContentId, {});
       this.curBrowser.knownFrames.splice(
           this.curBrowser.knownFrames.indexOf(this.curBrowser.mainContentId), 1);
     } else {
       // don't set this pref for B2G since the framescript can be safely reused
@@ -2319,22 +2319,22 @@ GeckoDriver.prototype.sessionTearDown = 
   this.sandboxes.clear();
   cert.uninstallOverride();
 };
 
 /**
  * Processes the "deleteSession" request from the client by tearing down
  * the session and responding "ok".
  */
-GeckoDriver.prototype.deleteSession = function(cmd, resp) {
+GeckoDriver.prototype.deleteSession = function (cmd, resp) {
   this.sessionTearDown();
 };
 
 /** Returns the current status of the Application Cache. */
-GeckoDriver.prototype.getAppCacheStatus = function*(cmd, resp) {
+GeckoDriver.prototype.getAppCacheStatus = function* (cmd, resp) {
   resp.body.value = yield this.listener.getAppCacheStatus();
 };
 
 /**
  * Import script to the JS evaluation runtime.
  *
  * Imported scripts are exposed in the contexts of all subsequent
  * calls to {@code executeScript}, {@code executeAsyncScript}, and
@@ -2381,17 +2381,17 @@ GeckoDriver.prototype.clearImportedScrip
  * @param {boolean} hash
  *     True if the user requests a hash of the image data.
  *
  * @return {string}
  *     If {@code hash} is false, PNG image encoded as base64 encoded string. If
  *     'hash' is True, hex digest of the SHA-256 hash of the base64 encoded
  *     string.
  */
-GeckoDriver.prototype.takeScreenshot = function(cmd, resp) {
+GeckoDriver.prototype.takeScreenshot = function (cmd, resp) {
   let {id, highlights, full, hash} = cmd.parameters;
   highlights = highlights || [];
 
   switch (this.context) {
     case Context.CHROME:
       let win = this.getCurrentWindow();
       let canvas = win.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
       let doc;
@@ -2442,17 +2442,17 @@ GeckoDriver.prototype.takeScreenshot = f
 
 /**
  * Get the current browser orientation.
  *
  * Will return one of the valid primary orientation values
  * portrait-primary, landscape-primary, portrait-secondary, or
  * landscape-secondary.
  */
-GeckoDriver.prototype.getScreenOrientation = function(cmd, resp) {
+GeckoDriver.prototype.getScreenOrientation = function (cmd, resp) {
   if (this.appName == "Firefox") {
     throw new UnsupportedOperationError();
   }
   resp.body.value = this.getCurrentWindow().screen.mozOrientation;
 };
 
 /**
  * Set the current browser orientation.
@@ -2460,17 +2460,17 @@ GeckoDriver.prototype.getScreenOrientati
  * The supplied orientation should be given as one of the valid
  * orientation values.  If the orientation is unknown, an error will
  * be raised.
  *
  * Valid orientations are "portrait" and "landscape", which fall
  * back to "portrait-primary" and "landscape-primary" respectively,
  * and "portrait-secondary" as well as "landscape-secondary".
  */
-GeckoDriver.prototype.setScreenOrientation = function(cmd, resp) {
+GeckoDriver.prototype.setScreenOrientation = function (cmd, resp) {
   assert.fennec();
 
   const ors = [
     "portrait", "landscape",
     "portrait-primary", "landscape-primary",
     "portrait-secondary", "landscape-secondary",
   ];
 
@@ -2489,97 +2489,97 @@ GeckoDriver.prototype.setScreenOrientati
 
 /**
  * Get the size of the browser window currently in focus.
  *
  * Will return the current browser window size in pixels. Refers to
  * window outerWidth and outerHeight values, which include scroll bars,
  * title bars, etc.
  */
-GeckoDriver.prototype.getWindowSize = function(cmd, resp) {
+GeckoDriver.prototype.getWindowSize = function (cmd, resp) {
   let win = this.getCurrentWindow();
   resp.body.width = win.outerWidth;
   resp.body.height = win.outerHeight;
 };
 
 /**
  * Set the size of the browser window currently in focus.
  *
  * Not supported on B2G. The supplied width and height values refer to
  * the window outerWidth and outerHeight values, which include scroll
  * bars, title bars, etc.
  */
-GeckoDriver.prototype.setWindowSize = function(cmd, resp) {
+GeckoDriver.prototype.setWindowSize = function (cmd, resp) {
   if (this.appName != "Firefox") {
     throw new UnsupportedOperationError();
   }
 
   let {width, height} = cmd.parameters;
   let win = this.getCurrentWindow();
   win.resizeTo(width, height);
   this.getWindowSize(cmd, resp);
 };
 
 /**
  * Maximizes the user agent window as if the user pressed the maximise
  * button.
  *
  * Not Supported on B2G or Fennec.
  */
-GeckoDriver.prototype.maximizeWindow = function(cmd, resp) {
+GeckoDriver.prototype.maximizeWindow = function (cmd, resp) {
   if (this.appName != "Firefox") {
     throw new UnsupportedOperationError();
   }
 
   let win = this.getCurrentWindow();
   win.maximize()
 };
 
 /**
  * Dismisses a currently displayed tab modal, or returns no such alert if
  * no modal is displayed.
  */
-GeckoDriver.prototype.dismissDialog = function(cmd, resp) {
+GeckoDriver.prototype.dismissDialog = function (cmd, resp) {
   this._checkIfAlertIsPresent();
 
   let {button0, button1} = this.dialog.ui;
   (button1 ? button1 : button0).click();
   this.dialog = null;
 };
 
 /**
  * Accepts a currently displayed tab modal, or returns no such alert if
  * no modal is displayed.
  */
-GeckoDriver.prototype.acceptDialog = function(cmd, resp) {
+GeckoDriver.prototype.acceptDialog = function (cmd, resp) {
   this._checkIfAlertIsPresent();
 
   let {button0} = this.dialog.ui;
   button0.click();
   this.dialog = null;
 };
 
 /**
  * Returns the message shown in a currently displayed modal, or returns a no such
  * alert error if no modal is currently displayed.
  */
-GeckoDriver.prototype.getTextFromDialog = function(cmd, resp) {
+GeckoDriver.prototype.getTextFromDialog = function (cmd, resp) {
   this._checkIfAlertIsPresent();
 
   let {infoBody} = this.dialog.ui;
   resp.body.value = infoBody.textContent;
 };
 
 /**
  * Sends keys to the input field of a currently displayed modal, or
  * returns a no such alert error if no modal is currently displayed. If
  * a tab modal is currently displayed but has no means for text input,
  * an element not visible error is returned.
  */
-GeckoDriver.prototype.sendKeysToDialog = function(cmd, resp) {
+GeckoDriver.prototype.sendKeysToDialog = function (cmd, resp) {
   this._checkIfAlertIsPresent();
 
   // see toolkit/components/prompts/content/commonDialog.js
   let {loginContainer, loginTextbox} = this.dialog.ui;
   if (loginContainer.hidden) {
     throw new ElementNotVisibleError("This prompt does not accept text input");
   }
 
@@ -2609,81 +2609,81 @@ GeckoDriver.prototype._checkIfAlertIsPre
  * a non-recoverable state if it hasn't been enabled before.
  *
  * This method is used for custom in application shutdowns via marionette.quit()
  * or marionette.restart(), like File -> Quit.
  *
  * @param {boolean} state
  *     True if the server should accept new socket connections.
  */
-GeckoDriver.prototype.acceptConnections = function(cmd, resp) {
+GeckoDriver.prototype.acceptConnections = function (cmd, resp) {
   assert.boolean(cmd.parameters.value);
   this._server.acceptConnections = cmd.parameters.value;
 }
 
 /**
  * Quits Firefox with the provided flags and tears down the current
  * session.
  */
-GeckoDriver.prototype.quitApplication = function(cmd, resp) {
+GeckoDriver.prototype.quitApplication = function (cmd, resp) {
   if (this.appName != "Firefox") {
     throw new WebDriverError("In app initiated quit only supported in Firefox");
   }
 
   let flags = Ci.nsIAppStartup.eAttemptQuit;
   for (let k of cmd.parameters.flags || []) {
     flags |= Ci.nsIAppStartup[k];
   }
 
   this._server.acceptConnections = false;
   resp.send();
 
   this.sessionTearDown();
   Services.startup.quit(flags);
 };
 
-GeckoDriver.prototype.installAddon = function(cmd, resp) {
+GeckoDriver.prototype.installAddon = function (cmd, resp) {
   if (this.appName != "Firefox") {
     throw new UnsupportedOperationError();
   }
 
   let path = cmd.parameters.path;
   let temp = cmd.parameters.temporary || false;
   if (typeof path == "undefined" || typeof path != "string" ||
       typeof temp != "boolean") {
     throw InvalidArgumentError();
   }
 
   return addon.install(path, temp);
 };
 
-GeckoDriver.prototype.uninstallAddon = function(cmd, resp) {
+GeckoDriver.prototype.uninstallAddon = function (cmd, resp) {
   if (this.appName != "Firefox") {
     throw new UnsupportedOperationError();
   }
 
   let id = cmd.parameters.id;
   if (typeof id == "undefined" || typeof id != "string") {
     throw new InvalidArgumentError();
   }
 
   return addon.uninstall(id);
 };
 
 /**
  * Helper function to convert an outerWindowID into a UID that Marionette
  * tracks.
  */
-GeckoDriver.prototype.generateFrameId = function(id) {
+GeckoDriver.prototype.generateFrameId = function (id) {
   let uid = id + (this.appName == "B2G" ? "-b2g" : "");
   return uid;
 };
 
 /** Receives all messages from content messageManager. */
-GeckoDriver.prototype.receiveMessage = function(message) {
+GeckoDriver.prototype.receiveMessage = function (message) {
   switch (message.name) {
     case "Marionette:ok":
     case "Marionette:done":
     case "Marionette:error":
       // check if we need to remove the mozbrowserclose listener
       if (this.mozBrowserClose !== null) {
         let win = this.getCurrentWindow();
         win.removeEventListener("mozbrowserclose", this.mozBrowserClose, true);
@@ -2791,17 +2791,17 @@ GeckoDriver.prototype.responseCompleted 
  * @param {Array.<string>} urls
  *     Array of .dtd URLs.
  * @param {string} id
  *     The ID of the entity to retrieve the localized string for.
  *
  * @return {string}
  *     The localized string for the requested entity.
  */
-GeckoDriver.prototype.localizeEntity = function(cmd, resp) {
+GeckoDriver.prototype.localizeEntity = function (cmd, resp) {
   let {urls, id} = cmd.parameters;
 
   if (!Array.isArray(urls)) {
     throw new InvalidArgumentError("Value of `urls` should be of type 'Array'");
   }
   if (typeof id != "string") {
     throw new InvalidArgumentError("Value of `id` should be of type 'string'");
   }
@@ -2818,17 +2818,17 @@ GeckoDriver.prototype.localizeEntity = f
  * @param {Array.<string>} urls
  *     Array of .properties URLs.
  * @param {string} id
  *     The ID of the property to retrieve the localized string for.
  *
  * @return {string}
  *     The localized string for the requested property.
  */
-GeckoDriver.prototype.localizeProperty = function(cmd, resp) {
+GeckoDriver.prototype.localizeProperty = function (cmd, resp) {
   let {urls, id} = cmd.parameters;
 
   if (!Array.isArray(urls)) {
     throw new InvalidArgumentError("Value of `urls` should be of type 'Array'");
   }
   if (typeof id != "string") {
     throw new InvalidArgumentError("Value of `id` should be of type 'string'");
   }
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -229,17 +229,17 @@ element.Store = class {
  * @throws InvalidSelectorError
  *     If |strategy| is unknown.
  * @throws InvalidSelectorError
  *     If |selector| is malformed.
  * @throws NoSuchElementError
  *     If a single element is requested, this error will throw if the
  *     element is not found.
  */
-element.find = function(container, strategy, selector, opts = {}) {
+element.find = function (container, strategy, selector, opts = {}) {
   opts.all = !!opts.all;
   opts.timeout = opts.timeout || 0;
 
   let searchFn;
   if (opts.all) {
     searchFn = findElements.bind(this);
   } else {
     searchFn = findElement.bind(this);
@@ -304,17 +304,17 @@ function find_(container, strategy, sele
  * @param {DOMElement} startNode
  *     Where in the DOM hiearchy to begin searching.
  * @param {string} expr
  *     XPath search expression.
  *
  * @return {DOMElement}
  *     First element matching expression.
  */
-element.findByXPath = function(root, startNode, expr) {
+element.findByXPath = function (root, startNode, expr) {
   let iter = root.evaluate(expr, startNode, null,
       Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE, null)
   return iter.singleNodeValue;
 };
 
 /**
  * Find elements by XPath expression.
  *
@@ -323,17 +323,17 @@ element.findByXPath = function(root, sta
  * @param {DOMElement} startNode
  *     Where in the DOM hierarchy to begin searching.
  * @param {string} expr
  *     XPath search expression.
  *
  * @return {Array.<DOMElement>}
  *     Sequence of found elements matching expression.
  */
-element.findByXPathAll = function(root, startNode, expr) {
+element.findByXPathAll = function (root, startNode, expr) {
   let rv = [];
   let iter = root.evaluate(expr, startNode, null,
       Ci.nsIDOMXPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
   let el = iter.iterateNext();
   while (el) {
     rv.push(el);
     el = iter.iterateNext();
   }
@@ -346,32 +346,32 @@ element.findByXPathAll = function(root, 
  * @param {DOMElement} node
  *     Where in the DOM hierarchy to being searching.
  * @param {string} s
  *     Link text to search for.
  *
  * @return {Array.<DOMAnchorElement>}
  *     Sequence of link elements which text is |s|.
  */
-element.findByLinkText = function(node, s) {
+element.findByLinkText = function (node, s) {
   return filterLinks(node, link => link.text.trim() === s);
 };
 
 /**
  * Find all hyperlinks descendant of |node| which link text contains |s|.
  *
  * @param {DOMElement} node
  *     Where in the DOM hierachy to begin searching.
  * @param {string} s
  *     Link text to search for.
  *
  * @return {Array.<DOMAnchorElement>}
  *     Sequence of link elements which text containins |s|.
  */
-element.findByPartialLinkText = function(node, s) {
+element.findByPartialLinkText = function (node, s) {
   return filterLinks(node, link => link.text.indexOf(s) != -1);
 };
 
 /**
  * Filters all hyperlinks that are descendant of |node| by |predicate|.
  *
  * @param {DOMElement} node
  *     Where in the DOM hierarchy to begin searching.
@@ -610,49 +610,49 @@ function implicitlyWaitFor(func, timeout
     return res;
   }, err => {
     timer.cancel();
     throw err;
   });
 }
 
 /** Determines if |obj| is an HTML or JS collection. */
-element.isCollection = function(seq) {
+element.isCollection = function (seq) {
   switch (Object.prototype.toString.call(seq)) {
     case "[object Arguments]":
     case "[object Array]":
     case "[object FileList]":
     case "[object HTMLAllCollection]":
     case "[object HTMLCollection]":
     case "[object HTMLFormControlsCollection]":
     case "[object HTMLOptionsCollection]":
     case "[object NodeList]":
       return true;
 
     default:
       return false;
   }
 };
 
-element.makeWebElement = function(uuid) {
+element.makeWebElement = function (uuid) {
   return {
     [element.Key]: uuid,
     [element.LegacyKey]: uuid,
   };
 };
 
 /**
  * Checks if |ref| has either |element.Key| or |element.LegacyKey| as properties.
  *
  * @param {?} ref
  *     Object that represents a web element reference.
  * @return {boolean}
  *     True if |ref| has either expected property.
  */
-element.isWebElementReference = function(ref) {
+element.isWebElementReference = function (ref) {
   let properties = Object.getOwnPropertyNames(ref);
   return properties.includes(element.Key) || properties.includes(element.LegacyKey);
 };
 
 element.generateUUID = function() {
   let uuid = uuidGen.generateUUID().toString();
   return uuid.substring(1, uuid.length - 1);
 };
@@ -669,17 +669,17 @@ element.generateUUID = function() {
  *     Window.
  * @param {ShadowRoot} shadowRoot
  *     Shadow root.
  *
  * @return {?}
  *     Same object as provided by |obj| with the web elements replaced
  *     by DOM elements.
  */
-element.fromJson = function(
+element.fromJson = function (
     obj, seenEls, win, shadowRoot = undefined) {
   switch (typeof obj) {
     case "boolean":
     case "number":
     case "string":
       return obj;
 
     case "object":
@@ -725,17 +725,17 @@ element.fromJson = function(
  *     Object to be marshaled.
  * @param {element.Store} seenEls
  *     Element store to use for lookup of web element references.
  *
  * @return {?}
  *     Same object as provided by |obj| with the elements replaced by
  *     web elements.
  */
-element.toJson = function(obj, seenEls) {
+element.toJson = function (obj, seenEls) {
   let t = Object.prototype.toString.call(obj);
 
   // null
   if (t == "[object Undefined]" || t == "[object Null]") {
     return null;
   }
 
   // literals
@@ -778,17 +778,17 @@ element.toJson = function(obj, seenEls) 
  *     Window object that contains the element or the current host
  *     of the shadow root.
  * @param {ShadowRoot=} shadowRoot
  *     An optional shadow root containing an element.
  *
  * @return {boolean}
  *     Flag indicating that the element is disconnected.
  */
-element.isDisconnected = function(el, frame, shadowRoot = undefined) {
+element.isDisconnected = function (el, frame, shadowRoot = undefined) {
   // shadow dom
   if (shadowRoot && frame.ShadowRoot) {
     if (el.compareDocumentPosition(shadowRoot) &
         DOCUMENT_POSITION_DISCONNECTED) {
       return true;
     }
 
     // looking for next possible ShadowRoot ancestor
@@ -821,17 +821,17 @@ element.isDisconnected = function(el, fr
  *     the centre of the target's bounding box.
  *
  * @return {Object.<string, number>}
  *     X- and Y coordinates.
  *
  * @throws TypeError
  *     If |xOffset| or |yOffset| are not numbers.
  */
-element.coordinates = function(
+element.coordinates = function (
     node, xOffset = undefined, yOffset = undefined) {
 
   let box = node.getBoundingClientRect();
 
   if (typeof xOffset == "undefined" || xOffset === null) {
     xOffset = box.width / 2.0;
   }
   if (typeof yOffset == "undefined" || yOffset === null) {
@@ -858,17 +858,17 @@ element.coordinates = function(
  *     the target's bounding box.
  * @param {number=} y
  *     Vertical offset relative to target.  Defaults to the centre of
  *     the target's bounding box.
  *
  * @return {boolean}
  *     True if if |el| is in viewport, false otherwise.
  */
-element.inViewport = function(el, x = undefined, y = undefined) {
+element.inViewport = function (el, x = undefined, y = undefined) {
   let win = el.ownerDocument.defaultView;
   let c = element.coordinates(el, x, y);
   let vp = {
     top: win.pageYOffset,
     left: win.pageXOffset,
     bottom: (win.pageYOffset + win.innerHeight),
     right: (win.pageXOffset + win.innerWidth)
   };
@@ -892,17 +892,17 @@ element.inViewport = function(el, x = un
  *     the target's bounding box.
  * @param {number=} y
  *     Vertical offset relative to target.  Defaults to the centre of
  *     the target's bounding box.
  *
  * @return {boolean}
  *     True if visible, false otherwise.
  */
-element.isVisible = function(el, x = undefined, y = undefined) {
+element.isVisible = function (el, x = undefined, y = undefined) {
   let win = el.ownerDocument.defaultView;
 
   // Bug 1094246: webdriver's isShown doesn't work with content xul
   if (!element.isXULElement(el) && !atom.isElementDisplayed(el, win)) {
     return false;
   }
 
   if (el.tagName.toLowerCase() == "body") {
@@ -913,34 +913,34 @@ element.isVisible = function(el, x = und
     element.scrollIntoView(el);
     if (!element.inViewport(el)) {
       return false;
     }
   }
   return true;
 };
 
-element.isInteractable = function(el) {
+element.isInteractable = function (el) {
   return element.isPointerInteractable(el) ||
       element.isKeyboardInteractable(el);
 };
 
 /**
  * A pointer-interactable element is defined to be the first
  * non-transparent element, defined by the paint order found at the centre
  * point of its rectangle that is inside the viewport, excluding the size
  * of any rendered scrollbars.
  *
  * @param {DOMElement} el
  *     Element determine if is pointer-interactable.
  *
  * @return {boolean}
  *     True if interactable, false otherwise.
  */
-element.isPointerInteractable = function(el) {
+element.isPointerInteractable = function (el) {
   let tree = element.getInteractableElementTree(el, el.ownerDocument);
   return tree[0] === el;
 };
 
 /**
  * Calculate the in-view centre point of the area of the given DOM client
  * rectangle that is inside the viewport.
  *
@@ -948,17 +948,17 @@ element.isPointerInteractable = function
  *     Element off a DOMRect sequence produced by calling |getClientRects|
  *     on a |DOMElement|.
  * @param {nsIDOMWindow} win
  *     Current browsing context.
  *
  * @return {Map.<string, number>}
  *     X and Y coordinates that denotes the in-view centre point of |rect|.
  */
-element.getInViewCentrePoint = function(rect, win) {
+element.getInViewCentrePoint = function (rect, win) {
   const {max, min} = Math;
 
   let x = {
     left: max(0, min(rect.x, rect.x + rect.width)),
     right: min(win.innerWidth, max(rect.x, rect.x + rect.width)),
   };
   let y = {
     top: max(0, min(rect.y, rect.y + rect.height)),
@@ -981,17 +981,17 @@ element.getInViewCentrePoint = function(
  * @param {DOMElement} el
  *     Element to determine if is pointer-interactable.
  * @param {DOMDocument} doc
  *     Current browsing context's active document.
  *
  * @return {Array.<DOMElement>}
  *     Sequence of non-opaque elements in paint order.
  */
-element.getInteractableElementTree = function(el, doc) {
+element.getInteractableElementTree = function (el, doc) {
   let win = doc.defaultView;
 
   // pointer-interactable elements tree, step 1
   if (element.isDisconnected(el, win)) {
     return [];
   }
 
   // steps 2-3
@@ -1007,33 +1007,33 @@ element.getInteractableElementTree = fun
   let tree = doc.elementsFromPoint(centre.x, centre.y);
 
   // only visible elements are considered interactable
   return tree.filter(el => win.getComputedStyle(el).opacity === "1");
 };
 
 // TODO(ato): Not implemented.
 // In fact, it's not defined in the spec.
-element.isKeyboardInteractable = function(el) {
+element.isKeyboardInteractable = function (el) {
   return true;
 };
 
 /**
  * Attempts to scroll into view |el|.
  *
  * @param {DOMElement} el
  *     Element to scroll into view.
  */
-element.scrollIntoView = function(el) {
+element.scrollIntoView = function (el) {
   if (el.scrollIntoView) {
     el.scrollIntoView({block: "end", inline: "nearest", behavior: "instant"});
   }
 };
 
-element.isXULElement = function(el) {
+element.isXULElement = function (el) {
   let ns = atom.getElementAttribute(el, "namespaceURI");
   return ns.indexOf("there.is.only.xul") >= 0;
 };
 
 const boolEls = {
   audio: ["autoplay", "controls", "loop", "muted"],
   button: ["autofocus", "disabled", "formnovalidate"],
   details: ["open"],
@@ -1062,17 +1062,17 @@ const boolEls = {
  * @param {DOMElement} el
  *     Element to test if |attr| is a boolean attribute on.
  * @param {string} attr
  *     Attribute to test is a boolean attribute.
  *
  * @return {boolean}
  *     True if the attribute is boolean, false otherwise.
  */
-element.isBooleanAttribute = function(el, attr) {
+element.isBooleanAttribute = function (el, attr) {
   if (el.namespaceURI !== XMLNS) {
     return false;
   }
 
   // global boolean attributes that apply to all HTML elements,
   // except for custom elements
   if ((attr == "hidden" || attr == "itemscope") && !el.localName.includes("-")) {
     return true;
--- a/testing/marionette/error.js
+++ b/testing/marionette/error.js
@@ -51,17 +51,17 @@ this.error = {};
  * isn't unique across browsers, and XPCOM nsIException's are special
  * snowflakes.
  *
  * @param {*} val
  *     Any value that should be undergo the test for errorness.
  * @return {boolean}
  *     True if error, false otherwise.
  */
-error.isError = function(val) {
+error.isError = function (val) {
   if (val === null || typeof val != "object") {
     return false;
   } else if (val instanceof Ci.nsIException) {
     return true;
   } else {
     // DOMRectList errors on string comparison
    try {
       let proto = Object.getPrototypeOf(val);
@@ -70,59 +70,59 @@ error.isError = function(val) {
       return false;
     }
   }
 };
 
 /**
  * Checks if obj is an object in the WebDriverError prototypal chain.
  */
-error.isWebDriverError = function(obj) {
+error.isWebDriverError = function (obj) {
   return error.isError(obj) &&
       ("name" in obj && ERRORS.has(obj.name));
 };
 
 /**
  * Wraps an Error prototype in a WebDriverError.  If the given error is
  * already a WebDriverError, this is effectively a no-op.
  */
-error.wrap = function(err) {
+error.wrap = function (err) {
   if (error.isWebDriverError(err)) {
     return err;
   }
   return new WebDriverError(`${err.name}: ${err.message}`, err.stack);
 };
 
 /**
  * Wraps an Error as a WebDriverError type.  If the given error is already
  * in the WebDriverError prototype chain, this function acts as a no-op.
  */
-error.wrap = function(err) {
+error.wrap = function (err) {
   if (error.isWebDriverError(err)) {
     return err;
   }
   return new WebDriverError(err.message, err.stacktrace);
 };
 
 /**
  * Unhandled error reporter.  Dumps the error and its stacktrace to console,
  * and reports error to the Browser Console.
  */
-error.report = function(err) {
+error.report = function (err) {
   let msg = `Marionette threw an error: ${error.stringify(err)}`;
   dump(msg + "\n");
   if (Cu.reportError) {
     Cu.reportError(msg);
   }
 };
 
 /**
  * Prettifies an instance of Error and its stacktrace to a string.
  */
-error.stringify = function(err) {
+error.stringify = function (err) {
   try {
     let s = err.toString();
     if ("stack" in err) {
       s += "\n" + err.stack;
     }
     return s;
   } catch (e) {
     return "<unprintable error>";
@@ -133,17 +133,17 @@ error.stringify = function(err) {
  * Pretty-print values passed to template strings.
  *
  * Usage:
  *
  *     let input = {value: true};
  *     error.pprint`Expected boolean, got ${input}`;
  *     => "Expected boolean, got [object Object] {"value": true}"
  */
-error.pprint = function(strings, ...values) {
+error.pprint = function (strings, ...values) {
   let res = [];
   for (let i = 0; i < strings.length; i++) {
     res.push(strings[i]);
     if (i < values.length) {
       let val = values[i];
       res.push(Object.prototype.toString.call(val));
       let s = JSON.stringify(val);
       if (s && s.length > 0) {
@@ -161,17 +161,17 @@ error.pprint = function(strings, ...valu
  * @param {WebDriverError} err
  *     Error to serialise.
  *
  * @return {Object.<string, Object>}
  *     JSON dictionary with the keys "error", "message", and "stacktrace".
  * @throws {TypeError}
  *     If error type is not serialisable.
  */
-error.toJson = function(err) {
+error.toJson = function (err) {
   if (!error.isWebDriverError(err)) {
     throw new TypeError(`Unserialisable error type: ${err}`);
   }
 
   let json = {
     error: err.status,
     message: err.message || "",
     stacktrace: err.stack || "",
@@ -183,17 +183,17 @@ error.toJson = function(err) {
  * Unmarshal a JSON dictionary to a WebDriverError prototype.
  *
  * @param {Object.<string, string>} json
  *     JSON dictionary with the keys "error", "message", and "stacktrace".
  *
  * @return {WebDriverError}
  *     Deserialised error prototype.
  */
-error.fromJson = function(json) {
+error.fromJson = function (json) {
   if (!statusLookup.has(json.error)) {
     throw new TypeError(`Undeserialisable error type: ${json.error}`);
   }
 
   let errCls = statusLookup.get(json.error);
   let err = new errCls(json.message);
   if ("stacktrace" in json) {
     err.stack = json.stacktrace;
@@ -201,69 +201,69 @@ error.fromJson = function(json) {
   return err;
 };
 
 /**
  * WebDriverError is the prototypal parent of all WebDriver errors.
  * It should not be used directly, as it does not correspond to a real
  * error in the specification.
  */
-this.WebDriverError = function(msg, stack = undefined) {
+this.WebDriverError = function (msg, stack = undefined) {
   Error.call(this, msg);
   this.name = "WebDriverError";
   this.message = msg;
   this.stack = stack;
   this.status = "webdriver error";
   this.stack = stack;
 };
 WebDriverError.prototype = Object.create(Error.prototype);
 
-this.ElementNotAccessibleError = function(msg) {
+this.ElementNotAccessibleError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "ElementNotAccessibleError";
   this.status = "element not accessible";
 };
 ElementNotAccessibleError.prototype = Object.create(WebDriverError.prototype);
 
-this.ElementNotVisibleError = function(msg) {
+this.ElementNotVisibleError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "ElementNotVisibleError";
   this.status = "element not visible";
 };
 ElementNotVisibleError.prototype = Object.create(WebDriverError.prototype);
 
-this.InsecureCertificateError = function(msg) {
+this.InsecureCertificateError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "InsecureCertificateError";
   this.status = "insecure certificate";
 };
 InsecureCertificateError.prototype = Object.create(WebDriverError.prototype);
 
-this.InvalidArgumentError = function(msg) {
+this.InvalidArgumentError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "InvalidArgumentError";
   this.status = "invalid argument";
 };
 InvalidArgumentError.prototype = Object.create(WebDriverError.prototype);
 
-this.InvalidElementStateError = function(msg) {
+this.InvalidElementStateError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "InvalidElementStateError";
   this.status = "invalid element state";
 };
 InvalidElementStateError.prototype = Object.create(WebDriverError.prototype);
 
-this.InvalidSelectorError = function(msg) {
+this.InvalidSelectorError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "InvalidSelectorError";
   this.status = "invalid selector";
 };
 InvalidSelectorError.prototype = Object.create(WebDriverError.prototype);
 
-this.InvalidSessionIdError = function(msg) {
+this.InvalidSessionIdError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "InvalidSessionIdError";
   this.status = "invalid session id";
 };
 InvalidSessionIdError.prototype = Object.create(WebDriverError.prototype);
 
 /**
  * Creates an error message for a JavaScript error thrown during
@@ -277,17 +277,17 @@ InvalidSessionIdError.prototype = Object
  * @param {string=} file
  *     The filename of the test file containing the Marionette
  *     command that caused this error to occur.
  * @param {number=} line
  *     The line number of the above test file.
  * @param {string=} script
  *     The JS script being executed in text form.
  */
-this.JavaScriptError = function(
+this.JavaScriptError = function (
     err, fnName = null, file = null, line = null, script = null) {
   let msg = String(err);
   let trace = "";
 
   if (fnName) {
     trace += fnName;
     if (file) {
       trace += ` @${file}`;
@@ -312,94 +312,94 @@ this.JavaScriptError = function(
 
   WebDriverError.call(this, msg);
   this.name = "JavaScriptError";
   this.status = "javascript error";
   this.stack = trace;
 };
 JavaScriptError.prototype = Object.create(WebDriverError.prototype);
 
-this.NoAlertOpenError = function(msg) {
+this.NoAlertOpenError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "NoAlertOpenError";
   this.status = "no such alert";
 };
 NoAlertOpenError.prototype = Object.create(WebDriverError.prototype);
 
-this.NoSuchElementError = function(msg) {
+this.NoSuchElementError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "NoSuchElementError";
   this.status = "no such element";
 };
 NoSuchElementError.prototype = Object.create(WebDriverError.prototype);
 
-this.NoSuchFrameError = function(msg) {
+this.NoSuchFrameError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "NoSuchFrameError";
   this.status = "no such frame";
 };
 NoSuchFrameError.prototype = Object.create(WebDriverError.prototype);
 
-this.NoSuchWindowError = function(msg) {
+this.NoSuchWindowError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "NoSuchWindowError";
   this.status = "no such window";
 };
 NoSuchWindowError.prototype = Object.create(WebDriverError.prototype);
 
-this.ScriptTimeoutError = function(msg) {
+this.ScriptTimeoutError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "ScriptTimeoutError";
   this.status = "script timeout";
 };
 ScriptTimeoutError.prototype = Object.create(WebDriverError.prototype);
 
-this.SessionNotCreatedError = function(msg) {
+this.SessionNotCreatedError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "SessionNotCreatedError";
   this.status = "session not created";
 };
 SessionNotCreatedError.prototype = Object.create(WebDriverError.prototype);
 
-this.StaleElementReferenceError = function(msg) {
+this.StaleElementReferenceError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "StaleElementReferenceError";
   this.status = "stale element reference";
 };
 StaleElementReferenceError.prototype = Object.create(WebDriverError.prototype);
 
-this.TimeoutError = function(msg) {
+this.TimeoutError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "TimeoutError";
   this.status = "timeout";
 };
 TimeoutError.prototype = Object.create(WebDriverError.prototype);
 
-this.UnableToSetCookieError = function(msg) {
+this.UnableToSetCookieError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "UnableToSetCookieError";
   this.status = "unable to set cookie";
 };
 UnableToSetCookieError.prototype = Object.create(WebDriverError.prototype);
 
-this.UnknownCommandError = function(msg) {
+this.UnknownCommandError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "UnknownCommandError";
   this.status = "unknown command";
 };
 UnknownCommandError.prototype = Object.create(WebDriverError.prototype);
 
-this.UnknownError = function(msg) {
+this.UnknownError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "UnknownError";
   this.status = "unknown error";
 };
 UnknownError.prototype = Object.create(WebDriverError.prototype);
 
-this.UnsupportedOperationError = function(msg) {
+this.UnsupportedOperationError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "UnsupportedOperationError";
   this.status = "unsupported operation";
 };
 UnsupportedOperationError.prototype = Object.create(WebDriverError.prototype);
 
 const nameLookup = new Map();
 const statusLookup = new Map();
--- a/testing/marionette/evaluate.js
+++ b/testing/marionette/evaluate.js
@@ -93,17 +93,17 @@ this.evaluate = {};
  *     the script.  Note that the return value requires serialisation before
  *     it can be sent to the client.
  *
  * @throws JavaScriptError
  *   If an Error was thrown whilst evaluating the script.
  * @throws ScriptTimeoutError
  *   If the script was interrupted due to script timeout.
  */
-evaluate.sandbox = function(sb, script, args = [], opts = {}) {
+evaluate.sandbox = function (sb, script, args = [], opts = {}) {
   let scriptTimeoutID, timeoutHandler, unloadHandler;
 
   let promise = new Promise((resolve, reject) => {
     let src = "";
     sb[COMPLETE] = resolve;
     timeoutHandler = () => reject(new ScriptTimeoutError("Timed out"));
     unloadHandler = () => reject(
         new JavaScriptError("Document was unloaded during execution"));
@@ -185,17 +185,17 @@ this.sandbox = {};
  *     The sandbox to augment.
  * @param {Object} adapter
  *     Object that holds an {@code exports} property, or a map, of
  *     function names and function references.
  *
  * @return {Sandbox}
  *     The augmented sandbox.
  */
-sandbox.augment = function(sb, adapter) {
+sandbox.augment = function (sb, adapter) {
   function* entries(obj) {
      for (let key of Object.keys(obj)) {
        yield [key, obj[key]];
      }
   }
 
   let funcs = adapter.exports || entries(adapter);
   for (let [name, func] of funcs) {
@@ -212,17 +212,17 @@ sandbox.augment = function(sb, adapter) 
  *     The DOM Window object.
  * @param {nsIPrincipal=} principal
  *     An optional, custom principal to prefer over the Window.  Useful if
  *     you need elevated security permissions.
  *
  * @return {Sandbox}
  *     The created sandbox.
  */
-sandbox.create = function(window, principal = null, opts = {}) {
+sandbox.create = function (window, principal = null, opts = {}) {
   let p = principal || window;
   opts = Object.assign({
     sameZoneAs: window,
     sandboxPrototype: window,
     wantComponents: true,
     wantXrays: true,
   }, opts);
   return new Cu.Sandbox(p, opts);
@@ -233,31 +233,31 @@ sandbox.create = function(window, princi
  * will have lasting side-effects.
  *
  * @param {Window} window
  *     The DOM Window object.
  *
  * @return {Sandbox}
  *     The created sandbox.
  */
-sandbox.createMutable = function(window) {
+sandbox.createMutable = function (window) {
   let opts = {
     wantComponents: false,
     wantXrays: false,
   };
   return sandbox.create(window, null, opts);
 };
 
-sandbox.createSystemPrincipal = function(window) {
+sandbox.createSystemPrincipal = function (window) {
   let principal = Cc["@mozilla.org/systemprincipal;1"]
       .createInstance(Ci.nsIPrincipal);
   return sandbox.create(window, principal);
 };
 
-sandbox.createSimpleTest = function(window, harness) {
+sandbox.createSimpleTest = function (window, harness) {
   let sb = sandbox.create(window);
   sb = sandbox.augment(sb, harness);
   sb[FINISH] = () => sb[COMPLETE](harness.generate_results());
   return sb;
 };
 
 /**
  * Sandbox storage.  When the user requests a sandbox by a specific name,
--- a/testing/marionette/event.js
+++ b/testing/marionette/event.js
@@ -61,17 +61,17 @@ event.Modifiers = {
  * @param {(DOMElement|string)} target
  *     Target of event.  Can either be an element or the ID of an element.
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  *
  * @throws {TypeError}
  *     If the event is unsupported.
  */
-event.sendMouseEvent = function(mouseEvent, target, window = undefined) {
+event.sendMouseEvent = function (mouseEvent, target, window = undefined) {
   if (!event.MouseEvents.hasOwnProperty(mouseEvent.type)) {
     throw new TypeError("Unsupported event type: " + mouseEvent.type);
   }
 
   if (!target.nodeType && typeof target != "string") {
     throw new TypeError("Target can only be a DOM element or a string: " + target);
   }
 
@@ -131,49 +131,49 @@ event.sendMouseEvent = function(mouseEve
  *
  * This function handles casing of characters (sends the right charcode,
  * and sends a shift key for uppercase chars).  No other modifiers are
  * handled at this point.
  *
  * For now this method only works for English letters (lower and upper
  * case) and the digits 0-9.
  */
-event.sendChar = function(char, window = undefined) {
+event.sendChar = function (char, window = undefined) {
   // DOM event charcodes match ASCII (JS charcodes) for a-zA-Z0-9
   let hasShift = (char == char.toUpperCase());
   event.synthesizeKey(char, {shiftKey: hasShift}, window);
 };
 
 /**
  * Send string to the focused element.
  *
  * For now this method only works for English letters (lower and upper
  * case) and the digits 0-9.
  */
-event.sendString = function(string, window = undefined) {
+event.sendString = function (string, window = undefined) {
   for (let i = 0; i < string.length; ++i) {
     event.sendChar(string.charAt(i), window);
   }
 };
 
 /**
  * Send the non-character key to the focused element.
  *
  * The name of the key should be the part that comes after "DOM_VK_"
  * in the nsIDOMKeyEvent constant name for this key.  No modifiers are
  * handled at this point.
  */
-event.sendKey = function(key, window = undefined) {
+event.sendKey = function (key, window = undefined) {
   let keyName = "VK_" + key.toUpperCase();
   event.synthesizeKey(keyName, {shiftKey: false}, window);
 };
 
 // TODO(ato): Unexpose this when action.Chain#emitMouseEvent
 // no longer emits its own events
-event.parseModifiers_ = function(modifiers) {
+event.parseModifiers_ = function (modifiers) {
   let mval = 0;
   if (modifiers.shiftKey) {
     mval |= Ci.nsIDOMNSEvent.SHIFT_MASK;
   }
   if (modifiers.ctrlKey) {
     mval |= Ci.nsIDOMNSEvent.CONTROL_MASK;
   }
   if (modifiers.altKey) {
@@ -210,17 +210,17 @@ event.parseModifiers_ = function(modifie
  *     Vertical offset to click from the target's bounding box.
  * @param {Object.<string, ?>} opts
  *     Object which may contain the properties "shiftKey", "ctrlKey",
  *     "altKey", "metaKey", "accessKey", "clickCount", "button", and
  *     "type".
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  */
-event.synthesizeMouse = function(
+event.synthesizeMouse = function (
     element, offsetX, offsetY, opts, window = undefined) {
   let rect = element.getBoundingClientRect();
   event.synthesizeMouseAtPoint(
       rect.left + offsetX, rect.top + offsetY, opts, window);
 };
 
 /*
  * Synthesize a mouse event at a particular point in a window.
@@ -234,17 +234,17 @@ event.synthesizeMouse = function(
  *     CSS pixels from the top document margin.
  * @param {Object.<string, ?>} event
  *     Object which may contain the properties "shiftKey", "ctrlKey",
  *     "altKey", "metaKey", "accessKey", "clickCount", "button", and
  *     "type".
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  */
-event.synthesizeMouseAtPoint = function(
+event.synthesizeMouseAtPoint = function (
     left, top, opts, window = undefined) {
 
   let domutils = getDOMWindowUtils(window);
 
   let button = opts.button || 0;
   let clickCount = opts.clickCount || 1;
   let modifiers = event.parseModifiers_(opts);
 
@@ -258,17 +258,17 @@ event.synthesizeMouseAtPoint = function(
         "mouseup", left, top, button, clickCount, modifiers);
   }
 };
 
 /**
  * Call event.synthesizeMouse with coordinates at the centre of the
  * target.
  */
-event.synthesizeMouseAtCenter = function(element, event, window) {
+event.synthesizeMouseAtCenter = function (element, event, window) {
   let rect = element.getBoundingClientRect();
   event.synthesizeMouse(
       element,
       rect.width / 2,
       rect.height / 2,
       event,
       window);
 };
@@ -298,17 +298,17 @@ event.synthesizeMouseAtCenter = function
  * @param {number} offsetY
  * @param {number} offsetY
  * @param {Object.<string, ?>} event
  *     Object which may contain the properties shiftKey, ctrlKey, altKey,
  *     metaKey, accessKey, button, type, axis, delta, and hasPixels.
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  */
-event.synthesizeMouseScroll = function(
+event.synthesizeMouseScroll = function (
     target, offsetX, offsetY, ev, window = undefined) {
 
   let domutils = getDOMWindowUtils(window);
 
   // see nsMouseScrollFlags in nsGUIEvent.h
   const kIsVertical = 0x02;
   const kIsHorizontal = 0x04;
   const kHasPixels = 0x08;
@@ -442,17 +442,17 @@ function computeKeyCodeFromChar_(char) {
 
 /**
  * Returns true if the given key should cause keypress event when widget
  * handles the native key event.  Otherwise, false.
  *
  * The key code should be one of consts of nsIDOMKeyEvent.DOM_VK_*,
  * or a key name begins with "VK_", or a character.
  */
-event.isKeypressFiredKey = function(key) {
+event.isKeypressFiredKey = function (key) {
   if (typeof key == "string") {
     if (key.indexOf("VK_") === 0) {
       key = Ci.nsIDOMKeyEvent["DOM_" + key];
       if (!key) {
         throw new TypeError("Unknown key: " + key);
       }
 
     // if key generates a character, it must cause a keypress event
@@ -491,17 +491,17 @@ event.isKeypressFiredKey = function(key)
  *    of that type is fired.  Otherwise, a keydown, a keypress, and then a
  *     keyup event are fired in sequence.
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  *
  * @throws {TypeError}
  *     If unknown key.
  */
-event.synthesizeKey = function(key, event, win = undefined)
+event.synthesizeKey = function (key, event, win = undefined)
 {
   var TIP = getTIP_(win);
   if (!TIP) {
     return;
   }
   var KeyboardEvent = getKeyboardEvent_(win);
   var modifiers = emulateToActivateModifiers_(TIP, event, win);
   var keyEventDict = createKeyboardEventDictionary_(key, event, win);
@@ -936,17 +936,17 @@ function checkExpectedEvent_(
  *     Expected originalTarget of the event.
  * @param {DOMEvent} expectedEvent
  *     Expected type of the event, such as "select".
  * @param {string} testName
  *     Test name when outputing results.
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  */
-event.synthesizeMouseExpectEvent = function(
+event.synthesizeMouseExpectEvent = function (
     target, offsetX, offsetY, ev, expectedTarget, expectedEvent,
     testName, window = undefined) {
 
   let eventHandler = expectEvent_(
       expectedTarget,
       expectedEvent,
       testName);
   event.synthesizeMouse(target, offsetX, offsetY, ev, window);
@@ -975,17 +975,17 @@ event.synthesizeMouseExpectEvent = funct
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  *
  * To test that an event is not fired, use an expected type preceded by an
  * exclamation mark, such as "!select".
  *
  * aWindow is optional, and defaults to the current window object.
  */
-event.synthesizeKeyExpectEvent = function(
+event.synthesizeKeyExpectEvent = function (
     key, ev, expectedTarget, expectedEvent, testName,
     window = undefined) {
 
   let eventHandler = expectEvent_(
       expectedTarget,
       expectedEvent,
       testName);
   event.synthesizeKey(key, ev, window);
@@ -1004,17 +1004,17 @@ event.synthesizeKeyExpectEvent = functio
  *     member.  The value must be "compositionstart", "compositionend" or
  *     "compositionupdate".  And also this may have |data| and |locale|
  *     which would be used for the value of each property of the
  *     composition event.  Note that the data would be ignored if the
  *     event type were "compositionstart".
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  */
-event.synthesizeComposition = function(ev, window = undefined) {
+event.synthesizeComposition = function (ev, window = undefined) {
   let domutils = getDOMWindowUtils(window);
   domutils.sendCompositionEvent(ev.type, ev.data || "", ev.locale || "");
 };
 
 /**
  * Synthesize a text event.
  *
  * The text event's information, this has |composition| and |caret|
@@ -1049,17 +1049,17 @@ event.synthesizeComposition = function(e
  * larger than 0, it should be wide caret.  However, current nsEditor
  * doesn't support wide caret, therefore, you should always set 0 now.
  *
  * @param {Object.<string, ?>} ev
  *     The text event's information,
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  */
-event.synthesizeText = function(ev, window = undefined) {
+event.synthesizeText = function (ev, window = undefined) {
   let domutils = getDOMWindowUtils(window);
 
   if (!ev.composition ||
       !ev.composition.clauses ||
       !ev.composition.clauses[0]) {
     return;
   }
 
@@ -1101,17 +1101,17 @@ event.synthesizeText = function(ev, wind
  * Synthesize a query selected text event.
  *
  * @param {Window=}
  *     Window object.  Defaults to the current window.
  *
  * @return {(nsIQueryContentEventResult|null)}
  *     Event's result, or null if it failed.
  */
-event.synthesizeQuerySelectedText = function(window = undefined) {
+event.synthesizeQuerySelectedText = function (window = undefined) {
   let domutils = getDOMWindowUtils(window);
   return domutils.sendQueryContentEvent(
       domutils.QUERY_SELECTED_TEXT, 0, 0, 0, 0);
 };
 
 /**
  * Synthesize a selection set event.
  *
@@ -1124,17 +1124,17 @@ event.synthesizeQuerySelectedText = func
  * @param {boolean} reverse
  *     If true, the selection is from |aOffset + aLength| to |aOffset|.
  *     Otherwise, from |aOffset| to |aOffset + aLength|.
  * @param {Window=} window
  *     Window object.  Defaults to the current window.
  *
  * @return         True, if succeeded.  Otherwise false.
  */
-event.synthesizeSelectionSet = function(
+event.synthesizeSelectionSet = function (
     offset, length, reverse, window = undefined) {
   let domutils = getDOMWindowUtils(window);
   return domutils.sendSelectionSetEvent(offset, length, reverse);
 };
 
 const KEYCODES_LOOKUP = {
   "VK_SHIFT": "shiftKey",
   "VK_CONTROL": "ctrlKey",
@@ -1201,33 +1201,33 @@ const VIRTUAL_KEYCODE_LOOKUP = {
 
 function getKeyCode(c) {
   if (c in VIRTUAL_KEYCODE_LOOKUP) {
     return VIRTUAL_KEYCODE_LOOKUP[c];
   }
   return c;
 }
 
-event.sendKeyDown = function(keyToSend, modifiers, document) {
+event.sendKeyDown = function (keyToSend, modifiers, document) {
   modifiers.type = "keydown";
   event.sendSingleKey(keyToSend, modifiers, document);
   if (["VK_SHIFT", "VK_CONTROL", "VK_ALT", "VK_META"].indexOf(getKeyCode(keyToSend)) < 0) {
     modifiers.type = "keypress";
     event.sendSingleKey(keyToSend, modifiers, document);
   }
   delete modifiers.type;
 };
 
-event.sendKeyUp = function(keyToSend, modifiers, window = undefined) {
+event.sendKeyUp = function (keyToSend, modifiers, window = undefined) {
   modifiers.type = "keyup";
   event.sendSingleKey(keyToSend, modifiers, window);
   delete modifiers.type;
 };
 
-event.sendSingleKey = function(keyToSend, modifiers, window = undefined) {
+event.sendSingleKey = function (keyToSend, modifiers, window = undefined) {
   let keyCode = getKeyCode(keyToSend);
   if (keyCode in KEYCODES_LOOKUP) {
     let modName = KEYCODES_LOOKUP[keyCode];
     modifiers[modName] = !modifiers[modName];
   } else if (modifiers.shiftKey) {
     keyCode = keyCode.toUpperCase();
   }
   event.synthesizeKey(keyCode, modifiers, window);
@@ -1252,17 +1252,17 @@ function focusElement(element) {
 }
 
 /**
  * @param {Array.<string>} keySequence
  * @param {Element} element
  * @param {Object.<string, boolean>=} opts
  * @param {Window=} window
  */
-event.sendKeysToElement = function(
+event.sendKeysToElement = function (
     keySequence, el, opts = {}, window = undefined) {
 
   if (opts.ignoreVisibility || element.isVisible(el)) {
     focusElement(el);
 
     // make Object.<modifier, false> map
     let modifiers = Object.create(event.Modifiers);
     for (let modifier in event.Modifiers) {
@@ -1275,60 +1275,60 @@ event.sendKeysToElement = function(
       event.sendSingleKey(c, modifiers, window);
     }
 
   } else {
     throw new ElementNotVisibleError("Element is not visible");
   }
 };
 
-event.sendEvent = function(eventType, el, modifiers = {}, opts = {}) {
+event.sendEvent = function (eventType, el, modifiers = {}, opts = {}) {
   opts.canBubble = opts.canBubble || true;
 
   let doc = el.ownerDocument || el.document;
   let ev = doc.createEvent("Event");
 
   ev.shiftKey = modifiers["shift"];
   ev.metaKey = modifiers["meta"];
   ev.altKey = modifiers["alt"];
   ev.ctrlKey = modifiers["ctrl"];
 
   ev.initEvent(eventType, opts.canBubble, true);
   el.dispatchEvent(ev);
 };
 
-event.focus = function(el, opts = {}) {
+event.focus = function (el, opts = {}) {
   opts.canBubble = opts.canBubble || true;
   let doc = el.ownerDocument || el.document;
   let win = doc.defaultView;
 
   let ev = new win.FocusEvent(el);
   ev.initEvent("focus", opts.canBubble, true);
   el.dispatchEvent(ev);
 };
 
-event.mouseover = function(el, modifiers = {}, opts = {}) {
+event.mouseover = function (el, modifiers = {}, opts = {}) {
   return event.sendEvent("mouseover", el, modifiers, opts);
 };
 
-event.mousemove = function(el, modifiers = {}, opts = {}) {
+event.mousemove = function (el, modifiers = {}, opts = {}) {
   return event.sendEvent("mousemove", el, modifiers, opts);
 };
 
-event.mousedown = function(el, modifiers = {}, opts = {}) {
+event.mousedown = function (el, modifiers = {}, opts = {}) {
   return event.sendEvent("mousedown", el, modifiers, opts);
 };
 
-event.mouseup = function(el, modifiers = {}, opts = {}) {
+event.mouseup = function (el, modifiers = {}, opts = {}) {
   return event.sendEvent("mouseup", el, modifiers, opts);
 };
 
-event.click = function(el, modifiers = {}, opts = {}) {
+event.click = function (el, modifiers = {}, opts = {}) {
   return event.sendEvent("click", el, modifiers, opts);
 };
 
-event.change = function(el, modifiers = {}, opts = {}) {
+event.change = function (el, modifiers = {}, opts = {}) {
   return event.sendEvent("change", el, modifiers, opts);
 };
 
-event.input = function(el, modifiers = {}, opts = {}) {
+event.input = function (el, modifiers = {}, opts = {}) {
   return event.sendEvent("input", el, modifiers, opts);
 };
--- a/testing/marionette/frame.js
+++ b/testing/marionette/frame.js
@@ -17,17 +17,17 @@ const FRAME_SCRIPT = "chrome://marionett
 
 // list of OOP frames that has the frame script loaded
 var remoteFrames = [];
 
 /**
  * An object representing a frame that Marionette has loaded a
  * frame script in.
  */
-frame.RemoteFrame = function(windowId, frameId) {
+frame.RemoteFrame = function (windowId, frameId) {
   // outerWindowId relative to main process
   this.windowId = windowId;
   // actual frame relative to the windowId's frames list
   this.frameId = frameId;
   // assigned frame ID, used for messaging
   this.targetFrameId = this.frameId;
   // list of OOP frames that has the frame script loaded
   this.remoteFrames = [];
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py
@@ -2,17 +2,22 @@
 # 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
 
 from marionette_driver.by import By
 from marionette_driver.errors import JavascriptException
 
-from marionette_harness import MarionetteTestCase, WindowManagerMixin, skip_if_chrome
+from marionette_harness import (
+    MarionetteTestCase,
+    skip_if_chrome,
+    skip_if_mobile,
+    WindowManagerMixin,
+)
 
 
 class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase):
     contexts = set(["chrome", "content"])
 
     script_file = os.path.abspath(
         os.path.join(__file__, os.path.pardir, "importscript.js"))
     another_script_file = os.path.abspath(
@@ -100,16 +105,17 @@ class TestImportScriptContent(WindowMana
 
     def test_multiple_imports(self):
         self.marionette.import_script(self.script_file)
         self.marionette.import_script(self.another_script_file)
         self.assert_defined("testFunc")
         self.assert_defined("testAnotherFunc")
 
     @skip_if_chrome
+    @skip_if_mobile  # New windows not supported in Fennec
     def test_imports_apply_globally(self):
         self.marionette.navigate(
             self.marionette.absolute_url("test_windows.html"))
 
         def open_window_with_link():
             self.marionette.find_element(By.LINK_TEXT, "Open new window").click()
 
         new_window = self.open_window(trigger=open_window_with_link)
--- a/testing/marionette/interaction.js
+++ b/testing/marionette/interaction.js
@@ -168,17 +168,17 @@ interaction.clickElement = function*(el,
  * area of the first DOM client rectangle that is inside the viewport.
  *
  * @param {DOMElement} el
  *     Element to calculate the visible centre point of.
  *
  * @return {Object.<string, number>}
  *     X- and Y-position.
  */
-interaction.calculateCentreCoords = function(el) {
+interaction.calculateCentreCoords = function (el) {
   let rects = el.getClientRects();
   return {
     x: rects[0].left + rects[0].width / 2.0,
     y: rects[0].top + rects[0].height / 2.0,
   };
 };
 
 /**
@@ -193,17 +193,17 @@ interaction.calculateCentreCoords = func
  * @param {HTMLOptionElement} option
  *     Option element to select.
  *
  * @throws TypeError
  *     If |el| is a XUL element or not an <option> element.
  * @throws Error
  *     If unable to find |el|'s parent <select> element.
  */
-interaction.selectOption = function(el) {
+interaction.selectOption = function (el) {
   if (element.isXULElement(el)) {
     throw new Error("XUL dropdowns not supported");
   }
   if (el.localName != "option") {
     throw new TypeError("Invalid elements");
   }
 
   let win = getWindow(el);
@@ -226,17 +226,17 @@ interaction.selectOption = function(el) 
 /**
  * Appends |path| to an <input type=file>'s file list.
  *
  * @param {HTMLInputElement} el
  *     An <input type=file> element.
  * @param {string} path
  *     Full path to file.
  */
-interaction.uploadFile = function(el, path) {
+interaction.uploadFile = function (el, path) {
   let file;
   try {
     file = File.createFromFileName(path);
   } catch (e) {
     throw new InvalidArgumentError("File not found: " + path);
   }
 
   let fs = Array.prototype.slice.call(el.files);
@@ -264,17 +264,17 @@ interaction.uploadFile = function(el, pa
  *     Option element.
  *
  * @return {HTMLSelectElement}
  *     Select element wrapping |optionEl|.
  *
  * @throws {Error}
  *     If unable to find the <select> element.
  */
-interaction.getSelectForOptionElement = function(optionEl) {
+interaction.getSelectForOptionElement = function (optionEl) {
   let parent = optionEl;
   while (parent.parentNode && parent.localName != "select") {
     parent = parent.parentNode;
   }
 
   if (parent.localName != "select") {
     throw new Error("Unable to find parent of <option> element");
   }
@@ -289,17 +289,17 @@ interaction.getSelectForOptionElement = 
  *     Element to send key events to.
  * @param {Array.<string>} value
  *     Sequence of keystrokes to send to the element.
  * @param {boolean} ignoreVisibility
  *     Flag to enable or disable element visibility tests.
  * @param {boolean=} strict
  *     Enforce strict accessibility tests.
  */
-interaction.sendKeysToElement = function(el, value, ignoreVisibility, strict = false) {
+interaction.sendKeysToElement = function (el, value, ignoreVisibility, strict = false) {
   let win = getWindow(el);
   let a11y = accessibility.get(strict);
   return a11y.getAccessible(el, true).then(acc => {
     a11y.assertActionable(acc, el);
     event.sendKeysToElement(value, el, {ignoreVisibility: false}, win);
   });
 };
 
@@ -309,17 +309,17 @@ interaction.sendKeysToElement = function
  * @param {DOMElement|XULElement} el
  *     Element to determine displayedness of.
  * @param {boolean=} strict
  *     Enforce strict accessibility tests.
  *
  * @return {boolean}
  *     True if element is displayed, false otherwise.
  */
-interaction.isElementDisplayed = function(el, strict = false) {
+interaction.isElementDisplayed = function (el, strict = false) {
   let win = getWindow(el);
   let displayed = atom.isElementDisplayed(el, win);
 
   let a11y = accessibility.get(strict);
   return a11y.getAccessible(el).then(acc => {
     a11y.assertVisible(acc, el, displayed);
     return displayed;
   });
@@ -329,17 +329,17 @@ interaction.isElementDisplayed = functio
  * Check if element is enabled.
  *
  * @param {DOMElement|XULElement} el
  *     Element to test if is enabled.
  *
  * @return {boolean}
  *     True if enabled, false otherwise.
  */
-interaction.isElementEnabled = function(el, strict = false) {
+interaction.isElementEnabled = function (el, strict = false) {
   let enabled = true;
   let win = getWindow(el);
 
   if (element.isXULElement(el)) {
     // check if XUL element supports disabled attribute
     if (DISABLED_ATTRIBUTE_SUPPORTED_XUL.has(el.tagName.toUpperCase())) {
       let disabled = atom.getElementAttribute(el, "disabled", win);
       if (disabled && disabled === "true") {
@@ -366,17 +366,17 @@ interaction.isElementEnabled = function(
  * @param {DOMElement|XULElement} el
  *     Element to test if is selected.
  * @param {boolean=} strict
  *     Enforce strict accessibility tests.
  *
  * @return {boolean}
  *     True if element is selected, false otherwise.
  */
-interaction.isElementSelected = function(el, strict = false) {
+interaction.isElementSelected = function (el, strict = false) {
   let selected = true;
   let win = getWindow(el);
 
   if (element.isXULElement(el)) {
     let tagName = el.tagName.toUpperCase();
     if (CHECKED_PROPERTY_SUPPORTED_XUL.has(tagName)) {
       selected = el.checked;
     }
--- a/testing/marionette/l10n.js
+++ b/testing/marionette/l10n.js
@@ -37,17 +37,17 @@ this.l10n = {};
  * @param {Array.<string>} urls
  *     Array of .dtd URLs.
  * @param {string} id
  *     The ID of the entity to retrieve the localized string for.
  *
  * @return {string}
  *     The localized string for the requested entity.
  */
-l10n.localizeEntity = function(urls, id) {
+l10n.localizeEntity = function (urls, id) {
   // Add xhtml11.dtd to prevent missing entity errors with XHTML files
   urls.push("resource:///res/dtd/xhtml11.dtd");
 
   // Build a string which contains all possible entity locations
   let locations = [];
   urls.forEach((url, index) => {
     locations.push(`<!ENTITY % dtd_${index} SYSTEM "${url}">%dtd_${index};`);
   })
@@ -74,17 +74,17 @@ l10n.localizeEntity = function(urls, id)
  * @param {Array.<string>} urls
  *     Array of .properties URLs.
  * @param {string} id
  *     The ID of the property to retrieve the localized string for.
  *
  * @return {string}
  *     The localized string for the requested property.
  */
-l10n.localizeProperty = function(urls, id) {
+l10n.localizeProperty = function (urls, id) {
   let property = null;
 
   for (let url of urls) {
     let bundle = Services.strings.createBundle(url);
     try {
       property = bundle.GetStringFromName(id);
       break;
     } catch (e) {}
--- a/testing/marionette/legacyaction.js
+++ b/testing/marionette/legacyaction.js
@@ -17,17 +17,17 @@ this.EXPORTED_SYMBOLS = ["action"];
 
 const logger = Log.repository.getLogger("Marionette");
 
 this.action = {};
 
 /**
  * Functionality for (single finger) action chains.
  */
-action.Chain = function(checkForInterrupted) {
+action.Chain = function (checkForInterrupted) {
   // for assigning unique ids to all touches
   this.nextTouchId = 1000;
   // keep track of active Touches
   this.touchIds = {};
   // last touch for each fingerId
   this.lastCoordinates = null;
   this.isTap = false;
   this.scrolling = false;
@@ -40,17 +40,17 @@ action.Chain = function(checkForInterrup
   } else {
     this.checkForInterrupted = () => {};
   }
 
   // determines if we create touch events
   this.inputSource = null;
 };
 
-action.Chain.prototype.dispatchActions = function(
+action.Chain.prototype.dispatchActions = function (
     args,
     touchId,
     container,
     seenEls,
     touchProvider) {
   // Some touch events code in the listener needs to do ipc, so we can't
   // share this code across chrome/content.
   if (touchProvider) {
@@ -93,17 +93,17 @@ action.Chain.prototype.dispatchActions =
  *     Number of clicks, button notes the mouse button.
  * @param {number} elClientX
  *     X coordinate of the mouse relative to the viewport.
  * @param {number} elClientY
  *     Y coordinate of the mouse relative to the viewport.
  * @param {Object} modifiers
  *     An object of modifier keys present.
  */
-action.Chain.prototype.emitMouseEvent = function(
+action.Chain.prototype.emitMouseEvent = function (
     doc,
     type,
     elClientX,
     elClientY,
     button,
     clickCount,
     modifiers) {
   if (!this.checkForInterrupted()) {
@@ -162,17 +162,17 @@ action.Chain.prototype.resetValues = fun
  * @param {Object.<string, boolean>} keyModifiers
  *     Keeps track of keyDown/keyUp pairs through an action chain.
  * @param {function(?)} cb
  *     Called on success.
  *
  * @return {Object.<string, number>}
  *     Last finger ID, or an empty object.
  */
-action.Chain.prototype.actions = function(chain, touchId, i, keyModifiers, cb) {
+action.Chain.prototype.actions = function (chain, touchId, i, keyModifiers, cb) {
   if (i == chain.length) {
     cb(touchId || null);
     this.resetValues();
     return;
   }
 
   let pack = chain[i];
   let command = pack[0];
@@ -312,17 +312,17 @@ action.Chain.prototype.actions = functio
       break;
   }
 };
 
 /**
  * Given an element and a pair of coordinates, returns an array of the
  * form [clientX, clientY, pageX, pageY, screenX, screenY].
  */
-action.Chain.prototype.getCoordinateInfo = function(el, corx, cory) {
+action.Chain.prototype.getCoordinateInfo = function (el, corx, cory) {
   let win = el.ownerDocument.defaultView;
   return [
     corx, // clientX
     cory, // clientY
     corx + win.pageXOffset, // pageX
     cory + win.pageYOffset, // pageY
     corx + win.mozInnerScreenX, // screenX
     cory + win.mozInnerScreenY // screenY
@@ -332,17 +332,17 @@ action.Chain.prototype.getCoordinateInfo
 /**
  * @param {number} x
  *     X coordinate of the location to generate the event that is relative
  *     to the viewport.
  * @param {number} y
  *     Y coordinate of the location to generate the event that is relative
  *     to the viewport.
  */
-action.Chain.prototype.generateEvents = function(
+action.Chain.prototype.generateEvents = function (
     type, x, y, touchId, target, keyModifiers) {
   this.lastCoordinates = [x, y];
   let doc = this.container.frame.document;
 
   switch (type) {
     case "tap":
       if (this.mouseEventsOnly) {
         this.mouseTap(
@@ -465,13 +465,13 @@ action.Chain.prototype.generateEvents = 
       break;
 
     default:
       throw new WebDriverError("Unknown event type: " + type);
   }
   this.checkForInterrupted();
 };
 
-action.Chain.prototype.mouseTap = function(doc, x, y, button, count, mod) {
+action.Chain.prototype.mouseTap = function (doc, x, y, button, count, mod) {
   this.emitMouseEvent(doc, "mousemove", x, y, button, count, mod);
   this.emitMouseEvent(doc, "mousedown", x, y, button, count, mod);
   this.emitMouseEvent(doc, "mouseup", x, y, button, count, mod);
 };
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -174,17 +174,17 @@ function emitTouchEventForIFrame(message
 //
 // Perhaps one could even conceive having a separate instance of
 // CommandProcessor for the listener, because the code is mostly the same.
 function dispatch(fn) {
   if (typeof fn != "function") {
     throw new TypeError("Provided dispatch handler is not a function");
   }
 
-  return function(msg) {
+  return function (msg) {
     let id = msg.json.command_id;
 
     let req = Task.spawn(function*() {
       if (typeof msg.json == "undefined" || msg.json instanceof Array) {
         return yield fn.apply(null, msg.json);
       } else {
         return yield fn(msg.json);
       }
@@ -686,21 +686,21 @@ function actionChain(chain, touchId) {
  * Function to emit touch events which allow multi touch on the screen
  * @param type represents the type of event, touch represents the current touch,touches are all pending touches
  */
 function emitMultiEvents(type, touch, touches) {
   let target = touch.target;
   let doc = target.ownerDocument;
   let win = doc.defaultView;
   // touches that are in the same document
-  let documentTouches = doc.createTouchList(touches.filter(function(t) {
+  let documentTouches = doc.createTouchList(touches.filter(function (t) {
     return ((t.target.ownerDocument === doc) && (type != 'touchcancel'));
   }));
   // touches on the same target
-  let targetTouches = doc.createTouchList(touches.filter(function(t) {
+  let targetTouches = doc.createTouchList(touches.filter(function (t) {
     return ((t.target === target) && ((type != 'touchcancel') || (type != 'touchend')));
   }));
   // Create changed touches
   let changedTouches = doc.createTouchList(touch);
   // Create the event object
   let event = doc.createEvent('TouchEvent');
   event.initTouchEvent(type,
                        true,
--- a/testing/marionette/mach_commands.py
+++ b/testing/marionette/mach_commands.py
@@ -19,26 +19,26 @@ from mach.decorators import (
     Command,
 )
 
 def is_firefox_or_android(cls):
     """Must have Firefox build or Android build."""
     return conditions.is_firefox(cls) or conditions.is_android(cls)
 
 def setup_marionette_argument_parser():
-    from marionette.runtests import MarionetteArguments
+    from marionette_harness.runtests import MarionetteArguments
     from mozlog.structured import commandline
     parser = MarionetteArguments()
     commandline.add_logging_group(parser)
     return parser
 
 def run_marionette(tests, binary=None, topsrcdir=None, **kwargs):
     from mozlog.structured import commandline
 
-    from marionette.runtests import (
+    from marionette_harness.runtests import (
         MarionetteTestRunner,
         MarionetteHarness
     )
 
     parser = setup_marionette_argument_parser()
 
     if not tests:
         tests = [os.path.join(topsrcdir,
--- a/testing/marionette/message.js
+++ b/testing/marionette/message.js
@@ -36,17 +36,17 @@ this.Message = {};
  *     or result.
  *
  * @return {(Command,Response)}
  *     Based on the message type, a Command or Response instance.
  *
  * @throws {TypeError}
  *     If the message type is not recognised.
  */
-Message.fromMsg = function(data) {
+Message.fromMsg = function (data) {
   switch (data[0]) {
     case Command.TYPE:
       return Command.fromMsg(data);
 
     case Response.TYPE:
       return Response.fromMsg(data);
 
     default:
@@ -147,17 +147,17 @@ Command.TYPE = 0;
 const validator = {
   exclusionary: {
     "capabilities": ["error", "value"],
     "error": ["value", "sessionId", "capabilities"],
     "sessionId": ["error", "value"],
     "value": ["error", "sessionId", "capabilities"],
   },
 
-  set: function(obj, prop, val) {
+  set: function (obj, prop, val) {
     let tests = this.exclusionary[prop];
     if (tests) {
       for (let t of tests) {
         if (obj.hasOwnProperty(t)) {
           throw new TypeError(`${t} set, cannot set ${prop}`);
         }
       }
     }
--- a/testing/marionette/modal.js
+++ b/testing/marionette/modal.js
@@ -32,17 +32,17 @@ modal = {
  * This function is a no-op if called on any other product than Firefox.
  *
  * @param {function(Object, string)} handler
  *     The handler to be called, which is passed the
  *     subject (e.g. ChromeWindow) and the topic (one of
  *     {@code modal.COMMON_DIALOG_LOADED} or
  *     {@code modal.TABMODAL_DIALOG_LOADED}.
  */
-modal.addHandler = function(handler) {
+modal.addHandler = function (handler) {
   if (!isFirefox()) {
     return;
   }
 
   Object.keys(this.handlers).map(topic => {
     this.handlers[topic].add(handler);
     Services.obs.addObserver(handler, topic, false);
   });
@@ -52,17 +52,17 @@ modal.addHandler = function(handler) {
  * Remove modal dialogue handler by function reference.
  *
  * This function is a no-op if called on any other product than Firefox.
  *
  * @param {function} toRemove
  *     The handler previously passed to modal.addHandler which will now
  *     be removed.
  */
-modal.removeHandler = function(toRemove) {
+modal.removeHandler = function (toRemove) {
   if (!isFirefox()) {
     return;
   }
 
   for (let topic of Object.keys(this.handlers)) {
     let handlers = this.handlers[topic];
     for (let handler of handlers) {
       if (handler == toRemove) {
--- a/testing/marionette/navigate.js
+++ b/testing/marionette/navigate.js
@@ -23,17 +23,17 @@ this.navigate = {};
  *
  * @return {boolean}
  *     Full page load would be expected if future is followed.
  *
  * @throws TypeError
  *     If |current| is not defined, or any of |current| or |future|
  *     are invalid URLs.
  */
-navigate.isLoadEventExpected = function(current, future = undefined) {
+navigate.isLoadEventExpected = function (current, future = undefined) {
   if (typeof current == "undefined") {
     throw TypeError("Expected at least one URL");
   }
 
   // assume we will go somewhere exciting
   if (typeof future == "undefined") {
     return true;
   }
@@ -89,17 +89,17 @@ navigate.isLoadEventExpected = function(
  *
  * @return {navigate.IdempotentURL}
  *     Considered by some to be a somewhat saner URL.
  *
  * @throws TypeError
  *     If |o| is not a valid type or if is a string that cannot be parsed
  *     as a URL.
  */
-navigate.IdempotentURL = function(o) {
+navigate.IdempotentURL = function (o) {
   let url = new URL(o);
 
   let hash = url.hash;
   if (hash == "" && url.href[url.href.length - 1] == "#") {
     hash = "#";
   }
 
   return {
--- a/testing/marionette/proxy.js
+++ b/testing/marionette/proxy.js
@@ -39,17 +39,17 @@ this.proxy = {};
  * passed literally.  The latter specialisation is temporary to achieve
  * backwards compatibility with listener.js.
  *
  * @param {function(): (nsIMessageSender|nsIMessageBroadcaster)} mmFn
  *     Closure function returning the current message manager.
  * @param {function(string, Object, number)} sendAsyncFn
  *     Callback for sending async messages.
  */
-proxy.toListener = function(mmFn, sendAsyncFn) {
+proxy.toListener = function (mmFn, sendAsyncFn) {
   let sender = new proxy.AsyncMessageChannel(mmFn, sendAsyncFn);
   return new Proxy(sender, ownPriorityGetterTrap);
 };
 
 /**
  * Provides a transparent interface between chrome- and content space.
  *
  * The AsyncMessageChannel is an abstraction of the message manager
@@ -250,17 +250,17 @@ proxy.AsyncMessageChannel.ReplyType = {
 /**
  * A transparent content-to-chrome RPC interface where responses are
  * presented as promises.
  *
  * @param {nsIFrameMessageManager} frameMessageManager
  *     The content frame's message manager, which itself is usually an
  *     implementor of.
  */
-proxy.toChromeAsync = function(frameMessageManager) {
+proxy.toChromeAsync = function (frameMessageManager) {
   let sender = new AsyncChromeSender(frameMessageManager);
   return new Proxy(sender, ownPriorityGetterTrap);
 };
 
 /**
  * Sends asynchronous RPC messages to chrome space using a frame's
  * sendAsyncMessage (nsIAsyncMessageSender) function.
  *
@@ -329,17 +329,17 @@ this.AsyncChromeSender = class {
  * Example on how to use from a frame content script:
  *
  *     let chrome = proxy.toChrome(sendSyncMessage.bind(this));
  *     let cookie = chrome.getCookie("foo");
  *
  * @param {nsISyncMessageSender} sendSyncMessageFn
  *     The frame message manager's sendSyncMessage function.
  */
-proxy.toChrome = function(sendSyncMessageFn) {
+proxy.toChrome = function (sendSyncMessageFn) {
   let sender = new proxy.SyncChromeSender(sendSyncMessageFn);
   return new Proxy(sender, ownPriorityGetterTrap);
 };
 
 /**
  * The SyncChromeSender sends synchronous RPC messages to the chrome
  * context, using a frame's sendSyncMessage (nsISyncMessageSender)
  * function.
@@ -355,14 +355,14 @@ proxy.SyncChromeSender = class {
   }
 
   send(func, args) {
     let name = "Marionette:" + func.toString();
     return this.sendSyncMessage_(name, marshal(args));
   }
 };
 
-var marshal = function(args) {
+var marshal = function (args) {
   if (args.length == 1 && typeof args[0] == "object") {
     return args[0];
   }
   return args;
 };
--- a/testing/marionette/server.js
+++ b/testing/marionette/server.js
@@ -36,17 +36,17 @@ const MANAGE_OFFLINE_STATUS_PREF = "netw
  * created.
  *
  * @param {number} port
  *     Port for server to listen to.
  * @param {boolean} forceLocal
  *     Listen only to connections from loopback if true.  If false,
  *     accept all connections.
  */
-this.MarionetteServer = function(port, forceLocal) {
+this.MarionetteServer = function (port, forceLocal) {
   this.port = port;
   this.forceLocal = forceLocal;
   this.conns = {};
   this.nextConnId = 0;
   this.alive = false;
   this._acceptConnections = false;
 };
 
@@ -69,17 +69,17 @@ MarionetteServer.prototype.driverFactory
       Preferences.set(MANAGE_OFFLINE_STATUS_PREF, false);
       Services.io.manageOfflineStatus = false;
       Services.io.offline = false;
   }
 
   return new GeckoDriver(appName, this);
 };
 
-MarionetteServer.prototype.__defineSetter__("acceptConnections", function(value) {
+MarionetteServer.prototype.__defineSetter__("acceptConnections", function (value) {
   if (!value) {
     logger.info("New connections will no longer be accepted");
   } else {
     logger.info("New connections are accepted again");
   }
 
   this._acceptConnections = value;
 });
@@ -107,17 +107,17 @@ MarionetteServer.prototype.stop = functi
   this._acceptConnections = false;
 };
 
 MarionetteServer.prototype.closeListener = function() {
   this.listener.close();
   this.listener = null;
 };
 
-MarionetteServer.prototype.onSocketAccepted = function(
+MarionetteServer.prototype.onSocketAccepted = function (
     serverSocket, clientSocket) {
   if (!this._acceptConnections) {
     logger.warn("New connections are currently not accepted");
     return;
   }
 
   let input = clientSocket.openInputStream(0, 0, 0);
   let output = clientSocket.openOutputStream(0, 0, 0);
@@ -128,17 +128,17 @@ MarionetteServer.prototype.onSocketAccep
   dispatcher.onclose = this.onConnectionClosed.bind(this);
   this.conns[connId] = dispatcher;
 
   logger.debug(`Accepted connection ${connId} from ${clientSocket.host}:${clientSocket.port}`);
   dispatcher.sayHello();
   transport.ready();
 };
 
-MarionetteServer.prototype.onConnectionClosed = function(conn) {
+MarionetteServer.prototype.onConnectionClosed = function (conn) {
   let id = conn.connId;
   delete this.conns[id];
   logger.debug(`Closed connection ${id}`);
 };
 
 function isMulet() {
   return Preferences.get("b2g.is_mulet", false);
 }
--- a/testing/marionette/test_action.js
+++ b/testing/marionette/test_action.js
@@ -60,17 +60,17 @@ add_test(function test_processPointerUpD
   equal(act.button, actionItem.button);
 
   run_next_test();
 });
 
 add_test(function test_validateActionDurationAndCoordinates() {
   let actionItem = {};
   let actionSequence = {id: "some_id"};
-  let check = function(type, subtype, message = undefined) {
+  let check = function (type, subtype, message = undefined) {
     message = message || `duration: ${actionItem.duration}, subtype: ${subtype}`;
     actionItem.type = subtype;
     actionSequence.type = type;
     checkErrors(/Expected '.*' \(.*\) to be >= 0/,
         action.Action.fromJson, [actionSequence, actionItem], message);
   };
   for (let d of [-1, "a"]) {
     actionItem.duration = d;
@@ -206,17 +206,17 @@ add_test(function test_processPauseActio
   equal(act.duration, actionItem.duration);
 
   run_next_test();
 });
 
 add_test(function test_processActionSubtypeValidation() {
   let actionItem = {type: "dancing"};
   let actionSequence = {id: "some_id"};
-  let check = function(regex) {
+  let check = function (regex) {
     let message = `type: ${actionSequence.type}, subtype: ${actionItem.type}`;
     checkErrors(regex, action.Action.fromJson, [actionSequence, actionItem], message);
   };
   for (let type of ["none", "key", "pointer"]) {
     actionSequence.type = type;
     check(new RegExp(`Unknown subtype for ${type} action`));
   }
   run_next_test();
--- a/testing/web-platform/harness/wptrunner/executors/testharness_marionette.js
+++ b/testing/web-platform/harness/wptrunner/executors/testharness_marionette.js
@@ -9,17 +9,17 @@ window.wrappedJSObject.addEventListener(
     if (event.data.type != "complete") {
         return;
     }
     window.wrappedJSObject.removeEventListener("message", listener);
     clearTimeout(timer);
     var tests = event.data.tests;
     var status = event.data.status;
 
-    var subtest_results = tests.map(function(x) {
+    var subtest_results = tests.map(function (x) {
         return [x.name, x.status, x.message, x.stack]
     });
 
     marionetteScriptFinished(["%(url)s",
                               status.status,
                               status.message,
                               status.stack,
                               subtest_results]);
--- a/toolkit/.eslintrc.js
+++ b/toolkit/.eslintrc.js
@@ -146,21 +146,21 @@ module.exports = {
 
     // Error on newline where a semicolon is needed
     "no-unexpected-multiline": "error",
 
     // No unreachable statements
     "no-unreachable": "error",
 
     // No declaring variables that are never used
-    // "no-unused-vars": ["error", {
-    //   "vars": "local",
-    //   "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
-    //   "args": "none",
-    // }],
+    "no-unused-vars": ["error", {
+      "vars": "local",
+      "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
+      "args": "none",
+    }],
 
     // No using variables before defined
     // "no-use-before-define": ["error", "nofunc"],
 
     // No using with
     "no-with": "error",
 
     // No spacing inside rest or spread expressions
--- a/toolkit/components/.eslintrc.js
+++ b/toolkit/components/.eslintrc.js
@@ -1,11 +1,6 @@
 "use strict";
 
 module.exports = {
   "rules": {
-    "no-unused-vars": ["error", {
-      "vars": "local",
-      "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS",
-      "args": "none",
-    }]
   }
 };
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -250,17 +250,24 @@ this.PageThumbs = {
     }
     if (aBrowser.isRemoteBrowser) {
       let mm = aBrowser.messageManager;
       let resultFunc = function(aMsg) {
         mm.removeMessageListener("Browser:Thumbnail:CheckState:Response", resultFunc);
         aCallback(aMsg.data.result);
       }
       mm.addMessageListener("Browser:Thumbnail:CheckState:Response", resultFunc);
-      mm.sendAsyncMessage("Browser:Thumbnail:CheckState");
+      try {
+        mm.sendAsyncMessage("Browser:Thumbnail:CheckState");
+      } catch (ex) {
+        Cu.reportError(ex);
+        // If the message manager is not able send our message, taking a content
+        // screenshot is also not going to work: return false.
+        resultFunc({ data: { result: false } });
+      }
     } else {
       aCallback(PageThumbUtils.shouldStoreContentThumbnail(aBrowser.contentDocument,
                                                            aBrowser.docShell));
     }
   },
 
   // The background thumbnail service captures to canvas but doesn't want to
   // participate in this service's telemetry, which is why this method exists.
--- a/toolkit/content/aboutSupport.js
+++ b/toolkit/content/aboutSupport.js
@@ -432,17 +432,17 @@ var snapshotFormatters = {
       }
       addRow(id, "gpuActive", strings.GetStringFromName(active));
       addRows(id, trs);
     }
     showGpu("gpu-1", "");
     showGpu("gpu-2", "2");
 
     // Remove adapter keys.
-    for (let [prop, key] of adapterKeys) {
+    for (let [prop, /* key */] of adapterKeys) {
       delete data[prop];
       delete data[prop + "2"];
     }
     delete data.isGPU2Active;
 
     let featureLog = data.featureLog;
     delete data.featureLog;
 
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -409,17 +409,16 @@ var PingPicker = {
     // Update the displayed ping.
     yield this._updateArchivedPingData();
   }),
 
   _renderWeeks: function() {
     let weekSelector = document.getElementById("choose-ping-week");
     removeAllChildNodes(weekSelector);
 
-    let index = 0;
     for (let week of this._weeks) {
       let text = shortDateString(week.startDate)
                  + " - " + shortDateString(yesterday(week.endDate));
 
       let option = document.createElement("option");
       let content = document.createTextNode(text);
       option.appendChild(content);
       weekSelector.appendChild(option);
@@ -623,17 +622,16 @@ var EnvironmentData = {
     let table = document.createElement("table");
     table.setAttribute("id", sectionTitle);
     this.appendAddonSubsectionTitle(sectionTitle, table);
     this.appendRow(table, "persona", addonObj.persona);
     addonSection.appendChild(table);
   },
 
   renderActivePlugins: function(addonObj, addonSection, sectionTitle) {
-    let data = explodeObject(addonObj);
     let table = document.createElement("table");
     table.setAttribute("id", sectionTitle);
     this.appendAddonSubsectionTitle(sectionTitle, table);
 
     for (let plugin of addonObj) {
       let data = explodeObject(plugin);
       this.appendHeadingName(table, data.get("name"));
 
--- a/toolkit/content/aboutwebrtc/aboutWebrtc.js
+++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js
@@ -267,17 +267,16 @@ AecLogging.prototype.offState = function
   } catch (e) {
     this._message = null;
   }
 };
 
 AecLogging.prototype.onState = function() {
   this._label = getString("aec_logging_on_state_label");
   try {
-    let file = Services.prefs.getCharPref("media.webrtc.debug.aec_log_dir");
     this._message = getString("aec_logging_on_state_msg");
   } catch (e) {
     this._message = null;
   }
 };
 
 AecLogging.prototype.onClick = function() {
   if (WebrtcGlobalInformation.aecDebug) {
@@ -673,21 +672,41 @@ ICEStats.prototype = {
        getString("priority"), getString("nominated"), getString("selected")],
       tbody);
 
     let div = document.createElement("div");
     let heading = document.createElement("h4");
 
     heading.textContent = getString("ice_stats_heading");
     div.appendChild(heading);
+
     div.appendChild(statsTable.render());
+    div.appendChild(this.renderIceMetric("ice_restart_count_label",
+                                         this._report.iceRestarts));
+    div.appendChild(this.renderIceMetric("ice_rollback_count_label",
+                                         this._report.iceRollbacks));
 
     return div;
   },
 
+  renderIceMetric: function(labelName, value) {
+    let info = document.createElement("div");
+    let label = document.createElement("span");
+    let body = document.createElement("span");
+
+    label.className = "info-label";
+    label.textContent = `${getString(labelName)}: `;
+    info.appendChild(label);
+
+    body.className = "info-body";
+    body.textContent = value;
+    info.appendChild(body);
+    return info;
+  },
+
   generateICEStats: function() {
     // Create an index based on candidate ID for each element in the
     // iceCandidateStats array.
     let candidates = new Map();
 
     for (let candidate of this._report.iceCandidateStats) {
       candidates.set(candidate.id, candidate);
     }
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -433,17 +433,16 @@ var Printing = {
       sendAsyncMessage("Printing:Error", {
         isPrinting: wbp.doingPrint,
         nsresult: nsresult,
       });
     }
   },
 
   receiveMessage(message) {
-    let objects = message.objects;
     let data = message.data;
     switch (message.name) {
       case "Printing:Preview:Enter": {
         this.enterPrintPreview(Services.wm.getOuterWindowWithId(data.windowID), data.simplifiedMode);
         break;
       }
 
       case "Printing:Preview:Exit": {
@@ -659,17 +658,16 @@ var Printing = {
   },
 
   exitPrintPreview() {
     docShell.printPreview.exitPrintPreview();
   },
 
   print(contentWindow, simplifiedMode) {
     let printSettings = this.getPrintSettings();
-    let rv = Cr.NS_OK;
 
     // If we happen to be on simplified mode, we need to set docURL in order
     // to generate header/footer content correctly, since simplified tab has
     // "about:blank" as its URI.
     if (printSettings && simplifiedMode) {
       printSettings.docURL = contentWindow.document.baseURI;
     }
 
--- a/toolkit/content/tests/browser/browser_bug1170531.js
+++ b/toolkit/content/tests/browser/browser_bug1170531.js
@@ -1,26 +1,15 @@
 // Test for bug 1170531
 // https://bugzilla.mozilla.org/show_bug.cgi?id=1170531
 
 add_task(function* () {
   // Get a bunch of DOM nodes
-  let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).
-        getInterface(Ci.nsIDOMWindowUtils);
-
   let editMenu = document.getElementById("edit-menu");
-  let menubar = editMenu.parentNode;
   let menuPopup = editMenu.menupopup;
-  let editMenuIndex = -1;
-  for (let i = 0; i < menubar.children.length; i++) {
-    if (menubar.children[i] === editMenu) {
-      editMenuIndex = i;
-      break;
-    }
-  }
 
   let closeMenu = function(aCallback) {
     if (OS.Constants.Sys.Name == "Darwin") {
       executeSoon(aCallback);
       return;
     }
 
     menuPopup.addEventListener("popuphidden", function onPopupHidden() {
--- a/toolkit/content/tests/browser/browser_contentTitle.js
+++ b/toolkit/content/tests/browser/browser_contentTitle.js
@@ -1,13 +1,12 @@
 var url = "https://example.com/browser/toolkit/content/tests/browser/file_contentTitle.html";
 
 add_task(function*() {
   let tab = gBrowser.selectedTab = gBrowser.addTab(url);
-  let browser = tab.linkedBrowser;
   yield new Promise((resolve) => {
     addEventListener("TestLocationChange", function listener() {
       removeEventListener("TestLocationChange", listener);
       resolve();
     }, true, true);
   });
 
   is(gBrowser.contentTitle, "Test Page", "Should have the right title.");
--- a/toolkit/content/tests/browser/browser_crash_previous_frameloader.js
+++ b/toolkit/content/tests/browser/browser_crash_previous_frameloader.js
@@ -95,17 +95,17 @@ add_task(function* test_crash_in_previou
       setTimeout(() => {
         dump("\nEt tu, Brute?\n");
         dies();
       }, 0);
     });
 
     gBrowser.updateBrowserRemoteness(browser, false);
     info("Waiting for content process to go away.");
-    let [subject, data] = yield contentProcessGone;
+    let [subject /* , data */] = yield contentProcessGone;
 
     // If we don't clean up the minidump, the harness will
     // complain.
     cleanUpMinidump(subject);
 
     info("Content process is gone!");
     Assert.ok(!sawTabCrashed,
               "Should not have seen the oop-browser-crashed event.");
--- a/toolkit/content/tests/browser/browser_keyevents_during_autoscrolling.js
+++ b/toolkit/content/tests/browser/browser_keyevents_during_autoscrolling.js
@@ -7,17 +7,16 @@ add_task(function * ()
   const kKeyDownEvent  = 1;
   const kKeyPressEvent = 2;
   const kKeyUpEvent    = 4;
   const kAllKeyEvents  = 7;
 
   var expectedKeyEvents;
   var dispatchedKeyEvents;
   var key;
-  var root;
 
   /**
    * Encapsulates EventUtils.sendChar().
    */
   function sendChar(aChar)
   {
     key = aChar;
     dispatchedKeyEvents = kNoKeyEvents;
--- a/toolkit/content/tests/chrome/test_autocomplete_with_composition_on_input.html
+++ b/toolkit/content/tests/chrome/test_autocomplete_with_composition_on_input.html
@@ -33,23 +33,23 @@ function runTests()
   var target = document.getElementById("input");
 
   // Register a word to the form history.
   target.focus();
   target.value = "Mozilla";
   synthesizeKey("VK_RETURN", {});
   target.value = "";
 
-  var test1 = new nsDoTestsForAutoCompleteWithComposition(
+  new nsDoTestsForAutoCompleteWithComposition(
     "Testing on HTML input (asynchronously search)",
     window, target, formFillController.controller, is,
     function() { return target.value; },
     function() {
       target.setAttribute("timeout", 0);
-      var test2 = new nsDoTestsForAutoCompleteWithComposition(
+      new nsDoTestsForAutoCompleteWithComposition(
         "Testing on HTML input (synchronously search)",
         window, target, formFillController.controller, is,
         function() { return target.value; },
         function() {
           formFillController.timeout = originalFormFillTimeout;
           SpecialPowers.detachFormFillControllerFrom(window);
           SimpleTest.finish();
         });
--- a/toolkit/content/tests/chrome/xul_selectcontrol.js
+++ b/toolkit/content/tests/chrome/xul_selectcontrol.js
@@ -314,17 +314,17 @@ function test_nsIDOMXULSelectControlElem
   expectedValue = keyWrap ? "first" : "second";
   synthesizeKeyExpectEvent(forwardKey, {}, keyWrap ? element : null, "select", testid + "key down 2");
   test_nsIDOMXULSelectControlElement_States(element, testid + "key down 2", 2,
     expectedItem, expectedIndex, expectedValue);
 
   var thirditem = element.appendItem("Third Item", "third");
   var fourthitem = element.appendItem("Fourth Item", "fourth");
   if (behaviourContains(element.localName, "select-extended-keynav")) {
-    var fifthitem = element.appendItem("Fifth Item", "fifth");
+    element.appendItem("Fifth Item", "fifth");
     var sixthitem = element.appendItem("Sixth Item", "sixth");
 
     synthesizeKeyExpectEvent("VK_END", {}, element, "select", testid + "key end");
     test_nsIDOMXULSelectControlElement_States(element, testid + "key end", 6, sixthitem, 5, "sixth");
 
     synthesizeKeyExpectEvent("VK_HOME", {}, element, "select", testid + "key home");
     test_nsIDOMXULSelectControlElement_States(element, testid + "key home", 6, firstitem, 0, "first");
 
--- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/BrowserView.js
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/BrowserView.js
@@ -170,27 +170,21 @@ function() {
 
   function getNewBatchOperationState() {
     return {
       viewportSizeChanged: false,
       dirtyAll: false
     };
   }
 
-  function clampViewportWH(width, height, visibleRect) {
-    let minW = visibleRect.width;
-    let minH = visibleRect.height;
-    return [Math.max(width, minW), Math.max(height, minH)];
-  }
-
-  function initContainer(container, visibleRect) {
-    container.style.width    = visibleRect.width  + 'px';
-    container.style.height   = visibleRect.height + 'px';
-    container.style.overflow = '-moz-hidden-unscrollable';
-  }
+  // function clampViewportWH(width, height, visibleRect) {
+  //   let minW = visibleRect.width;
+  //   let minH = visibleRect.height;
+  //   return [Math.max(width, minW), Math.max(height, minH)];
+  // }
 
   function resizeContainerToViewport(container, viewportRect) {
     container.style.width  = viewportRect.width  + 'px';
     container.style.height = viewportRect.height + 'px';
   }
 
   // !!! --- RESIZE HACK BEGIN -----
   function simulateMozAfterSizeChange(browser, width, height) {
@@ -252,17 +246,16 @@ function() {
 
     getVisibleRectX: function getVisibleRectX() { return this._visibleRect.x; },
     getVisibleRectY: function getVisibleRectY() { return this._visibleRect.y; },
     getVisibleRectWidth: function getVisibleRectWidth() { return this._visibleRect.width; },
     getVisibleRectHeight: function getVisibleRectHeight() { return this._visibleRect.height; },
 
     setViewportDimensions: function setViewportDimensions(width, height, causedByZoom) {
       let bvs = this._browserViewportState;
-      let vis = this._visibleRect;
 
       if (!bvs)
         return;
 
       // [width, height] = clampViewportWH(width, height, vis);
       bvs.viewportRect.right  = width;
       bvs.viewportRect.bottom = height;
 
@@ -325,19 +318,16 @@ function() {
 
     discardAllBatchOperations: function discardAllBatchOperations() {
       let bops = this._batchOps;
       while (bops.length > 0)
         this.discardBatchOperation();
     },
 
     moveVisibleBy: function moveVisibleBy(dx, dy) {
-      let vr = this._visibleRect;
-      let vs = this._browserViewportState;
-
       this.onBeforeVisibleMove(dx, dy);
       this.onAfterVisibleMove(dx, dy);
     },
 
     moveVisibleTo: function moveVisibleTo(x, y) {
       let visibleRect = this._visibleRect;
       let dx = x - visibleRect.x;
       let dy = y - visibleRect.y;
@@ -686,9 +676,8 @@ BrowserView.BrowserViewportState.prototy
                  '\tvisibleX='     + this.visibleX,
                  '\tvisibleY='     + this.visibleY,
                  '\tzoomLevel='    + this.zoomLevel];
 
     return '[BrowserViewportState] {\n' + props.join(',\n') + '\n}';
   }
 
 };
-
--- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/FooScript.js
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/FooScript.js
@@ -104,17 +104,16 @@ BrowserView.prototype = {
   },
 
   resizeTileContainer: function resizeTileContainer() {
 
   },
 
   scrollboxToViewportRect: function scrollboxToViewportRect(rect, clip) {
     let leftbar  = this._leftbar.getBoundingClientRect();
-    let rightbar = this._rightbar.getBoundingClientRect();
     let topbar   = this._topbar.getBoundingClientRect();
 
     let xtrans = -leftbar.width;
     let ytrans = -topbar.height;
     let x = rect.x + xtrans;
     let y = rect.y + ytrans;
 
     // XXX we're cheating --- this is not really a clip, but its the only
--- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/TileManager.js
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/TileManager.js
@@ -171,17 +171,16 @@ TileManager.prototype = {
     if (destCriticalRect) {
 
       let rect = destCriticalRect;
 
       let create = false;
 
       // this._tileCache.forEachIntersectingRect(destCriticalRect, false, appendNonDirtyTile, this);
       let visited = {};
-      let evictGuard = null;
       if (create) {
 	evictGuard = function evictGuard(tile) {
 	  return !visited[tile.toString()];
 	};
       }
 
       let starti = rect.left  >> kTileExponentWidth;
       let endi   = rect.right >> kTileExponentWidth;
@@ -823,18 +822,16 @@ TileManager.Tile.prototype = {
 
     let ctx = this._canvas.getContext("2d");
     ctx.save();
 
     browserView.browserToViewportCanvasContext(ctx);
 
     ctx.translate(x, y);
 
-    let cw = browserView._contentWindow;
-    // let cw = browser.contentWindow;
     ctx.asyncDrawXULElement(browserView._browser,
                    rect.left, rect.top,
                    rect.right - rect.left, rect.bottom - rect.top,
                    "grey",
                    (ctx.DRAWWINDOW_DO_NOT_FLUSH | ctx.DRAWWINDOW_DRAW_CARET));
 
     ctx.restore();
 
--- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/WidgetStack.js
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/WidgetStack.js
@@ -584,18 +584,16 @@ WidgetStack.prototype = {
       this._viewportBounds.setBounds(arguments[0],
       arguments[1],
       arguments[2],
       arguments[3]);
     } else {
       throw "Invalid number of arguments to setViewportBounds";
     }
 
-    let vp = this._viewport;
-
     let dleft = this._viewportBounds.left - oldBounds.left;
     let dright = this._viewportBounds.right - oldBounds.right;
     let dtop = this._viewportBounds.top - oldBounds.top;
     let dbottom = this._viewportBounds.bottom - oldBounds.bottom;
 
     // log2("setViewportBounds dltrb", dleft, dtop, dright, dbottom);
 
     // move all vp-relative widgets to be the right offset from the bounds again
@@ -622,25 +620,23 @@ WidgetStack.prototype = {
 
     for (let bid in this._barriers) {
       let barrier = this._barriers[bid];
 
       // log2("setViewportBounds: looking at barrier", bid, barrier.vpRelative, barrier.type);
 
       if (barrier.vpRelative) {
         if (barrier.type == "vertical") {
-          let q = "v barrier moving from " + barrier.x + " to ";
           if (barrier.vpOffsetXBefore) {
             barrier.x += dleft;
           } else {
             barrier.x += dright;
           }
           // log2(q += barrier.x);
         } else if (barrier.type == "horizontal") {
-          let q = "h barrier moving from " + barrier.y + " to ";
           if (barrier.vpOffsetYBefore) {
             barrier.y += dtop;
           } else {
             barrier.y += dbottom;
           }
           // log2(q += barrier.y);
         }
       }
@@ -1235,18 +1231,16 @@ WidgetStack.prototype = {
   // If the widget goes to the left or above the viewport widget, then
   // vpOffsetXBefore or vpOffsetYBefore is set.
   // See setViewportBounds for use of vpOffset* state variables, and for how
   // the actual x and y coords of each widget are calculated based on their offsets
   // and the viewport bounds.
   _updateWidgets: function() {
     let vp = this._viewport;
 
-    let ofRect = this._viewingRect.clone();
-
     for (let wid in this._widgetState) {
       let state = this._widgetState[wid];
       if (vp && state.vpRelative) {
         // compute the vpOffset from 0,0 assuming that the viewport rect is 0,0
         if (state.rect.left >= vp.rect.right) {
           state.vpOffsetXBefore = false;
           state.vpOffsetX = state.rect.left - vp.rect.width;
         } else {
@@ -1371,18 +1365,16 @@ WidgetStack.prototype = {
     // t != "tb" && t != "bt" &&
 
     if (t != "horizontal" &&
         t != "vertical")
     {
       throw "Invalid barrier type: " + t;
     }
 
-    let x, y;
-
     let barrier = {};
     let vp = this._viewport;
 
     barrier.type = t;
 
     if (el.getAttribute("left"))
       barrier.x = parseInt(el.getAttribute("left"));
     else if (el.getAttribute("top"))
--- a/toolkit/content/tests/mochitest/test_mousecapture.xhtml
+++ b/toolkit/content/tests/mochitest/test_mousecapture.xhtml
@@ -1,18 +1,18 @@
 <?xml version="1.0"?>
 <!DOCTYPE HTML>
 <html xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
       xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title>Mouse Capture Tests</title>
   <link rel="stylesheet" href="chrome://global/skin/" type="text/css"/>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> 
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <body id="body" xmlns="http://www.w3.org/1999/xhtml">
   <p id="display"/><div id="content" style="display: none"/><pre id="test"/>
 
 <script><![CDATA[
 
 SimpleTest.expectAssertions(6, 12);
 
@@ -167,19 +167,16 @@ function runTests()
   synthesizeMouse(image, 2, 2, { type: "mouseup" });
 
   window.scroll(0, 0);
 
   // save scroll
   var scrollX = parent ? parent.scrollX : 0;
   var scrollY = parent ? parent.scrollY : 0;
 
-  var b = frames[0].document.getElementById("b");
-//  runCaptureTest(b, selectionCallback);
-
   // restore scroll
   if (parent) parent.scroll(scrollX, scrollY);
 
 //  frames[0].getSelection().collapseToStart();
 
   var body = frames[0].document.body;
   var fixed = frames[0].document.getElementById("fixed");
   function captureOnBody() { body.setCapture() }
@@ -331,9 +328,8 @@ SimpleTest.waitForFocus(runTests);
   <img id="image" xmlns="http://www.w3.org/1999/xhtml"
        onmousedown="this.setCapture();" onmouseup="this.releaseCapture();"
        ondragstart="ok(false, 'should not get a drag when a setCapture is active');"
        src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC"/>
 
 </body>
 
 </html>
-
--- a/toolkit/content/tests/widgets/tree_shared.js
+++ b/toolkit/content/tests/widgets/tree_shared.js
@@ -620,17 +620,16 @@ function testtag_tree_TreeSelection_UI(t
 
 function testtag_tree_UI_editing(tree, testid, rowInfo)
 {
   testid += " editing UI ";
 
   // check editing UI
   var ecolumn = tree.columns[0];
   var rowIndex = 2;
-  var inputField = tree.inputField;
 
   // temporary make the tree editable to test mouse double click
   var wasEditable = tree.editable;
   if (!wasEditable)
     tree.editable = true;
 
   // if this is a container save its current open status
   var row = rowInfo.rows[rowIndex];
@@ -918,17 +917,16 @@ function testtag_tree_TreeView_rows(tree
     isEditable: function(row, cell) { return cell.editable },
     isSelectable: function(row, cell) { return cell.selectable },
     getImageSrc: function(row, cell) { return cell.image },
     getProgressMode: function(row, cell) { return cell.mode }
   };
 
   var failedMethods = { };
   var checkMethod, actual, expected;
-  var containerInfo = null;
   var toggleOpenStateOK = true;
 
   for (r = startRow; r < length; r++) {
     var row = rowInfo.rows[r];
     for (var c = 0; c < row.cells.length; c++) {
       var cell = row.cells[c];
 
       for (checkMethod in checkCellMethods) {
--- a/toolkit/content/treeUtils.js
+++ b/toolkit/content/treeUtils.js
@@ -53,26 +53,24 @@ var gTreeUtils = {
 
   sort: function(aTree, aView, aDataSet, aColumn, aComparator,
                  aLastSortColumn, aLastSortAscending)
   {
     var ascending = (aColumn == aLastSortColumn) ? !aLastSortAscending : true;
     if (aDataSet.length == 0)
       return ascending;
 
-    var numericSort = !isNaN(aDataSet[0][aColumn]);
     var sortFunction = null;
     if (aComparator) {
       sortFunction = function(a, b) { return aComparator(a[aColumn], b[aColumn]); };
     }
     aDataSet.sort(sortFunction);
     if (!ascending)
       aDataSet.reverse();
 
     aTree.view.selection.clearSelection();
     aTree.view.selection.select(0);
     aTree.treeBoxObject.invalidate();
     aTree.treeBoxObject.ensureRowIsVisible(0);
 
     return ascending;
   }
 };
-
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -939,17 +939,18 @@
                 }
               }
             }
           }
           catch (e) {
             Components.utils.reportError(e);
           }
           try {
-            var securityUI = this.securityUI;
+            // Ensures the securityUI is initialized.
+            var securityUI = this.securityUI; // eslint-disable-line no-unused-vars
           }
           catch (e) {
           }
 
           // XXX tabbrowser.xml sets "relatedBrowser" as a direct property on
           // some browsers before they are put into a DOM (and get a binding).
           // This hack makes sure that we hold a weak reference to the other
           // browser (and go through the proper getter and setter).
@@ -1564,17 +1565,16 @@
       </handler>
       <handler event="drop" group="system">
       <![CDATA[
         // No need to handle "drop" in e10s, since nsDocShellTreeOwner.cpp in the child process
         // handles that case using "@mozilla.org/content/dropped-link-handler;1" service.
         if (!this.droppedLinkHandler || event.defaultPrevented || this.isRemoteBrowser)
           return;
 
-        let name = { };
         let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
                             getService(Components.interfaces.nsIDroppedLinkHandler);
         try {
           // Pass true to prevent the dropping of javascript:/data: URIs
           var links = linkHandler.dropLinks(event, true);
         } catch (ex) {
           return;
         }
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -396,18 +396,16 @@
         <![CDATA[
           this.popupBoxObject.moveToAnchor(aAnchorElement, aPosition, aX, aY, aAttributesOverride);
         ]]>
         </body>
       </method>
       <method name="adjustArrowPosition">
         <body>
         <![CDATA[
-        var arrow = document.getAnonymousElementByAttribute(this, "anonid", "arrow");
-
         var anchor = this.anchorNode;
         if (!anchor) {
           return;
         }
 
         var container = document.getAnonymousElementByAttribute(this, "anonid", "container");
         var arrowbox = document.getAnonymousElementByAttribute(this, "anonid", "arrowbox");
 
--- a/toolkit/content/widgets/preferences.xml
+++ b/toolkit/content/widgets/preferences.xml
@@ -1063,18 +1063,16 @@
         if (!this._fireEvent("beforeaccept", this)) {
           return false;
         }
 
         var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
                     .getService(Components.interfaces.nsIScriptSecurityManager);
         if (this.type == "child" && window.opener &&
             secMan.isSystemPrincipal(window.opener.document.nodePrincipal)) {
-          let psvc = Components.classes["@mozilla.org/preferences-service;1"]
-                               .getService(Components.interfaces.nsIPrefBranch);
           var pdocEl = window.opener.document.documentElement;
           if (pdocEl.instantApply) {
             let panes = this.preferencePanes;
             for (let i = 0; i < panes.length; ++i)
               panes[i].writePreferences(true);
           }
           else {
             // Clone all the preferences elements from the child document and
--- a/toolkit/content/widgets/spinner.js
+++ b/toolkit/content/widgets/spinner.js
@@ -13,17 +13,16 @@
  */
 
 function Spinner(props, context) {
   this.context = context;
   this._init(props);
 }
 
 {
-  const debug = 0 ? console.log.bind(console, "[spinner]") : function() {};
 
   const ITEM_HEIGHT = 2.5,
         VIEWPORT_SIZE = 7,
         VIEWPORT_COUNT = 5,
         SCROLL_TIMEOUT = 100;
 
   Spinner.prototype = {
     /**
@@ -91,17 +90,16 @@ function Spinner(props, context) {
      *          {Number/String} value: The centered value
      *          {Array} items: The list of items for display
      *          {Boolean} isInfiniteScroll: Whether or not the spinner should
      *            have infinite scroll capability
      *          {Boolean} isValueSet: true if user has selected a value
      *        }
      */
     setState(newState) {
-      const { spinner } = this.elements;
       const { value, items } = this.state;
       const { value: newValue, items: newItems, isValueSet, isInvalid } = newState;
 
       if (this._isArrayDiff(newItems, items)) {
         this.state = Object.assign(this.state, newState);
         this._updateItems();
         this._scrollTo(newValue, true);
       } else if (newValue != value) {
@@ -124,17 +122,17 @@ function Spinner(props, context) {
      * - If a smooth scroll has reached its destination, set [isScrolling] state
      *   to false
      * - If the value has changed, update the [value] state and call [setValue]
      * - If infinite scrolling is on, reset the scrolling position if necessary
      */
     _onScroll() {
       const { items, itemsView, isInfiniteScroll } = this.state;
       const { viewportSize, viewportTopOffset } = this.props;
-      const { spinner, itemsViewElements } = this.elements;
+      const { spinner } = this.elements;
 
       this.state.index = this._getIndexByOffset(spinner.scrollTop);
 
       const value = itemsView[this.state.index + viewportTopOffset].value;
 
       // Check if smooth scrolling has reached its destination.
       // This prevents input box jump when input box changes values.
       if (this.state.value == value && this.state.isScrolling) {
--- a/toolkit/content/widgets/tabbox.xml
+++ b/toolkit/content/widgets/tabbox.xml
@@ -26,17 +26,17 @@
         ]]>
         </setter>
         <getter>
         <![CDATA[
           return (this.getAttribute("handleCtrlTab") != "false");
         ]]>
         </getter>
       </property>
-      
+
       <property name="handleCtrlPageUpDown">
         <setter>
         <![CDATA[
           this.setAttribute("handleCtrlPageUpDown", val);
           return val;
         ]]>
         </setter>
         <getter>
@@ -69,17 +69,17 @@
         <getter>
         <![CDATA[
           return this.getElementsByTagNameNS(
               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
               "tabpanels").item(0);
         ]]>
         </getter>
       </property>
-      
+
       <property name="selectedIndex">
         <getter>
         <![CDATA[
           var tabs = this.tabs;
           return tabs ? tabs.selectedIndex : -1;
         ]]>
         </getter>
 
@@ -239,17 +239,17 @@
       <stylesheet src="chrome://global/skin/tabbox.css"/>
     </resources>
 
     <content>
       <xul:spacer class="tabs-left"/>
       <children/>
       <xul:spacer class="tabs-right" flex="1"/>
     </content>
-    
+
     <implementation implements="nsIDOMXULSelectControlElement, nsIDOMXULRelatedElement">
       <constructor>
       <![CDATA[
         // first and last tabs need to be able to have unique styles
         // and also need to select first tab on startup.
         if (this.firstChild)
           this.firstChild.setAttribute("first-tab", "true");
         if (this.lastChild)
@@ -294,18 +294,16 @@
             return null;
 
           let tabpanelsElm = tabboxElm.tabpanels;
           if (!tabpanelsElm)
             return null;
 
           // Get linked tab panel by 'linkedpanel' attribute on the given tab
           // element.
-          let linkedPanelElm = null;
-
           let linkedPanelId = aTabElm.linkedPanel;
           if (linkedPanelId) {
             let ownerDoc = this.ownerDocument;
 
             // XXX bug 565858: if XUL tab element is anonymous element then
             // suppose linked tab panel is hosted within the same XBL binding
             // and search it by ID attribute inside an anonymous content of
             // the binding. This is not robust assumption since tab elements may
@@ -381,17 +379,17 @@
           const tabs = this.childNodes;
           for (var i = 0; i < tabs.length; i++) {
             if (tabs[i].selected)
               return i;
           }
           return -1;
         ]]>
         </getter>
-        
+
         <setter>
         <![CDATA[
           var tab = this.getItemAtIndex(val);
           if (tab) {
             var alreadySelected = tab.selected;
 
             Array.forEach(this.childNodes, function(aTab) {
               if (aTab.selected && aTab != tab)
@@ -546,17 +544,17 @@
           var tab = document.createElementNS(XULNS, "tab");
           tab.setAttribute("label", label);
           tab.setAttribute("value", value);
           this.appendChild(tab);
           return tab;
         ]]>
         </body>
       </method>
-      
+
       <method name="insertItemAt">
         <parameter name="index"/>
         <parameter name="label"/>
         <parameter name="value"/>
         <body>
         <![CDATA[
           var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
           var tab = document.createElementNS(XULNS, "tab");
@@ -884,9 +882,8 @@
         var tabs = this.parentNode.childNodes;
         this.parentNode._selectNewTab(tabs[tabs.length - 1], -1);
       ]]>
       </handler>
     </handlers>
   </binding>
 
 </bindings>
-
--- a/toolkit/content/widgets/timekeeper.js
+++ b/toolkit/content/widgets/timekeeper.js
@@ -19,18 +19,16 @@
  *        }
  */
 function TimeKeeper(props) {
   this.props = props;
   this.state = { time: new Date(0), ranges: {} };
 }
 
 {
-  const debug = 0 ? console.log.bind(console, '[timekeeper]') : function() {};
-
   const DAY_PERIOD_IN_HOURS = 12,
         SECOND_IN_MS = 1000,
         MINUTE_IN_MS = 60000,
         HOUR_IN_MS = 3600000,
         DAY_PERIOD_IN_MS = 43200000,
         DAY_IN_MS = 86400000,
         TIME_FORMAT_24 = "24";
 
--- a/toolkit/content/widgets/timepicker.js
+++ b/toolkit/content/widgets/timepicker.js
@@ -5,18 +5,16 @@
 "use strict";
 
 function TimePicker(context) {
   this.context = context;
   this._attachEventListeners();
 }
 
 {
-  const debug = 0 ? console.log.bind(console, "[timepicker]") : function() {};
-
   const DAY_PERIOD_IN_HOURS = 12,
         SECOND_IN_MS = 1000,
         MINUTE_IN_MS = 60000,
         DAY_IN_MS = 86400000;
 
   TimePicker.prototype = {
     /**
      * Initializes the time picker. Set the default states and properties.
@@ -73,17 +71,17 @@ function TimePicker(context) {
       let time = new Date("1970-01-01T" + timeString + "Z");
       return time.toString() == "Invalid Date" ? false : time;
     },
 
     /**
      * Initalize the spinner components.
      */
     _createComponents() {
-      const { locale, step, format } = this.props;
+      const { locale, format } = this.props;
       const { timeKeeper } = this.state;
 
       const wrapSetValueFn = (setTimeFunction) => {
         return (value) => {
           setTimeFunction(value);
           this._setComponentStates();
           this._dispatchState();
         };
--- a/toolkit/crashreporter/CrashSubmit.jsm
+++ b/toolkit/crashreporter/CrashSubmit.jsm
@@ -396,17 +396,17 @@ Submitter.prototype = {
         this.extraKeyVals[key] = extraKeyVals[key];
       }
     }
 
     let additionalDumps = [];
     if ("additional_minidumps" in this.extraKeyVals) {
       let names = this.extraKeyVals.additional_minidumps.split(',');
       for (let name of names) {
-        let [dump, extra, memory] = getPendingMinidump(this.id + "-" + name);
+        let [dump /* , extra, memory */] = getPendingMinidump(this.id + "-" + name);
         if (!dump.exists()) {
           this.notifyStatus(FAILED);
           this.cleanup();
           return this.deferredSubmit.promise;
         }
         additionalDumps.push({'name': name, 'dump': dump});
       }
     }
@@ -449,18 +449,16 @@ this.CrashSubmit = {
    *
    *  @return a Promise that is fulfilled with the server crash ID when the
    *          submission succeeds and rejected otherwise.
    */
   submit: function CrashSubmit_submit(id, params)
   {
     params = params || {};
     let recordSubmission = false;
-    let submitSuccess = null;
-    let submitError = null;
     let noThrottle = false;
     let extraExtraKeyVals = null;
 
     if ('recordSubmission' in params)
       recordSubmission = params.recordSubmission;
     if ('noThrottle' in params)
       noThrottle = params.noThrottle;
     if ('extraExtraKeyVals' in params)
@@ -491,17 +489,17 @@ this.CrashSubmit = {
    * Add a .dmg.ignore file along side the .dmp file to indicate that the user
    * shouldn't be prompted to submit this crash report again.
    *
    * @param id
    *        Filename (minus .dmp extension) of the report to ignore
    */
 
   ignore: function CrashSubmit_ignore(id) {
-    let [dump, extra, mem] = getPendingMinidump(id);
+    let [dump /* , extra, memory */] = getPendingMinidump(id);
     return OS.File.open(dump.path + ".ignore", {create: true},
                         {unixFlags: OS.Constants.libc.O_CREAT})
       .then((file) => { file.close(); });
   },
 
   /**
    * Get the list of pending crash IDs.
    *
--- a/toolkit/crashreporter/test/unit/test_crashreporter.js
+++ b/toolkit/crashreporter/test/unit/test_crashreporter.js
@@ -3,17 +3,17 @@ function run_test()
   dump("INFO | test_crashreporter.js | Get crashreporter service.\n");
   var cr = Components.classes["@mozilla.org/toolkit/crash-reporter;1"]
                      .getService(Components.interfaces.nsICrashReporter);
   do_check_neq(cr, null);
 
   do_check_true(cr.enabled);
 
   try {
-    let su = cr.serverURL;
+    cr.serverURL;
     do_throw("Getting serverURL when not set should have thrown!");
   }
   catch (ex) {
     do_check_eq(ex.result, Components.results.NS_ERROR_FAILURE);
   }
 
   // check setting/getting serverURL
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
--- a/toolkit/forgetaboutsite/ForgetAboutSite.jsm
+++ b/toolkit/forgetaboutsite/ForgetAboutSite.jsm
@@ -88,17 +88,16 @@ this.ForgetAboutSite = {
     // Plugin data
     const phInterface = Ci.nsIPluginHost;
     const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
     let ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface);
     let tags = ph.getPluginTags();
     let promises = [];
     for (let i = 0; i < tags.length; i++) {
       let promise = new Promise(resolve => {
-        let tag = tags[i];
         try {
           ph.clearSiteData(tags[i], aDomain, FLAG_CLEAR_ALL, -1, function(rv) {
             resolve();
           });
         } catch (e) {
           // Ignore errors from the plugin, but resolve the promise
           resolve();
         }
--- a/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
+++ b/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
@@ -484,17 +484,17 @@ function* test_push_cleared()
            getService(Ci.nsIPushService);
   } catch (e) {
     // No push service, skip test.
     return;
   }
 
   do_get_profile();
   setPrefs();
-  const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
+  const {PushService, PushServiceWebSocket} = serviceExports;
   const userAgentID = 'bd744428-f125-436a-b6d0-dd0c9845837f';
   const channelID = '0ef2ad4a-6c49-41ad-af6e-95d2425276bf';
 
   let db = PushServiceWebSocket.newPushDB();
 
   try {
     PushService.init({
       serverURI: "wss://push.example.org/",
--- a/toolkit/identity/IdentityProvider.jsm
+++ b/toolkit/identity/IdentityProvider.jsm
@@ -173,17 +173,16 @@ IdentityProviderService.prototype = {
 
     // Expect a flow for this caller already to be underway.
     let provFlow = this.getProvisionFlow(aCaller.id, aCaller.doError);
 
     // keep the caller object around
     provFlow.caller = aCaller;
 
     let identity = provFlow.identity;
-    let frame = provFlow.provisioningFrame;
 
     // Determine recommended length of cert.
     let duration = this.certDuration;
 
     // Make a record that we have begun provisioning.  This is required
     // for genKeyPair.
     provFlow.didBeginProvisioning = true;
 
--- a/toolkit/identity/LogUtils.jsm
+++ b/toolkit/identity/LogUtils.jsm
@@ -82,18 +82,16 @@ IdentityLogger.prototype = {
     Services.console.logStringMessage(output);
   },
 
   /**
    * reportError() - report an error through component utils as well as
    * our log function
    */
   reportError: function reportError(aPrefix, ...aArgs) {
-    let prefix = aPrefix + ' ERROR';
-
     // Report the error in the browser
     let output = this._generateLogMessage(aPrefix, aArgs);
     Cu.reportError(output);
     dump("ERROR: " + output + "\n");
     for (let frame = Components.stack.caller; frame; frame = frame.caller) {
       dump(frame + "\n");
     }
   }
--- a/toolkit/identity/tests/unit/test_firefox_accounts.js
+++ b/toolkit/identity/tests/unit/test_firefox_accounts.js
@@ -175,18 +175,16 @@ function test_logout() {
   withSomebodySignedIn().then(() => {
     FirefoxAccounts.RP.watch(mockedRP);
   });
 }
 
 function test_error() {
   do_test_pending();
 
-  let received = [];
-
   // Mock the fxAccountsManager so that getAssertion rejects its promise and
   // triggers our onerror handler.  (This is the method that's used internally
   // by FirefoxAccounts.RP.request().)
   let originalGetAssertion = FirefoxAccounts.fxAccountsManager.getAssertion;
   FirefoxAccounts.fxAccountsManager.getAssertion = function(audience) {
     return Promise.reject(new Error("barf!"));
   };
 
--- a/toolkit/identity/tests/unit/test_jwcrypto.js
+++ b/toolkit/identity/tests/unit/test_jwcrypto.js
@@ -210,17 +210,17 @@ function test_audience_encoding_bug97258
   jwcrypto.generateKeyPair(
     "DS160",
     function(err, kp) {
       do_check_null(err);
       jwcrypto.generateAssertion("fake-cert", kp, audience,
         function(err2, backedAssertion) {
           do_check_null(err2);
 
-          let [cert, assertion] = backedAssertion.split("~");
+          let [/* cert */, assertion] = backedAssertion.split("~");
           let components = extractComponents(assertion);
           do_check_eq(components.payload.aud, audience);
 
           do_test_finished();
           run_next_test();
         }
       );
     }
--- a/toolkit/identity/tests/unit/test_log_utils.js
+++ b/toolkit/identity/tests/unit/test_log_utils.js
@@ -23,17 +23,17 @@ function toggle_debug() {
       }
     },
 
     init: function() {
       Services.prefs.addObserver('toolkit.identity.debug', this, false);
     }
   };
 
-  var wrapper = new Wrapper();
+  new Wrapper();
   Services.prefs.setBoolPref('toolkit.identity.debug', true);
 }
 
 // test that things don't break
 
 function logAlias(...args) {
   Logger.log.apply(Logger, ["log alias"].concat(args));
 }
--- a/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties
@@ -55,16 +55,18 @@ remote_sdp_heading = Remote SDP
 rtp_stats_heading = RTP Stats
 
 # LOCALIZATION NOTE (ice_state, ice_stats_heading): "ICE" is an abbreviation
 # for Interactive Connectivity Establishment, which is an IETF protocol,
 # and should not normally be translated. "Stats" is an abbreviation for
 # Statistics.
 ice_state = ICE State
 ice_stats_heading = ICE Stats
+ice_restart_count_label = ICE restarts
+ice_rollback_count_label = ICE rollbacks
 
 # LOCALIZATION NOTE (av_sync_label): "A/V" stands for Audio/Video.
 # "sync" is an abbreviation for sychronization. This is used as
 # a data label.
 av_sync_label = A/V sync
 
 # LOCALIZATION NOTE (jitter_buffer_delay_label): A jitter buffer is an
 # element in the processing chain, see http://wikipedia.org/wiki/Jitter
--- a/toolkit/modules/DateTimePickerHelper.jsm
+++ b/toolkit/modules/DateTimePickerHelper.jsm
@@ -105,17 +105,16 @@ this.DateTimePickerHelper = {
       browser.messageManager.sendAsyncMessage(
         "FormDateTime:PickerValueChanged", { hour, minute });
     }
   },
 
   // Get picker from browser and show it anchored to the input box.
   showPicker: function(aBrowser, aData) {
     let rect = aData.rect;
-    let dir = aData.dir;
     let type = aData.type;
     let detail = aData.detail;
 
     this._anchor = aBrowser.ownerGlobal.gBrowser.popupAnchor;
     this._anchor.left = rect.left;
     this._anchor.top = rect.top;
     this._anchor.width = rect.width;
     this._anchor.height = rect.height;
--- a/toolkit/modules/Finder.jsm
+++ b/toolkit/modules/Finder.jsm
@@ -412,17 +412,16 @@ Finder.prototype = {
         this.searchString == "" || !aWord || !this.matchesCountLimit) {
       this._notifyMatchesCount({
         total: 0,
         current: 0
       });
       return;
     }
 
-    let window = this._getWindow();
     this._currentFoundRange = this._fastFind.getFoundRange();
 
     let params = {
       caseSensitive: this._fastFind.caseSensitive,
       entireWord: this._fastFind.entireWord,
       linksOnly: aLinksOnly,
       word: aWord
     };
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -1490,18 +1490,16 @@ FinderHighlighter.prototype = {
   },
 
   WillDeleteSelection(selection) {
     let editor = this._getEditableNode(selection.getRangeAt(0)
                                                  .startContainer).editor;
     let controller = editor.selectionController;
     let fSelection = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);
 
-    let selectionIndex = 0;
-    let findSelectionIndex = 0;
     let shouldDelete = {};
     let numberOfDeletedSelections = 0;
     let numberOfMatches = fSelection.rangeCount;
 
     // We need to test if any ranges in the deleted selection (selection)
     // are in any of the ranges of the find selection
     // Usually both selections will only contain one range, however
     // either may contain more than one.
--- a/toolkit/modules/FinderIterator.jsm
+++ b/toolkit/modules/FinderIterator.jsm
@@ -448,17 +448,17 @@ this.FinderIterator = {
       // During the timeout, we could have gotten the signal to stop iterating.
       // Make sure we do here.
       if (!this.running || spawnId !== this._spawnId)
         return;
     }
 
     this._notifyListeners("start", this.params);
 
-    let { linksOnly, window, word } = this._currentParams;
+    let { linksOnly, window } = this._currentParams;
     // First we collect all frames we need to search through, whilst making sure
     // that the parent window gets dibs.
     let frames = [window].concat(this._collectFrames(window, finder));
     let iterCount = 0;
     for (let frame of frames) {
       for (let range of this._iterateDocument(this._currentParams, frame)) {
         // Between iterations, for example after a sleep of one cycle, we could
         // have gotten the signal to stop iterating. Make sure we do here.
--- a/toolkit/modules/InlineSpellChecker.jsm
+++ b/toolkit/modules/InlineSpellChecker.jsm
@@ -214,17 +214,16 @@ InlineSpellChecker.prototype = {
       list = this.mRemote.dictionaryList;
       curlang = this.mRemote.currentDictionary;
     }
     else if (this.mInlineSpellChecker) {
       var spellchecker = this.mInlineSpellChecker.spellChecker;
       var o1 = {}, o2 = {};
       spellchecker.GetDictionaryList(o1, o2);
       list = o1.value;
-      var listcount = o2.value;
       try {
         curlang = spellchecker.GetCurrentDictionary();
       } catch (e) {}
     }
 
     var sortedList = this.sortDictionaryList(list);
 
     for (var i = 0; i < sortedList.length; i++) {
@@ -258,17 +257,17 @@ InlineSpellChecker.prototype = {
     return list.length;
   },
 
   // Formats a valid BCP 47 language tag based on available localized names.
   getDictionaryDisplayName: function(dictionaryName) {
     try {
       // Get the display name for this dictionary.
       let languageTagMatch = /^([a-z]{2,3}|[a-z]{4}|[a-z]{5,8})(?:[-_]([a-z]{4}))?(?:[-_]([A-Z]{2}|[0-9]{3}))?((?:[-_](?:[a-z0-9]{5,8}|[0-9][a-z0-9]{3}))*)(?:[-_][a-wy-z0-9](?:[-_][a-z0-9]{2,8})+)*(?:[-_]x(?:[-_][a-z0-9]{1,8})+)?$/i;
-      var [languageTag, languageSubtag, scriptSubtag, regionSubtag, variantSubtags] = dictionaryName.match(languageTagMatch);
+      var [/* languageTag */, languageSubtag, scriptSubtag, regionSubtag, variantSubtags] = dictionaryName.match(languageTagMatch);
     } catch (e) {
       // If we weren't given a valid language tag, just use the raw dictionary name.
       return dictionaryName;
     }
 
     if (!gLanguageBundle) {
       // Create the bundles for language and region names.
       var bundleService = Components.classes["@mozilla.org/intl/stringbundle;1"]
--- a/toolkit/modules/NewTabUtils.jsm
+++ b/toolkit/modules/NewTabUtils.jsm
@@ -904,17 +904,17 @@ var Links = {
           } catch (e) {
             // We want to proceed even if a callback fails.
           }
         }
       }
     }
 
     let numProvidersRemaining = this._providers.size;
-    for (let [provider, links] of this._providers) {
+    for (let [provider /* , links */] of this._providers) {
       this._populateProviderCache(provider, () => {
         if (--numProvidersRemaining == 0)
           executeCallbacks();
       }, aForce);
     }
 
     this._addObserver();
   },
@@ -1017,17 +1017,17 @@ var Links = {
     * to increment or decrement it. We do this by iterating over all stored providers
     * to find which provider this link already exists in. For providers that
     * have this link, we will adjust siteMap for them accordingly.
     *
     * @param aLink The link that will affect siteMap
     * @param increment A boolean for whether to increment or decrement siteMap
     */
   _adjustSiteMapAndNotify: function(aLink, increment = true) {
-    for (let [provider, cache] of this._providers) {
+    for (let [/* provider */, cache] of this._providers) {
       // We only update siteMap if aLink is already stored in linkMap.
       if (cache.linkMap.get(aLink.url)) {
         if (increment) {
           this._incrementSiteMap(cache.siteMap, aLink);
           continue;
         }
         this._decrementSiteMap(cache.siteMap, aLink);
       }
--- a/toolkit/modules/PageMenu.jsm
+++ b/toolkit/modules/PageMenu.jsm
@@ -16,17 +16,16 @@ PageMenu.prototype = {
   _popup: null,
 
   // Only one of builder or browser will end up getting set.
   _builder: null,
   _browser: null,
 
   // Given a target node, get the context menu for it or its ancestor.
   getContextMenu: function(aTarget) {
-    let pageMenu = null;
     let target = aTarget;
     while (target) {
       let contextMenu = target.contextMenu;
       if (contextMenu) {
         return contextMenu;
       }
       target = target.parentNode;
     }
--- a/toolkit/modules/RemotePageManager.jsm
+++ b/toolkit/modules/RemotePageManager.jsm
@@ -509,17 +509,17 @@ var observer = (window) => {
 
   // Get the frame message manager for this window so we can associate this
   // page with a browser element
   let messageManager = window.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDocShell)
                              .QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIContentFrameMessageManager);
   // Set up the child side of the message port
-  let port = new ChildMessagePort(messageManager, window);
+  new ChildMessagePort(messageManager, window);
 };
 Services.obs.addObserver(observer, "chrome-document-global-created", false);
 Services.obs.addObserver(observer, "content-document-global-created", false);
 
 // A message from chrome telling us what pages to listen for
 Services.cpmm.addMessageListener("RemotePage:Register", ({ data }) => {
   for (let url of data.urls)
     registeredURLs.add(url);
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -202,18 +202,16 @@ this.SelectContentHelper.prototype = {
 
 function getComputedStyles(element) {
   return element.ownerDocument.defaultView.getComputedStyle(element);
 }
 
 function buildOptionListForChildren(node) {
   let result = [];
 
-  let win = node.ownerDocument.defaultView;
-
   for (let child of node.children) {
     let tagName = child.tagName.toUpperCase();
 
     if (tagName == 'OPTION' || tagName == 'OPTGROUP') {
       if (child.hidden) {
         continue;
       }
 
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -139,18 +139,16 @@ this.SelectParentHelper = {
       case "keydown":
         if (event.keyCode == event.DOM_VK_RETURN) {
           closedWithEnter = true;
         }
         break;
 
       case "command":
         if (event.target.hasAttribute("value")) {
-          let win = currentBrowser.ownerDocument.defaultView;
-
           currentBrowser.messageManager.sendAsyncMessage("Forms:SelectDropDownItem", {
             value: event.target.value,
             closedWithEnter: closedWithEnter
           });
         }
         break;
 
       case "fullscreen":
--- a/toolkit/modules/SpatialNavigation.jsm
+++ b/toolkit/modules/SpatialNavigation.jsm
@@ -244,17 +244,16 @@ function _getRootBounds(windowUtils) {
   return cssPageRectCopy;
 }
 
 // Returns the best node to focus from the list of nodes returned by the hit
 // test.
 function _getBestToFocus(nodes, key, currentlyFocused) {
   let best = null;
   let bestDist;
-  let bestMid;
   let nodeMid;
   let currentlyFocusedMid = _getMidpoint(currentlyFocused);
   let currentlyFocusedRect = currentlyFocused.getBoundingClientRect();
 
   for (let i = 0; i < nodes.length; i++) {
     // Reject the currentlyFocused, and all node types we can't focus
     if (!_canFocus(nodes[i]) || nodes[i] === currentlyFocused) {
       continue;
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -422,31 +422,31 @@ ConnectionData.prototype = Object.freeze
     return cloneStorageConnection(options);
   },
   _getOperationId: function() {
     return this._operationsCounter++;
   },
   _finalize: function() {
     this._log.debug("Finalizing connection.");
     // Cancel any pending statements.
-    for (let [k, statement] of this._pendingStatements) {
+    for (let [/* k */, statement] of this._pendingStatements) {
       statement.cancel();
     }
     this._pendingStatements.clear();
 
     // We no longer need to track these.
     this._statementCounter = 0;
 
     // Next we finalize all active statements.
-    for (let [k, statement] of this._anonymousStatements) {
+    for (let [/* k */, statement] of this._anonymousStatements) {
       statement.finalize();
     }
     this._anonymousStatements.clear();
 
-    for (let [k, statement] of this._cachedStatements) {
+    for (let [/* k */, statement] of this._cachedStatements) {
       statement.finalize();
     }
     this._cachedStatements.clear();
 
     // This guards against operations performed between the call to this
     // function and asyncClose() finishing. See also bug 726990.
     this._open = false;
 
@@ -656,17 +656,17 @@ ConnectionData.prototype = Object.freeze
   shrinkMemory: function() {
     this._log.info("Shrinking memory usage.");
     let onShrunk = this._clearIdleShrinkTimer.bind(this);
     return this.execute("PRAGMA shrink_memory").then(onShrunk, onShrunk);
   },
 
   discardCachedStatements: function() {
     let count = 0;
-    for (let [k, statement] of this._cachedStatements) {
+    for (let [/* k */, statement] of this._cachedStatements) {
       ++count;
       statement.finalize();
     }
     this._cachedStatements.clear();
     this._log.debug("Discarded " + count + " cached statements.");
     return count;
   },
 
@@ -1165,17 +1165,16 @@ OpenedConnection.prototype = Object.free
   /**
    * The integer schema version of the database.
    *
    * This is 0 if not schema version has been set.
    *
    * @return Promise<int>
    */
   getSchemaVersion: function() {
-    let self = this;
     return this.execute("PRAGMA user_version").then(
       function onSuccess(result) {
         if (result == null) {
           return 0;
         }
         return JSON.stringify(result[0].getInt32(0));
       }
     );
--- a/toolkit/modules/Task.jsm
+++ b/toolkit/modules/Task.jsm
@@ -418,17 +418,16 @@ TaskImpl.prototype = {
 
       if (gMaintainStack &&
           aException._capturedTaskStack != this._stack &&
           typeof stack == "string") {
 
         // Rewrite the stack for more readability.
 
         let bottomStack = this._stack;
-        let topStack = stack;
 
         stack = Task.Debugging.generateReadableStack(stack);
 
         aException.stack = stack;
 
         // If aException is reinjected in the same task and rethrown,
         // we don't want to perform the rewrite again.
         aException._capturedTaskStack = bottomStack;
--- a/toolkit/modules/UpdateUtils.jsm
+++ b/toolkit/modules/UpdateUtils.jsm
@@ -319,33 +319,16 @@ XPCOMUtils.defineLazyGetter(UpdateUtils,
           {szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
           {wServicePackMajor: WORD},
           {wServicePackMinor: WORD},
           {wSuiteMask: WORD},
           {wProductType: BYTE},
           {wReserved: BYTE}
           ]);
 
-      // This structure is described at:
-      // http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
-      const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
-          [
-          {wProcessorArchitecture: WORD},
-          {wReserved: WORD},
-          {dwPageSize: DWORD},
-          {lpMinimumApplicationAddress: ctypes.voidptr_t},
-          {lpMaximumApplicationAddress: ctypes.voidptr_t},
-          {dwActiveProcessorMask: DWORD.ptr},
-          {dwNumberOfProcessors: DWORD},
-          {dwProcessorType: DWORD},
-          {dwAllocationGranularity: DWORD},
-          {wProcessorLevel: WORD},
-          {wProcessorRevision: WORD}
-          ]);
-
       let kernel32 = false;
       try {
         kernel32 = ctypes.open("Kernel32");
       } catch (e) {
         Cu.reportError("Unable to open kernel32! " + e);
         osVersion += ".unknown (unknown)";
       }
 
--- a/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm
+++ b/toolkit/modules/secondscreen/SimpleServiceDiscovery.jsm
@@ -164,17 +164,17 @@ var SimpleServiceDiscovery = {
     this._searchTimeout.initWithCallback(this._searchShutdown.bind(this), SSDP_DISCOVER_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
 
     let data = SSDP_DISCOVER_PACKET;
 
     // Send discovery packets out at 1 per SSDP_TRANSMISSION_INTERVAL and send each SSDP_DISCOVER_ATTEMPTS times
     // to allow for packet loss on noisy networks.
     let timeout = SSDP_DISCOVER_DELAY;
     for (let attempts = 0; attempts < SSDP_DISCOVER_ATTEMPTS; attempts++) {
-      for (let [key, device] of this._devices) {
+      for (let [/* key */, device] of this._devices) {
         let target = device.target;
         setTimeout(function() {
           let msgData = data.replace("%SEARCH_TARGET%", target);
           try {
             let msgRaw = converter.convertToByteArray(msgData);
             socket.send(SSDP_ADDRESS, SSDP_PORT, msgRaw, msgRaw.length);
           } catch (e) {
             log("failed to convert to byte array: " + e);
@@ -219,17 +219,17 @@ var SimpleServiceDiscovery = {
   // Called when the search timeout is hit. We use it to cleanup the socket and
   // perform some post-processing on the services list.
   _searchShutdown: function _searchShutdown() {
     if (this._searchSocket) {
       // This will call onStopListening.
       this._searchSocket.close();
 
       // Clean out any stale services
-      for (let [key, service] of this._services) {
+      for (let [/* key */, service] of this._services) {
         if (service.lastPing != this._searchTimestamp) {
           this.removeService(service.uuid);
         }
       }
     }
 
     this._stopExternalDiscovery();
   },
@@ -300,29 +300,29 @@ var SimpleServiceDiscovery = {
       return this._services.get(aUUID);
     }
     return null;
   },
 
   // Returns an array copy of the active services
   get services() {
     let array = [];
-    for (let [key, service] of this._services) {
+    for (let [/* key */, service] of this._services) {
       let target = this._devices.get(service.deviceID);
       service.extensions = target.extensions;
       service.types = target.types;
       array.push(service);
     }
     return array;
   },
 
   // Returns false if the service does not match the device's filters
   _filterService: function _filterService(aService) {
     // Loop over all the devices, looking for one that matches the service
-    for (let [key, device] of this._devices) {
+    for (let [/* key */, device] of this._devices) {
       // First level of match is on the target itself
       if (device.target != aService.target) {
         continue;
       }
 
       // If we have no filter, everything passes
       if (!("filters" in device)) {
         aService.deviceID = device.id;
--- a/toolkit/modules/tests/browser/browser_RemotePageManager.js
+++ b/toolkit/modules/tests/browser/browser_RemotePageManager.js
@@ -95,17 +95,17 @@ add_task(function* init_navigate() {
   }
 
   yield loaded;
 
   gBrowser.goBack();
   port = yield waitForPort(TEST_URL, false);
 
   port.sendAsyncMessage("Ping2");
-  let message = yield waitForMessage(port, "Pong2");
+  yield waitForMessage(port, "Pong2");
   port.destroy();
 
   gBrowser.removeCurrentTab();
 });
 
 // Test that opening a page creates a port, sends the load event and then
 // closing the tab sends the unload event
 add_task(function* init_close() {
--- a/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js
+++ b/toolkit/modules/tests/xpcshell/test_CanonicalJSON.js
@@ -64,17 +64,16 @@ add_task(function* test_canonicalJSON_do
 });
 
 
 add_task(function* test_canonicalJSON_preserves_data() {
   const records = [
     {'foo': 'bar', 'last_modified': '12345', 'id': '1'},
     {'bar': 'baz', 'last_modified': '45678', 'id': '2'},
   ]
-  const serialized = CanonicalJSON.stringify(records);
   const expected = '[{"foo":"bar","id":"1","last_modified":"12345"},' +
                    '{"bar":"baz","id":"2","last_modified":"45678"}]';
   do_check_eq(CanonicalJSON.stringify(records), expected);
 });
 
 add_task(function* test_canonicalJSON_does_not_add_space_separators() {
   const records = [
     {'foo': 'bar', 'last_modified': '12345', 'id': '1'},
--- a/toolkit/modules/tests/xpcshell/test_FileUtils.js
+++ b/toolkit/modules/tests/xpcshell/test_FileUtils.js
@@ -28,17 +28,17 @@ add_test(function test_getFile() {
   other.append("foobar");
   do_check_true(file.equals(other));
 
   run_next_test();
 });
 
 add_test(function test_getFile_nonexistentDir() {
   do_check_throws(function() {
-    let file = FileUtils.getFile("NonexistentD", ["foobar"]);
+    FileUtils.getFile("NonexistentD", ["foobar"]);
   }, Components.results.NS_ERROR_FAILURE);
 
   run_next_test();
 });
 
 add_test(function test_getFile_createDirs() {
   let file = FileUtils.getFile("ProfD", ["a", "b", "foobar"]);
   do_check_true(file instanceof Components.interfaces.nsIFile);
@@ -64,17 +64,17 @@ add_test(function test_getDir() {
   other.append("foodir");
   do_check_true(dir.equals(other));
 
   run_next_test();
 });
 
 add_test(function test_getDir_nonexistentDir() {
   do_check_throws(function() {
-    let file = FileUtils.getDir("NonexistentD", ["foodir"]);
+    FileUtils.getDir("NonexistentD", ["foodir"]);
   }, Components.results.NS_ERROR_FAILURE);
 
   run_next_test();
 });
 
 add_test(function test_getDir_shouldCreate() {
   let dir = FileUtils.getDir("ProfD", ["c", "d", "foodir"], true);
   do_check_true(dir instanceof Components.interfaces.nsIFile);
--- a/toolkit/modules/tests/xpcshell/test_GMPInstallManager.js
+++ b/toolkit/modules/tests/xpcshell/test_GMPInstallManager.js
@@ -544,23 +544,19 @@ add_task(function* test_simpleCheckAndIn
   let result = yield installManager.simpleCheckAndInstall();
   do_check_eq(result.status, "too-frequent-no-check");
 });
 
 /**
  * Tests that installing addons when there is no server works as expected
  */
 add_test(function test_installAddon_noServer() {
-  let dir = FileUtils.getDir("TmpD", [], true);
   let zipFileName = "test_GMP.zip";
   let zipURL = URL_HOST + ":0/" + zipFileName;
 
-  let data = "e~=0.5772156649";
-  let zipFile = createNewZipFile(zipFileName, data);
-
   let responseXML =
     "<?xml version=\"1.0\"?>" +
     "<updates>" +
     "    <addons>" +
     "        <addon id=\"gmp-gmpopenh264\"" +
     "               URL=\"" + zipURL + "\"" +
     "               hashFunction=\"sha256\"" +
     "               hashValue=\"11221cbda000347b054028b527a60e578f919cb10f322ef8077d3491c6fcb474\"" +
--- a/toolkit/modules/tests/xpcshell/test_Log.js
+++ b/toolkit/modules/tests/xpcshell/test_Log.js
@@ -52,17 +52,17 @@ add_task(function test_Logger() {
 });
 
 add_task(function test_Logger_parent() {
   // Check whether parenting is correct
   let grandparentLog = Log.repository.getLogger("grandparent");
   let childLog = Log.repository.getLogger("grandparent.parent.child");
   do_check_eq(childLog.parent.name, "grandparent");
 
-  let parentLog = Log.repository.getLogger("grandparent.parent");
+  Log.repository.getLogger("grandparent.parent");
   do_check_eq(childLog.parent.name, "grandparent.parent");
 
   // Check that appends are exactly in scope
   let gpAppender = new MockAppender(new Log.BasicFormatter());
   gpAppender.level = Log.Level.Info;
   grandparentLog.addAppender(gpAppender);
   childLog.info("child info test");
   Log.repository.rootLogger.info("this shouldn't show up in gpAppender");
--- a/toolkit/modules/tests/xpcshell/test_Promise.js
+++ b/toolkit/modules/tests/xpcshell/test_Promise.js
@@ -282,17 +282,17 @@ tests.push(
     let exception_content = new Error("Boom!");
 
     let observer_1 = source.promise.then(
       function onResolve() {
         exception_thrown = true;
         throw exception_content;
       });
 
-    let observer_2 = source.promise.then(
+    source.promise.then(
       function onResolve() {
         do_check_true(exception_thrown, "Second observer called after first observer has thrown");
       }
     );
 
     let result = observer_1.then(
       function onResolve() {
         do_throw("observer_1 should not have resolved");
@@ -955,17 +955,16 @@ tests.push(
 
 function wait_for_uncaught(aMustAppear, aTimeout = undefined) {
   let remaining = new Set();
   for (let k of aMustAppear) {
     remaining.add(k);
   }
   let deferred = Promise.defer();
   let print = do_print;
-  let execute_soon = do_execute_soon;
   let observer = function({message, stack}) {
     let data = message + stack;
     print("Observing " + message + ", looking for " + aMustAppear.join(", "));
     for (let expected of remaining) {
       if (data.indexOf(expected) != -1) {
         print("I found " + expected);
         remaining.delete(expected);
       }
--- a/toolkit/modules/tests/xpcshell/test_session_recorder.js
+++ b/toolkit/modules/tests/xpcshell/test_session_recorder.js
@@ -26,17 +26,17 @@ function monkeypatchStartupInfo(recorder
       };
     }
   });
 }
 
 function sleep(wait) {
   let deferred = Promise.defer();
 
-  let timer = CommonUtils.namedTimer(function onTimer() {
+  CommonUtils.namedTimer(function onTimer() {
     deferred.resolve();
   }, wait, deferred.promise, "_sleepTimer");
 
   return deferred.promise;
 }
 
 function getRecorder(name, start, offset) {
   let recorder = new SessionRecorder("testing." + name + ".");
@@ -298,9 +298,8 @@ add_task(function* test_record_activity(
   Services.obs.notifyObservers(null, "user-interaction-active", null);
   do_check_eq(recorder.activeTicks, 4);
 
   Services.obs.notifyObservers(null, "user-interaction-active", null);
   do_check_eq(recorder.activeTicks, 5);
 
   recorder.onShutdown();
 });
-
--- a/toolkit/modules/tests/xpcshell/test_sqlite.js
+++ b/toolkit/modules/tests/xpcshell/test_sqlite.js
@@ -489,17 +489,16 @@ add_task(function* test_shrink_memory() 
   yield c.shrinkMemory();
   yield c.close();
 });
 
 add_task(function* test_no_shrink_on_init() {
   let c = yield getConnection("no_shrink_on_init",
                               {shrinkMemoryOnConnectionIdleMS: 200});
 
-  let oldShrink = c._connectionData.shrinkMemory;
   let count = 0;
   Object.defineProperty(c._connectionData, "shrinkMemory", {
     value: function() {
       count++;
     },
   });
 
   // We should not shrink until a statement has been executed.
@@ -754,21 +753,21 @@ add_task(function* test_programmatic_bin
 
   // Add some data in an implicit transaction before beginning the batch insert.
   yield c.execute(sql, {id: 1, path: "works"});
 
   let secondSucceeded = false;
   try {
     yield c.executeTransaction(function* transaction() {
       // Insert one row. This won't implicitly start a transaction.
-      let result = yield c.execute(sql, bindings[0]);
+      yield c.execute(sql, bindings[0]);
 
       // Insert multiple rows. mozStorage will want to start a transaction.
       // One of the inserts will fail, so the transaction should be rolled back.
-      result = yield c.execute(sql, bindings);
+      yield c.execute(sql, bindings);
       secondSucceeded = true;
     });
   } catch (ex) {
     print("Caught expected exception: " + ex);
   }
 
   // We did not get to the end of our in-transaction block.
   do_check_false(secondSucceeded);
@@ -790,17 +789,17 @@ add_task(function* test_programmatic_bin
     {id: 2, path: "foobar"},
     {id: 1, path: "toofoo"},
   ];
 
   let sql = "INSERT INTO dirs VALUES (:id, :path)";
   let secondSucceeded = false;
   yield c.execute(sql, {id: 1, path: "works"});
   try {
-    let result = yield c.execute(sql, bindings);
+    yield c.execute(sql, bindings);
     secondSucceeded = true;
   } catch (ex) {
     print("Caught expected exception: " + ex);
   }
 
   do_check_false(secondSucceeded);
 
   // The entire batch failed.
@@ -913,17 +912,17 @@ add_task(function* test_cloneStorageConn
   yield c.asyncClose();
   yield clone2.close();
   yield clone.close();
 });
 
 // Test Sqlite.cloneStorageConnection invalid argument.
 add_task(function* test_cloneStorageConnection() {
   try {
-    let clone = yield Sqlite.cloneStorageConnection({ connection: null });
+    yield Sqlite.cloneStorageConnection({ connection: null });
     do_throw(new Error("Should throw on invalid connection"));
   } catch (ex) {
     if (ex.name != "TypeError") {
       throw ex;
     }
   }
 });
 
--- a/toolkit/modules/tests/xpcshell/test_timer.js
+++ b/toolkit/modules/tests/xpcshell/test_timer.js
@@ -39,17 +39,17 @@ add_task(function* test_setInterval() {
   do_check_true(interval1 > 0, "setTimeout returns a positive number");
 
   imported.clearInterval(interval1);
 
   const EXPECTED_CALLS = 5;
   let calls = 0;
 
   yield new Promise((resolve) => {
-    let interval2 = imported.setInterval((param1, param2) => {
+    imported.setInterval((param1, param2) => {
       do_check_true(true, "Should be called");
       do_check_eq(param1, 15, "first parameter is correct");
       do_check_eq(param2, "hola", "second parameter is correct");
       if (calls >= EXPECTED_CALLS) {
         resolve();
       }
       calls++;
     }, 100, 15, "hola");
--- a/toolkit/mozapps/extensions/test/xpcshell/test_syncGUID.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_syncGUID.js
@@ -147,9 +147,8 @@ add_test(function test_addon_manager_get
       AddonManager.getAddonBySyncGUID("DOES_NOT_EXIST", function(missing) {
         do_check_eq(undefined, missing);
 
         run_next_test();
       });
     });
   });
 });
-
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
@@ -159,9 +159,8 @@ add_task(function*() {
   equal(addon.icon64URL, null);
 
   equal(AddonManager.getPreferredIconURL(addon, 128), null);
 
   addon.uninstall();
 
   yield promiseRestartManager();
 });
-
--- a/toolkit/mozapps/installer/package-name.mk
+++ b/toolkit/mozapps/installer/package-name.mk
@@ -29,23 +29,19 @@ MOZ_PKG_PLATFORM := win64
 else
 MOZ_PKG_PLATFORM := win32
 endif
 endif
 ifeq ($(OS_ARCH),Darwin)
 ifdef UNIVERSAL_BINARY
 MOZ_PKG_PLATFORM := mac
 else
-ifeq ($(TARGET_CPU),x86_64)
-MOZ_PKG_PLATFORM := mac64
-else
 MOZ_PKG_PLATFORM := mac
 endif
 endif
-endif
 ifeq ($(TARGET_OS),linux-gnu)
 MOZ_PKG_PLATFORM := linux-$(TARGET_CPU)
 endif
 endif #MOZ_PKG_PLATFORM
 
 ifdef MOZ_PKG_SPECIAL
 MOZ_PKG_PLATFORM := $(MOZ_PKG_PLATFORM)-$(MOZ_PKG_SPECIAL)
 endif
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -435,17 +435,17 @@ function getCanApplyUpdates() {
          * requires admin privileges to update other than Program Files.
          */
         let userCanElevate = false;
 
         if (parseFloat(windowsVersion) >= 6) {
           try {
             // KEY_UPDROOT will fail and throw an exception if
             // appDir is not under the Program Files, so we rely on that
-            let dir = Services.dirsvc.get(KEY_UPDROOT, Ci.nsIFile);
+            Services.dirsvc.get(KEY_UPDROOT, Ci.nsIFile);
             // appDir is under Program Files, so check if the user can elevate
             userCanElevate = Services.appinfo.QueryInterface(Ci.nsIWinAppHelper).
                              userCanElevate;
             LOG("getCanApplyUpdates - on Vista, userCanElevate: " + userCanElevate);
           }
           catch (ex) {
             // When the installation directory is not under Program Files,
             // fall through to checking if write access to the
--- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
+++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -1321,17 +1321,17 @@ function getSpecialFolderDir(aCSIDL) {
                                            ctypes.winapi_abi,
                                            ctypes.bool, /* bool(return) */
                                            ctypes.int32_t, /* HWND hwndOwner */
                                            ctypes.char16_t.ptr, /* LPTSTR lpszPath */
                                            ctypes.int32_t, /* int csidl */
                                            ctypes.bool /* BOOL fCreate */);
 
   let aryPath = ctypes.char16_t.array()(260);
-  let rv = SHGetSpecialFolderPath(0, aryPath, aCSIDL, false);
+  SHGetSpecialFolderPath(0, aryPath, aCSIDL, false);
   lib.close();
 
   let path = aryPath.readString(); // Convert the c-string to js-string
   if (!path) {
     return null;
   }
   debugDump("SHGetSpecialFolderPath returned path: " + path);
   let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
@@ -4070,18 +4070,16 @@ function runUpdateUsingApp(aExpectedStat
       return;
     }
 
     do_execute_soon(runUpdateFinished);
   }
 
   debugDump("start - launching application to apply update");
 
-  let appBin = getApplyDirFile(DIR_MACOS + FILE_APP_BIN, false);
-
   let launchBin = getLaunchBin();
   let args = getProcessArgs();
   debugDump("launching " + launchBin.path + " " + args.join(" "));
 
   gProcess = Cc["@mozilla.org/process/util;1"].
              createInstance(Ci.nsIProcess);
   gProcess.init(launchBin);
 
--- a/toolkit/profile/content/profileSelection.js
+++ b/toolkit/profile/content/profileSelection.js
@@ -222,17 +222,16 @@ function RenameProfile()
     return true;
   }
 
   return false;
 }
 
 function ConfirmDelete()
 {
-  var deleteButton = document.getElementById("delbutton");
   var profileList = document.getElementById( "profiles" );
 
   var selectedItem = profileList.selectedItem;
   if (!selectedItem) {
     return false;
   }
 
   var selectedProfile = selectedItem.profile;
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -590,16 +590,17 @@ public:
         break;
       case eKeyboardEventClass:
         mFlags.mComposed = mMessage == eKeyDown || mMessage == eKeyUp ||
                            mMessage == eKeyPress;
         break;
       case eMouseEventClass:
         mFlags.mComposed = mMessage == eMouseClick ||
                            mMessage == eMouseDoubleClick ||
+                           mMessage == eMouseAuxClick ||
                            mMessage == eMouseDown || mMessage == eMouseUp ||
                            mMessage == eMouseEnter || mMessage == eMouseLeave ||
                            mMessage == eMouseOver || mMessage == eMouseOut ||
                            mMessage == eMouseMove || mMessage == eContextMenu;
         break;
       case ePointerEventClass:
         // All pointer events are composed
         mFlags.mComposed = mMessage == ePointerDown ||
--- a/widget/EventMessageList.h
+++ b/widget/EventMessageList.h
@@ -79,16 +79,17 @@ NS_EVENT_MESSAGE(eLanguageChange)
 
 NS_EVENT_MESSAGE(eMouseMove)
 NS_EVENT_MESSAGE(eMouseUp)
 NS_EVENT_MESSAGE(eMouseDown)
 NS_EVENT_MESSAGE(eMouseEnterIntoWidget)
 NS_EVENT_MESSAGE(eMouseExitFromWidget)
 NS_EVENT_MESSAGE(eMouseDoubleClick)
 NS_EVENT_MESSAGE(eMouseClick)
+NS_EVENT_MESSAGE(eMouseAuxClick)
 // eMouseActivate is fired when the widget is activated by a click.
 NS_EVENT_MESSAGE(eMouseActivate)
 NS_EVENT_MESSAGE(eMouseOver)
 NS_EVENT_MESSAGE(eMouseOut)
 NS_EVENT_MESSAGE(eMouseHitTest)
 NS_EVENT_MESSAGE(eMouseEnter)
 NS_EVENT_MESSAGE(eMouseLeave)
 NS_EVENT_MESSAGE(eMouseLongTap)
--- a/widget/WidgetEventImpl.cpp
+++ b/widget/WidgetEventImpl.cpp
@@ -231,16 +231,17 @@ WidgetEvent::IsNativeEventDelivererForPl
 bool
 WidgetEvent::HasMouseEventMessage() const
 {
   switch (mMessage) {
     case eMouseDown:
     case eMouseUp:
     case eMouseClick:
     case eMouseDoubleClick:
+    case eMouseAuxClick:
     case eMouseEnterIntoWidget:
     case eMouseExitFromWidget:
     case eMouseActivate:
     case eMouseOver:
     case eMouseOut:
     case eMouseHitTest:
     case eMouseMove:
       return true;
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -3081,16 +3081,17 @@ case _value: eventName.AssignLiteral(_na
     _ASSIGN_eventName(eKeyDown,"eKeyDown");
     _ASSIGN_eventName(eKeyPress,"eKeyPress");
     _ASSIGN_eventName(eKeyUp,"eKeyUp");
     _ASSIGN_eventName(eMouseEnterIntoWidget,"eMouseEnterIntoWidget");
     _ASSIGN_eventName(eMouseExitFromWidget,"eMouseExitFromWidget");
     _ASSIGN_eventName(eMouseDown,"eMouseDown");
     _ASSIGN_eventName(eMouseUp,"eMouseUp");
     _ASSIGN_eventName(eMouseClick,"eMouseClick");
+    _ASSIGN_eventName(eMouseAuxClick,"eMouseAuxClick");
     _ASSIGN_eventName(eMouseDoubleClick,"eMouseDoubleClick");
     _ASSIGN_eventName(eMouseMove,"eMouseMove");
     _ASSIGN_eventName(eLoad,"eLoad");
     _ASSIGN_eventName(ePopState,"ePopState");
     _ASSIGN_eventName(eBeforeScriptExecute,"eBeforeScriptExecute");
     _ASSIGN_eventName(eAfterScriptExecute,"eAfterScriptExecute");
     _ASSIGN_eventName(eUnload,"eUnload");
     _ASSIGN_eventName(eHashChange,"eHashChange");
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -1138,17 +1138,18 @@ WinUtils::GetMousePointerID()
 
 /* static */
 bool
 WinUtils::GetIsMouseFromTouch(EventMessage aEventMessage)
 {
   const uint32_t MOZ_T_I_SIGNATURE = TABLET_INK_TOUCH | TABLET_INK_SIGNATURE;
   const uint32_t MOZ_T_I_CHECK_TCH = TABLET_INK_TOUCH | TABLET_INK_CHECK;
   return ((aEventMessage == eMouseMove || aEventMessage == eMouseDown ||
-           aEventMessage == eMouseUp || aEventMessage == eMouseDoubleClick) &&
+           aEventMessage == eMouseUp || aEventMessage == eMouseAuxClick ||
+           aEventMessage == eMouseDoubleClick) &&
          (GetMessageExtraInfo() & MOZ_T_I_SIGNATURE) == MOZ_T_I_CHECK_TCH);
 }
 
 /* static */
 MSG
 WinUtils::InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam, HWND aWnd)
 {
   MSG msg;
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -623,35 +623,41 @@ public:
   MOZ_MUST_USE RefPtr<MozPromise>
   ThenPromise(AbstractThread* aResponseThread, const char* aCallSite, ThisType* aThisVal,
               ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
   {
     using ThenType = MethodThenValue<ThisType, ResolveMethodType, RejectMethodType>;
     RefPtr<ThenValueBase> thenValue = new ThenType(
       aResponseThread, aThisVal, aResolveMethod, aRejectMethod, aCallSite);
     // mCompletionPromise must be created before ThenInternal() to avoid race.
-    thenValue->mCompletionPromise = new MozPromise::Private(
+    RefPtr<MozPromise> p = new MozPromise::Private(
       "<completion promise>", true /* aIsCompletionPromise */);
+    thenValue->mCompletionPromise = p;
+    // Note ThenInternal() might nullify mCompletionPromise before return.
+    // So we need to return p instead of mCompletionPromise.
     ThenInternal(aResponseThread, thenValue, aCallSite);
-    return thenValue->mCompletionPromise;
+    return p;
   }
 
   template<typename ResolveFunction, typename RejectFunction>
   MOZ_MUST_USE RefPtr<MozPromise>
   ThenPromise(AbstractThread* aResponseThread, const char* aCallSite,
               ResolveFunction&& aResolveFunction, RejectFunction&& aRejectFunction)
   {
     using ThenType = FunctionThenValue<ResolveFunction, RejectFunction>;
     RefPtr<ThenValueBase> thenValue = new ThenType(
       aResponseThread, Move(aResolveFunction), Move(aRejectFunction), aCallSite);
     // mCompletionPromise must be created before ThenInternal() to avoid race.
-    thenValue->mCompletionPromise = new MozPromise::Private(
+    RefPtr<MozPromise> p = new MozPromise::Private(
       "<completion promise>", true /* aIsCompletionPromise */);
+    thenValue->mCompletionPromise = p;
+    // Note ThenInternal() might nullify mCompletionPromise before return.
+    // So we need to return p instead of mCompletionPromise.
     ThenInternal(aResponseThread, thenValue, aCallSite);
-    return thenValue->mCompletionPromise;
+    return p;
   }
 
   void ChainTo(already_AddRefed<Private> aChainedPromise, const char* aCallSite)
   {
     MutexAutoLock lock(mMutex);
     MOZ_DIAGNOSTIC_ASSERT(!IsExclusive || !mHaveRequest);
     mHaveRequest = true;
     RefPtr<Private> chainedPromise = aChainedPromise;