merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 03 May 2016 16:17:32 +0200
changeset 362943 0a25833062a880f369e6f9f622413a94cc671bf4
parent 362793 9f866b72af4a3c4520205d55c60aa74548682c4a (current diff)
parent 362942 9e9f61f2b980ecc50b08c4cd944870ef2c42deb9 (diff)
child 362944 7f959c47385b56693f4977f4dc035971e98f68ed
child 362965 4ef8ee7f945ae397ac46ca7f420b4f28f6408f06
child 362967 146d177546b0e19947cd38a6c50bb750fa1fb091
child 362984 fbfca6a2366703d561c892365f5a422d6e43fab4
child 362985 0a81ad3bbff8796de1874ae32646f1f9cfc1a2b6
child 363051 2f658925992438b703466c0430f455bdd008b9a0
child 363101 1f51d38aa4997a2f3c1545dfe0950f209e6949f5
child 363110 b988845a276613d24d6246055becb68dbbfb6fd8
child 363133 5d02c4451a926f256885a94b783ebaad80086bb3
child 363144 8e8914d0eba96cc3c598ef6b846b06fc21b93d5c
child 363145 4183d1219a6be52bb95609e431f8ebe2677b5a5b
child 363154 10a60d56e37a9e758a17e4b80f55c82dd358cd45
child 363155 ab8eb8401a0c7021d9432e19aea4335d7b7d09dd
child 363156 199fdd2885e8e0999954be88e86967883943c946
child 363161 ce364739911ba0e17d93fd0ba56f671c7c841edd
child 363162 a099ca32a7eabd3c096ff2394f0dec5fd60525ca
child 363165 4b1eaf2e1c0d2a679665633456797653044aed1c
child 363187 3dbc63f311c1b585ddea4f89521c3b7cae548c0c
child 363196 7e384eb740a4ae1be5f40fe2fc31bc90d8f2854c
child 363202 0e29ccf9f04bf448e87a9767f4f0fa4c426ccfe6
child 363221 f4ab0bc658d669047b10df70b87cc63cec124f21
child 363231 d25b93936f508d69d5e83596eedbd66a35318f2b
child 363232 13054350512c010fd207d136c576559a11b092b5
child 363234 77c95ebb94a5af31ec4ad55f07e1453c7b15519c
child 363266 e38f949d7f59925c3f82a6193352e580a50d2636
child 363324 fac1310c919aa9c7a290a88e36da1490ebbc1406
child 363458 77e1c272105648a12e11defd74c6e2d37590c1a4
child 363522 ceaf5e30a72a27e73783c295f1f48a43dfc5ba33
child 363523 10b37e02c71e290af33a796984da660ab35c5d80
child 363657 f98988c649094859673c3f329c5c97e5b76f037c
child 363660 4daf7d4669369ef9bdc1f8d4e2ae0acc09649622
child 363680 2f40f8ea33533df989a054546dc4fc8b6e66e1f9
child 364158 ec041b5e59f72ae13a8cf5a6a051b86ef9f0a780
child 364792 fceef04ddb0f4650b8c6fd8d25489a0feb6394e9
child 365951 199dbae4f8c4ef110212035d5e4a2a27b25b5788
child 366394 aa64b236e3031bd8d5733b10c82393d12f253822
child 491518 9291c3b0effd78f29db8c03f8a5a687ebb423ce9
push id17058
push userbmo:ttromey@mozilla.com
push dateTue, 03 May 2016 14:35:18 +0000
reviewersmerge
milestone49.0a1
merge mozilla-inbound to mozilla-central a=merge
dom/requestsync/RequestSync.manifest
dom/requestsync/RequestSyncApp.jsm
dom/requestsync/RequestSyncManager.js
dom/requestsync/RequestSyncScheduler.js
dom/requestsync/RequestSyncService.jsm
dom/requestsync/RequestSyncTask.jsm
dom/requestsync/RequestSyncWifiService.cpp
dom/requestsync/RequestSyncWifiService.h
dom/requestsync/moz.build
dom/requestsync/tests/common_app.js
dom/requestsync/tests/common_basic.js
dom/requestsync/tests/file_app.sjs
dom/requestsync/tests/file_app.template.webapp
dom/requestsync/tests/file_basic_app.html
dom/requestsync/tests/file_interface.html
dom/requestsync/tests/mochitest.ini
dom/requestsync/tests/system_message_chrome_script.js
dom/requestsync/tests/test_basic.html
dom/requestsync/tests/test_basic_app.html
dom/requestsync/tests/test_bug1151082.html
dom/requestsync/tests/test_minInterval.html
dom/requestsync/tests/test_promise.html
dom/requestsync/tests/test_runNow.html
dom/requestsync/tests/test_wakeUp.html
dom/requestsync/tests/test_webidl.html
dom/webidl/RequestSyncManager.webidl
dom/webidl/RequestSyncScheduler.webidl
extensions/spellcheck/hunspell/src/dictmgr.cxx
extensions/spellcheck/hunspell/src/dictmgr.hxx
extensions/spellcheck/hunspell/src/patches/01-675553.diff
extensions/spellcheck/hunspell/src/patches/02-690892.diff
extensions/spellcheck/hunspell/src/patches/03-clang.diff
extensions/spellcheck/hunspell/src/patches/04-777292.diff
extensions/spellcheck/hunspell/src/patches/05-579517.diff
extensions/spellcheck/hunspell/src/patches/06-784776.diff
extensions/spellcheck/hunspell/src/patches/07-927728.diff
extensions/spellcheck/hunspell/src/patches/08-943268.diff
extensions/spellcheck/hunspell/src/patches/09-license.diff
extensions/spellcheck/hunspell/src/patches/10-983817.diff
extensions/spellcheck/hunspell/src/patches/11-318040.diff
mobile/android/config/tooltool-manifests/android/releng.manifest
modules/fdlibm/src/fdlibm.h.orig
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/cross-origin/http-http/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/cross-origin/http-http/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/cross-origin/http-http/iframe-tag/generic.swap-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/same-origin/http-http/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/same-origin/http-http/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/same-origin/http-http/iframe-tag/generic.swap-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/cross-origin/http-http/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/cross-origin/http-http/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/cross-origin/http-http/iframe-tag/generic.swap-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/same-origin/http-http/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/same-origin/http-http/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/same-origin/http-http/iframe-tag/generic.swap-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html.ini
testing/web-platform/meta/referrer-policy/origin-only/attr-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html.ini
--- a/accessible/base/EventTree.cpp
+++ b/accessible/base/EventTree.cpp
@@ -148,16 +148,17 @@ TreeMutation::Done()
   for (uint32_t idx = 0; idx < mStartIdx && idx < length; idx++) {
     MOZ_ASSERT(mParent->mChildren[idx]->mIndexInParent == static_cast<int32_t>(idx),
                "Wrong index detected");
   }
 #endif
 
   for (uint32_t idx = mStartIdx; idx < length; idx++) {
     mParent->mChildren[idx]->mIndexInParent = idx;
+    mParent->mChildren[idx]->mInt.mIndexOfEmbeddedChild = -1;
     mParent->mChildren[idx]->mStateFlags |= Accessible::eGroupInfoDirty;
   }
 
   if (mStartIdx < mParent->mChildren.Length() - 1) {
     mParent->mEmbeddedObjCollector = nullptr;
   }
 
   mParent->mStateFlags |= mStateFlagsCopy & Accessible::eKidsMutating;
--- a/accessible/tests/mochitest/hypertext/test_update.html
+++ b/accessible/tests/mochitest/hypertext/test_update.html
@@ -119,28 +119,54 @@
       }
 
       this.getID = function removeChild_getID()
       {
         return "check text after removing child from '" + aContainerID + "'";
       }
     }
 
+    function removeFirstChild(aContainer)
+    {
+      this.ht = getAccessible(aContainer, [ nsIAccessibleHyperText ]);
+      this.eventSeq = [
+        new invokerChecker(EVENT_REORDER, aContainer)
+      ];
 
+      this.invoke = function removeFirstChild_invoke()
+      {
+        is(this.ht.linkCount, 2, "Wrong embedded objects count before removal");
+
+        getNode(aContainer).removeChild(getNode(aContainer).firstElementChild);
+      }
+
+      this.finalCheck = function removeFirstChild_finalCheck()
+      {
+        // check list index before link count
+        is(this.ht.getLinkIndex(this.ht.firstChild), 0, "Wrong child index");
+        is(this.ht.linkCount, 1, "Wrong embedded objects count after removal");
+      }
+
+      this.getID = function removeFirstChild_getID()
+      {
+        return "Remove first child and check embedded object indeces";
+      }
+    }
 
     //gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
     function doTest()
     {
       gQueue = new eventQueue();
       gQueue.push(new addLinks("p1"));
       gQueue.push(new updateText("p2"));
       gQueue.push(new removeChild("div1","div2",
                                   "hello my good friend", "hello friend"));
+      gQueue.push(new removeFirstChild("c4"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
@@ -164,10 +190,14 @@
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <p id="p1"></p>
   <p id="p2"><b>hello</b><a>friend</a></p>
   <div id="div1">hello<span id="div2"> my<span id="div3"> good</span></span> friend</span></div>
+  <form id="c4">
+    <label for="c4_input">label</label>
+    <input id="c4_input">
+  </form>
 </body>
 </html>
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -1050,19 +1050,16 @@ pref("dom.mozSettings.SettingsManager.ve
 pref("dom.mozSettings.SettingsRequestManager.verbose.enabled", false);
 pref("dom.mozSettings.SettingsService.verbose.enabled", false);
 
 // Controlling whether we want to allow forcing some Settings
 // IndexedDB transactions to be opened as readonly or keep everything as
 // readwrite.
 pref("dom.mozSettings.allowForceReadOnly", false);
 
-// RequestSync API is enabled by default on B2G.
-pref("dom.requestSync.enabled", true);
-
 // Comma separated list of activity names that can only be provided by
 // the system app in dev mode.
 pref("dom.activities.developer_mode_only", "import-app");
 
 // mulet apparently loads firefox.js as well as b2g.js, so we have to explicitly
 // disable serviceworkers and push here to get them disabled in mulet.
 pref("dom.serviceWorkers.enabled", false);
 pref("dom.push.enabled", false);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -11,17 +11,16 @@ Cu.import('resource://gre/modules/AlarmS
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
 Cu.import('resource://gre/modules/NotificationDB.jsm');
 Cu.import('resource://gre/modules/Payment.jsm');
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
 Cu.import('resource://gre/modules/AlertsHelper.jsm');
-Cu.import('resource://gre/modules/RequestSyncService.jsm');
 Cu.import('resource://gre/modules/SystemUpdateService.jsm');
 
 if (isGonk) {
   Cu.import('resource://gre/modules/NetworkStatsService.jsm');
   Cu.import('resource://gre/modules/ResourceStatsService.jsm');
 }
 
 Cu.import('resource://gre/modules/KillSwitchMain.jsm');
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -346,19 +346,16 @@
 @RESPATH@/components/xpcom_xpti.xpt
 @RESPATH@/components/xpconnect.xpt
 @RESPATH@/components/xulapp.xpt
 @RESPATH@/components/xul.xpt
 @RESPATH@/components/xultmpl.xpt
 @RESPATH@/components/zipwriter.xpt
 
 ; JavaScript components
-@RESPATH@/components/RequestSync.manifest
-@RESPATH@/components/RequestSyncManager.js
-@RESPATH@/components/RequestSyncScheduler.js
 @RESPATH@/components/ChromeNotifications.js
 @RESPATH@/components/ChromeNotifications.manifest
 @RESPATH@/components/ConsoleAPI.manifest
 @RESPATH@/components/ConsoleAPIStorage.js
 @RESPATH@/components/BrowserElementParent.manifest
 @RESPATH@/components/BrowserElementParent.js
 @RESPATH@/components/BrowserElementProxy.manifest
 @RESPATH@/components/BrowserElementProxy.js
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -62,17 +62,17 @@
                 <button id="checkForUpdatesButton" align="start"
                         label="&update.checkForUpdatesButton.label;"
                         accesskey="&update.checkForUpdatesButton.accesskey;"
                         oncommand="gAppUpdater.checkForUpdates();"/>
                 <spacer flex="1"/>
               </hbox>
               <hbox id="downloadAndInstall" align="center">
                 <button id="downloadAndInstallButton" align="start"
-                        oncommand="gAppUpdater.doUpdate();"/>
+                        oncommand="gAppUpdater.startDownload();"/>
                         <!-- label and accesskey will be filled by JS -->
                 <spacer flex="1"/>
               </hbox>
               <hbox id="apply" align="center">
                 <button id="updateButton" align="start"
                         label="&update.updateButton.label2;"
                         accesskey="&update.updateButton.accesskey;"
                         oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
--- a/browser/base/content/browser-fullScreen.js
+++ b/browser/base/content/browser-fullScreen.js
@@ -126,32 +126,17 @@ var FullScreen = {
         // to get its corresponding browser here.
         let browser;
         if (event.target == gBrowser) {
           browser = event.originalTarget;
         } else {
           let topWin = event.target.ownerDocument.defaultView.top;
           browser = gBrowser.getBrowserForContentWindow(topWin);
         }
-        if (!browser || !this.enterDomFullscreen(browser)) {
-          if (document.fullscreenElement) {
-            // MozDOMFullscreen:Entered is dispatched synchronously in
-            // fullscreen change, hence we have to avoid calling this
-            // method synchronously here.
-            setTimeout(() => document.exitFullscreen(), 0);
-          }
-          break;
-        }
-        // If it is a remote browser, send a message to ask the content
-        // to enter fullscreen state. We don't need to do so if it is an
-        // in-process browser, since all related document should have
-        // entered fullscreen state at this point.
-        if (this._isRemoteBrowser(browser)) {
-          browser.messageManager.sendAsyncMessage("DOMFullscreen:Entered");
-        }
+        this.enterDomFullscreen(browser);
         break;
       }
       case "MozDOMFullscreen:Exited":
         this.cleanupDomFullscreen();
         break;
     }
   },
 
@@ -173,32 +158,40 @@ var FullScreen = {
       case "DOMFullscreen:Painted": {
         Services.obs.notifyObservers(window, "fullscreen-painted", "");
         break;
       }
     }
   },
 
   enterDomFullscreen : function(aBrowser) {
-    if (!document.fullscreenElement)
-      return false;
+    if (!document.fullscreenElement) {
+      return;
+    }
 
     // If we've received a fullscreen notification, we have to ensure that the
     // element that's requesting fullscreen belongs to the browser that's currently
     // active. If not, we exit fullscreen since the "full-screen document" isn't
     // actually visible now.
-    if (gBrowser.selectedBrowser != aBrowser) {
-      return false;
+    if (!aBrowser || gBrowser.selectedBrowser != aBrowser ||
+        // The top-level window has lost focus since the request to enter
+        // full-screen was made. Cancel full-screen.
+        Services.focus.activeWindow != window) {
+      // This function is called synchronously in fullscreen change, so
+      // we have to avoid calling exitFullscreen synchronously here.
+      setTimeout(() => document.exitFullscreen(), 0);
+      return;
     }
 
-    let focusManager = Services.focus;
-    if (focusManager.activeWindow != window) {
-      // The top-level window has lost focus since the request to enter
-      // full-screen was made. Cancel full-screen.
-      return false;
+    // If it is a remote browser, send a message to ask the content
+    // to enter fullscreen state. We don't need to do so if it is an
+    // in-process browser, since all related document should have
+    // entered fullscreen state at this point.
+    if (this._isRemoteBrowser(aBrowser)) {
+      aBrowser.messageManager.sendAsyncMessage("DOMFullscreen:Entered");
     }
 
     document.documentElement.setAttribute("inDOMFullscreen", true);
 
     if (gFindBarInitialized) {
       gFindBar.close(true);
     }
 
@@ -206,40 +199,38 @@ var FullScreen = {
     gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
     gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
     gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
 
     // Add listener to detect when the fullscreen window is re-focused.
     // If a fullscreen window loses focus, we show a warning when the
     // fullscreen window is refocused.
     window.addEventListener("activate", this);
-
-    return true;
   },
 
   cleanup: function () {
     if (!window.fullScreen) {
       MousePosTracker.removeListener(this);
       document.removeEventListener("keypress", this._keyToggleCallback, false);
       document.removeEventListener("popupshown", this._setPopupOpen, false);
       document.removeEventListener("popuphidden", this._setPopupOpen, false);
     }
   },
 
   cleanupDomFullscreen: function () {
+    window.messageManager
+          .broadcastAsyncMessage("DOMFullscreen:CleanUp");
+
     this._WarningBox.close();
     gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
     gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
     gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
     window.removeEventListener("activate", this);
 
     document.documentElement.removeAttribute("inDOMFullscreen");
-
-    window.messageManager
-          .broadcastAsyncMessage("DOMFullscreen:CleanUp");
   },
 
   _isRemoteBrowser: function (aBrowser) {
     return gMultiProcessBrowser && aBrowser.getAttribute("remote") == "true";
   },
 
   get _windowUtils() {
     return window.QueryInterface(Ci.nsIInterfaceRequestor)
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -1014,16 +1014,17 @@ var PageInfoListener = {
     let docInfo = {};
     docInfo.title = document.title;
     docInfo.location = document.location.toString();
     docInfo.referrer = document.referrer;
     docInfo.compatMode = document.compatMode;
     docInfo.contentType = document.contentType;
     docInfo.characterSet = document.characterSet;
     docInfo.lastModified = document.lastModified;
+    docInfo.principal = document.nodePrincipal;
 
     let documentURIObject = {};
     documentURIObject.spec = document.documentURIObject.spec;
     documentURIObject.originCharset = document.documentURIObject.originCharset;
     docInfo.documentURIObject = documentURIObject;
 
     docInfo.isContentWindowPrivate = PrivateBrowsingUtils.isContentWindowPrivate(content);
 
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -370,29 +370,30 @@ function loadPageInfo(frameOuterWindowID
   // Get initial pageInfoData needed to display the general, feeds, permission and security tabs.
   mm.addMessageListener("PageInfo:data", function onmessage(message) {
     mm.removeMessageListener("PageInfo:data", onmessage);
     pageInfoData = message.data;
     let docInfo = pageInfoData.docInfo;
     let windowInfo = pageInfoData.windowInfo;
     let uri = makeURI(docInfo.documentURIObject.spec,
                       docInfo.documentURIObject.originCharset);
+    let principal = docInfo.principal;
     gDocInfo = docInfo;
 
     gImageElement = pageInfoData.imageInfo;
 
     var titleFormat = windowInfo.isTopWindow ? "pageInfo.page.title"
                                              : "pageInfo.frame.title";
     document.title = gBundle.getFormattedString(titleFormat, [docInfo.location]);
 
     document.getElementById("main-window").setAttribute("relatedUrl", docInfo.location);
 
     makeGeneralTab(pageInfoData.metaViewRows, docInfo);
     initFeedTab(pageInfoData.feeds);
-    onLoadPermission(uri);
+    onLoadPermission(uri, principal);
     securityOnLoad(uri, windowInfo);
   });
 
   // Get the media elements from content script to setup the media tab.
   mm.addMessageListener("PageInfo:mediaData", function onmessage(message) {
     // Page info window was closed.
     if (window.closed) {
       mm.removeMessageListener("PageInfo:mediaData", onmessage);
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource:///modules/SitePermissions.jsm");
 Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
 
 const nsIQuotaManagerService = Components.interfaces.nsIQuotaManagerService;
 
 var gPermURI;
+var gPermPrincipal;
 var gUsageRequest;
 
 var gPermissions = SitePermissions.listPermissions();
 gPermissions.push("plugins");
 
 var permissionObserver = {
   observe: function (aSubject, aTopic, aData)
   {
@@ -23,21 +24,22 @@ var permissionObserver = {
           initRow(permission.type);
         else if (permission.type.startsWith("plugin"))
           setPluginsRadioState();
       }
     }
   }
 };
 
-function onLoadPermission(uri)
+function onLoadPermission(uri, principal)
 {
   var permTab = document.getElementById("permTab");
   if (SitePermissions.isSupportedURI(uri)) {
     gPermURI = uri;
+    gPermPrincipal = principal;
     var hostText = document.getElementById("hostText");
     hostText.value = gPermURI.prePath;
 
     for (var i of gPermissions)
       initRow(i);
     var os = Components.classes["@mozilla.org/observer-service;1"]
                        .getService(Components.interfaces.nsIObserverService);
     os.addObserver(permissionObserver, "perm-changed", false);
@@ -184,40 +186,33 @@ function initIndexedDBRow()
   let row = document.getElementById("perm-indexedDB-row");
   let extras = document.getElementById("perm-indexedDB-extras");
 
   row.appendChild(extras);
 
   var quotaManagerService =
     Components.classes["@mozilla.org/dom/quota-manager-service;1"]
               .getService(nsIQuotaManagerService);
-  let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
-                            .getService(Components.interfaces.nsIScriptSecurityManager)
-                            .createCodebasePrincipal(gPermURI, {});
   gUsageRequest =
-    quotaManagerService.getUsageForPrincipal(principal,
+    quotaManagerService.getUsageForPrincipal(gPermPrincipal,
                                              onIndexedDBUsageCallback);
 
   var status = document.getElementById("indexedDBStatus");
   var button = document.getElementById("indexedDBClear");
 
   status.value = "";
   status.setAttribute("hidden", "true");
   button.setAttribute("hidden", "true");
 }
 
 function onIndexedDBClear()
 {
-  let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
-                            .getService(Components.interfaces.nsIScriptSecurityManager)
-                            .createCodebasePrincipal(gPermURI, {});
-
   Components.classes["@mozilla.org/dom/quota-manager-service;1"]
             .getService(nsIQuotaManagerService)
-            .clearStoragesForPrincipal(principal);
+            .clearStoragesForPrincipal(gPermPrincipal);
 
   Components.classes["@mozilla.org/serviceworkers/manager;1"]
             .getService(Components.interfaces.nsIServiceWorkerManager)
             .removeAndPropagate(gPermURI.host);
 
   SitePermissions.remove(gPermURI, "indexedDB");
   initIndexedDBRow();
 }
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -507,20 +507,16 @@
 @RESPATH@/components/Webapps.manifest
 @RESPATH@/components/AppsService.js
 @RESPATH@/components/AppsService.manifest
 @RESPATH@/components/recording-cmdline.js
 @RESPATH@/components/recording-cmdline.manifest
 @RESPATH@/components/htmlMenuBuilder.js
 @RESPATH@/components/htmlMenuBuilder.manifest
 
-@RESPATH@/components/RequestSync.manifest
-@RESPATH@/components/RequestSyncManager.js
-@RESPATH@/components/RequestSyncScheduler.js
-
 @RESPATH@/components/PermissionSettings.js
 @RESPATH@/components/PermissionSettings.manifest
 @RESPATH@/components/ContactManager.js
 @RESPATH@/components/ContactManager.manifest
 @RESPATH@/components/PhoneNumberService.js
 @RESPATH@/components/PhoneNumberService.manifest
 @RESPATH@/components/NotificationStorage.js
 @RESPATH@/components/NotificationStorage.manifest
--- a/build/moz.configure/memory.configure
+++ b/build/moz.configure/memory.configure
@@ -81,17 +81,18 @@ set_define(jemalloc_os_define_android, '
 
 
 option('--enable-replace-malloc',
        help='Enable ability to dynamically replace the malloc implementation')
 
 @depends('--enable-replace-malloc', jemalloc, milestone, build_project)
 def replace_malloc(value, jemalloc, milestone, build_project):
     # Enable on central for the debugging opportunities it adds.
+    if value and not jemalloc:
+        die('--enable-replace-malloc requires --enable-jemalloc')
+    if value.origin != 'default':
+        return bool(value) or None
     if milestone.is_nightly and jemalloc and build_project != 'js':
         return True
-    if value and not jemalloc:
-        die('--enable-replace-malloc requires --enable-jemalloc')
-    return bool(value) or None
 
 set_config('MOZ_REPLACE_MALLOC', replace_malloc)
 set_define('MOZ_REPLACE_MALLOC', replace_malloc)
 add_old_configure_assignment('MOZ_REPLACE_MALLOC', replace_malloc)
--- a/config/system-headers
+++ b/config/system-headers
@@ -251,16 +251,17 @@ cairo-ps.h
 cairo-tee.h
 cairo-quartz.h
 cairo-win32.h
 cairo-xlib.h
 cairo-xlib-xrender.h
 cairo-directfb.h
 cairo-qpainter.h
 cairo-qt.h
+complex
 dfiff.h
 exception
 ffi.h
 fusion/reactor.h
 fusion/property.h
 fusion/conf.h
 fusion/build.h
 fusion/hash.h
--- a/dom/apps/PermissionsTable.jsm
+++ b/dom/apps/PermissionsTable.jsm
@@ -467,21 +467,16 @@ this.PermissionsTable =  { geolocation: 
                              privileged: DENY_ACTION,
                              certified: ALLOW_ACTION
                            },
                            "presentation-device-manage": {
                              app: DENY_ACTION,
                              privileged: DENY_ACTION,
                              certified: ALLOW_ACTION
                            },
-                           "requestsync-manager": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
                            "secureelement-manage": {
                              app: DENY_ACTION,
                              privileged: DENY_ACTION,
                              certified: ALLOW_ACTION
                            },
                            "inputport": {
                              app: DENY_ACTION,
                              privileged: DENY_ACTION,
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -1044,17 +1044,16 @@ METHOD(Exception, "exception")
 METHOD(Debug, "debug")
 METHOD(Table, "table")
 METHOD(Clear, "clear")
 
 void
 Console::Trace(JSContext* aCx)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
 
   const Sequence<JS::Value> data;
   Method(aCx, MethodTrace, NS_LITERAL_STRING("trace"), data);
 }
 
 // Displays an interactive listing of all the properties of an object.
 METHOD(Dir, "dir");
 METHOD(Dirxml, "dirxml");
@@ -1062,83 +1061,78 @@ METHOD(Dirxml, "dirxml");
 METHOD(Group, "group")
 METHOD(GroupCollapsed, "groupCollapsed")
 METHOD(GroupEnd, "groupEnd")
 
 void
 Console::Time(JSContext* aCx, const JS::Handle<JS::Value> aTime)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
 
   Sequence<JS::Value> data;
   SequenceRooter<JS::Value> rooter(aCx, &data);
 
   if (!aTime.isUndefined() && !data.AppendElement(aTime, fallible)) {
     return;
   }
 
   Method(aCx, MethodTime, NS_LITERAL_STRING("time"), data);
 }
 
 void
 Console::TimeEnd(JSContext* aCx, const JS::Handle<JS::Value> aTime)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
 
   Sequence<JS::Value> data;
   SequenceRooter<JS::Value> rooter(aCx, &data);
 
   if (!aTime.isUndefined() && !data.AppendElement(aTime, fallible)) {
     return;
   }
 
   Method(aCx, MethodTimeEnd, NS_LITERAL_STRING("timeEnd"), data);
 }
 
 void
 Console::TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
 
   Sequence<JS::Value> data;
   SequenceRooter<JS::Value> rooter(aCx, &data);
 
   if (aData.isString() && !data.AppendElement(aData, fallible)) {
     return;
   }
 
   Method(aCx, MethodTimeStamp, NS_LITERAL_STRING("timeStamp"), data);
 }
 
 void
 Console::Profile(JSContext* aCx, const Sequence<JS::Value>& aData)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
-
   ProfileMethod(aCx, NS_LITERAL_STRING("profile"), aData);
 }
 
 void
 Console::ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
-
   ProfileMethod(aCx, NS_LITERAL_STRING("profileEnd"), aData);
 }
 
 void
 Console::ProfileMethod(JSContext* aCx, const nsAString& aAction,
                        const Sequence<JS::Value>& aData)
 {
-  MOZ_ASSERT(mStatus == eInitialized);
+  if (IsShuttingDown()) {
+    return;
+  }
 
   if (!NS_IsMainThread()) {
     // Here we are in a worker thread.
     RefPtr<ConsoleProfileRunnable> runnable =
       new ConsoleProfileRunnable(this, aAction, aData);
 
     JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
     runnable->Dispatch(aCx);
@@ -1186,30 +1180,28 @@ Console::ProfileMethod(JSContext* aCx, c
   }
 }
 
 void
 Console::Assert(JSContext* aCx, bool aCondition,
                 const Sequence<JS::Value>& aData)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
 
   if (!aCondition) {
     Method(aCx, MethodAssert, NS_LITERAL_STRING("assert"), aData);
   }
 }
 
 METHOD(Count, "count")
 
 void
 Console::NoopMethod()
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
 
   // Nothing to do.
 }
 
 static
 nsresult
 StackFrameToStackEntry(JSContext* aCx, nsIStackFrame* aStackFrame,
                        ConsoleStackEntry& aStackEntry)
@@ -1273,17 +1265,19 @@ ReifyStack(JSContext* aCx, nsIStackFrame
 
 // Queue a call to a console method. See the CALL_DELAY constant.
 void
 Console::Method(JSContext* aCx, MethodName aMethodName,
                 const nsAString& aMethodString,
                 const Sequence<JS::Value>& aData)
 {
   AssertIsOnOwningThread();
-  MOZ_ASSERT(mStatus == eInitialized);
+  if (IsShuttingDown()) {
+    return;
+  }
 
   RefPtr<ConsoleCallData> callData(new ConsoleCallData());
 
   ClearException ce(aCx);
 
   if (NS_WARN_IF(!callData->Initialize(aCx, aMethodName, aMethodString,
                                        aData, this))) {
     return;
@@ -2406,10 +2400,17 @@ Console::SetConsoleEventHandler(AnyCallb
 
 void
 Console::AssertIsOnOwningThread() const
 {
   MOZ_ASSERT(mOwningThread);
   MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread);
 }
 
+bool
+Console::IsShuttingDown() const
+{
+  MOZ_ASSERT(mStatus != eUnknown);
+  return mStatus == eShuttingDown;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Console.h
+++ b/dom/base/Console.h
@@ -31,18 +31,16 @@ class ConsoleRunnable;
 class ConsoleCallDataRunnable;
 class ConsoleProfileRunnable;
 struct ConsoleStackEntry;
 
 class Console final : public nsIObserver
                     , public nsWrapperCache
                     , public nsSupportsWeakReference
 {
-  ~Console();
-
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Console, nsIObserver)
   NS_DECL_NSIOBSERVER
 
   static already_AddRefed<Console>
   Create(nsPIDOMWindowInner* aWindow, ErrorResult& aRv);
 
@@ -128,16 +126,17 @@ public:
   RetrieveConsoleEvents(JSContext* aCx, nsTArray<JS::Value>& aEvents,
                         ErrorResult& aRv);
 
   void
   SetConsoleEventHandler(AnyCallback* aHandler);
 
 private:
   explicit Console(nsPIDOMWindowInner* aWindow);
+  ~Console();
 
   void
   Initialize(ErrorResult& aRv);
 
   void
   Shutdown();
 
   enum MethodName
@@ -338,16 +337,19 @@ private:
   ShouldIncludeStackTrace(MethodName aMethodName) const;
 
   JSObject*
   GetOrCreateSandbox(JSContext* aCx, nsIPrincipal* aPrincipal);
 
   void
   AssertIsOnOwningThread() const;
 
+  bool
+  IsShuttingDown() const;
+
   // All these nsCOMPtr are touched on main thread only.
   nsCOMPtr<nsPIDOMWindowInner> mWindow;
   nsCOMPtr<nsIConsoleAPIStorage> mStorage;
   RefPtr<JSObjectHolder> mSandbox;
 
   // Touched on the owner thread.
   nsDataHashtable<nsStringHashKey, DOMHighResTimeStamp> mTimerRegistry;
   nsDataHashtable<nsStringHashKey, uint32_t> mCounterRegistry;
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -180,17 +180,17 @@ EventSource::Close()
   mReadyState = CLOSED;
 }
 
 nsresult
 EventSource::Init(nsISupports* aOwner,
                   const nsAString& aURL,
                   bool aWithCredentials)
 {
-  if (mReadyState != CONNECTING || !PrefEnabled()) {
+  if (mReadyState != CONNECTING) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aOwner);
   NS_ENSURE_STATE(sgo);
   // XXXbz why are we checking this?  This doesn't match anything in the spec.
   nsCOMPtr<nsIScriptContext> scriptContext = sgo->GetContext();
   NS_ENSURE_STATE(scriptContext);
@@ -567,23 +567,16 @@ EventSource::GetInterface(const nsIID & 
     }
 
     return wwatch->GetPrompt(window, aIID, aResult);
   }
 
   return QueryInterface(aIID, aResult);
 }
 
-// static
-bool
-EventSource::PrefEnabled(JSContext* aCx, JSObject* aGlobal)
-{
-  return Preferences::GetBool("dom.server-events.enabled", false);
-}
-
 nsresult
 EventSource::GetBaseURI(nsIURI **aBaseURI)
 {
   NS_ENSURE_ARG_POINTER(aBaseURI);
 
   *aBaseURI = nullptr;
 
   nsCOMPtr<nsIURI> baseURI;
--- a/dom/base/EventSource.h
+++ b/dom/base/EventSource.h
@@ -88,19 +88,16 @@ public:
     return mReadyState;
   }
 
   IMPL_EVENT_HANDLER(open)
   IMPL_EVENT_HANDLER(message)
   IMPL_EVENT_HANDLER(error)
   void Close();
 
-  // Determine if preferences allow EventSource
-  static bool PrefEnabled(JSContext* aCx = nullptr, JSObject* aGlobal = nullptr);
-
   virtual void DisconnectFromOwner() override;
 
 protected:
   virtual ~EventSource();
 
   nsresult Init(nsISupports* aOwner,
                 const nsAString& aURL,
                 bool aWithCredentials);
--- a/dom/base/File.cpp
+++ b/dom/base/File.cpp
@@ -861,53 +861,43 @@ BlobImplFile::GetSize(ErrorResult& aRv)
     mLength = fileSize;
   }
 
   return mLength;
 }
 
 namespace {
 
-class GetTypeRunnable final : public Runnable
+class GetTypeRunnable final : public WorkerMainThreadRunnable
 {
 public:
   GetTypeRunnable(WorkerPrivate* aWorkerPrivate,
-                  nsIEventTarget* aSyncLoopTarget,
                   BlobImpl* aBlobImpl)
-    : mWorkerPrivate(aWorkerPrivate)
-    , mSyncLoopTarget(aSyncLoopTarget)
+    : WorkerMainThreadRunnable(aWorkerPrivate,
+                               NS_LITERAL_CSTRING("BlobImplFile :: GetType"))
     , mBlobImpl(aBlobImpl)
   {
-    MOZ_ASSERT(aWorkerPrivate);
-    MOZ_ASSERT(aSyncLoopTarget);
     MOZ_ASSERT(aBlobImpl);
     aWorkerPrivate->AssertIsOnWorkerThread();
   }
 
-  NS_IMETHOD
-  Run() override
+  bool
+  MainThreadRun() override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     nsAutoString type;
     mBlobImpl->GetType(type);
-
-    RefPtr<MainThreadStopSyncLoopRunnable> runnable =
-      new MainThreadStopSyncLoopRunnable(mWorkerPrivate,
-                                         mSyncLoopTarget.forget(), true);
-    NS_WARN_IF(!runnable->Dispatch());
-    return NS_OK;
+    return true;
   }
 
 private:
   ~GetTypeRunnable()
   {}
 
-  WorkerPrivate* mWorkerPrivate;
-  nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
   RefPtr<BlobImpl> mBlobImpl;
 };
 
 } // anonymous namespace
 
 void
 BlobImplFile::GetType(nsAString& aType)
 {
@@ -920,24 +910,22 @@ BlobImplFile::GetType(nsAString& aType)
     if (!NS_IsMainThread()) {
       WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
       if (!workerPrivate) {
         // I have no idea in which thread this method is called. We cannot
         // return any valid value.
         return;
       }
 
-      AutoSyncLoopHolder syncLoop(workerPrivate);
+      RefPtr<GetTypeRunnable> runnable =
+        new GetTypeRunnable(workerPrivate, this);
 
-      RefPtr<GetTypeRunnable> runnable =
-        new GetTypeRunnable(workerPrivate, syncLoop.EventTarget(), this);
-      nsresult rv = NS_DispatchToMainThread(runnable);
-      NS_WARN_IF(NS_FAILED(rv));
-
-      NS_WARN_IF(!syncLoop.Run());
+      ErrorResult rv;
+      runnable->Dispatch(rv);
+      NS_WARN_IF(rv.Failed());
       return;
     }
 
     nsresult rv;
     nsCOMPtr<nsIMIMEService> mimeService =
       do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return;
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -282,17 +282,18 @@ namespace {
 class PrintErrorOnConsoleRunnable final : public WorkerMainThreadRunnable
 {
 public:
   PrintErrorOnConsoleRunnable(WebSocketImpl* aImpl,
                               const char* aBundleURI,
                               const char16_t* aError,
                               const char16_t** aFormatStrings,
                               uint32_t aFormatStringsLen)
-    : WorkerMainThreadRunnable(aImpl->mWorkerPrivate)
+    : WorkerMainThreadRunnable(aImpl->mWorkerPrivate,
+                               NS_LITERAL_CSTRING("WebSocket :: print error on console"))
     , mImpl(aImpl)
     , mBundleURI(aBundleURI)
     , mError(aError)
     , mFormatStrings(aFormatStrings)
     , mFormatStringsLen(aFormatStringsLen)
   { }
 
   bool MainThreadRun() override
@@ -567,17 +568,18 @@ WebSocketImpl::FailConnection(uint16_t a
 }
 
 namespace {
 
 class DisconnectInternalRunnable final : public WorkerMainThreadRunnable
 {
 public:
   explicit DisconnectInternalRunnable(WebSocketImpl* aImpl)
-    : WorkerMainThreadRunnable(aImpl->mWorkerPrivate)
+    : WorkerMainThreadRunnable(aImpl->mWorkerPrivate,
+                               NS_LITERAL_CSTRING("WebSocket :: disconnect"))
     , mImpl(aImpl)
   { }
 
   bool MainThreadRun() override
   {
     mImpl->DisconnectInternal();
     return true;
   }
@@ -985,18 +987,19 @@ public:
 
 private:
   JSContext* mCx;
 };
 
 class WebSocketMainThreadRunnable : public WorkerMainThreadRunnable
 {
 public:
-  WebSocketMainThreadRunnable(WorkerPrivate* aWorkerPrivate)
-    : WorkerMainThreadRunnable(aWorkerPrivate)
+  WebSocketMainThreadRunnable(WorkerPrivate* aWorkerPrivate,
+                              const nsACString& aTelemetryKey)
+    : WorkerMainThreadRunnable(aWorkerPrivate, aTelemetryKey)
   {
     MOZ_ASSERT(aWorkerPrivate);
     aWorkerPrivate->AssertIsOnWorkerThread();
   }
 
   bool MainThreadRun() override
   {
     AssertIsOnMainThread();
@@ -1024,17 +1027,18 @@ protected:
 class InitRunnable final : public WebSocketMainThreadRunnable
 {
 public:
   InitRunnable(WebSocketImpl* aImpl, const nsAString& aURL,
                nsTArray<nsString>& aProtocolArray,
                const nsACString& aScriptFile, uint32_t aScriptLine,
                uint32_t aScriptColumn,
                ErrorResult& aRv, bool* aConnectionFailed)
-    : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate)
+    : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate,
+                                  NS_LITERAL_CSTRING("WebSocket :: init"))
     , mImpl(aImpl)
     , mURL(aURL)
     , mProtocolArray(aProtocolArray)
     , mScriptFile(aScriptFile)
     , mScriptLine(aScriptLine)
     , mScriptColumn(aScriptColumn)
     , mRv(aRv)
     , mConnectionFailed(aConnectionFailed)
@@ -1093,17 +1097,18 @@ protected:
   ErrorResult& mRv;
   bool* mConnectionFailed;
 };
 
 class AsyncOpenRunnable final : public WebSocketMainThreadRunnable
 {
 public:
   AsyncOpenRunnable(WebSocketImpl* aImpl, ErrorResult& aRv)
-    : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate)
+    : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate,
+                                  NS_LITERAL_CSTRING("WebSocket :: AsyncOpen"))
     , mImpl(aImpl)
     , mRv(aRv)
   {
     MOZ_ASSERT(mWorkerPrivate);
     mWorkerPrivate->AssertIsOnWorkerThread();
   }
 
 protected:
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3061,47 +3061,35 @@ nsDOMWindowUtils::RemoteFrameFullscreenR
 {
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   doc->RemoteFrameFullscreenReverted();
   return NS_OK;
 }
 
-class MOZ_STACK_CLASS FullscreenChangePrepare
+static void
+PrepareForFullscreenChange(nsIPresShell* aPresShell, const nsSize& aSize,
+                           nsSize* aOldSize = nullptr)
 {
-public:
-  FullscreenChangePrepare(nsIPresShell* aPresShell,
-                          const nsSize& aSize, nsSize* aOldSize = nullptr)
-    : mPresShell(aPresShell)
-  {
-    if (mPresShell) {
-      mPresShell->SetIsInFullscreenChange(true);
-    }
-    if (aSize.IsEmpty()) {
-      return;
-    }
-    if (nsViewManager* viewManager = mPresShell->GetViewManager()) {
+  if (!aPresShell) {
+    return;
+  }
+  if (nsRefreshDriver* rd = aPresShell->GetRefreshDriver()) {
+    rd->SetIsResizeSuppressed();
+  }
+  if (!aSize.IsEmpty()) {
+    if (nsViewManager* viewManager = aPresShell->GetViewManager()) {
       if (aOldSize) {
         viewManager->GetWindowDimensions(&aOldSize->width, &aOldSize->height);
       }
       viewManager->SetWindowDimensions(aSize.width, aSize.height);
     }
   }
-
-  ~FullscreenChangePrepare()
-  {
-    if (mPresShell) {
-      mPresShell->SetIsInFullscreenChange(false);
-    }
-  }
-
-private:
-  nsCOMPtr<nsIPresShell> mPresShell;
-};
+}
 
 class OldWindowSize : public LinkedListElement<OldWindowSize>
 {
 public:
   static void Set(nsPIDOMWindowOuter* aWindow, const nsSize& aSize)
   {
     OldWindowSize* item = GetItem(aWindow);
     if (item) {
@@ -3152,53 +3140,55 @@ private:
   nsSize mSize;
 };
 
 LinkedList<OldWindowSize> OldWindowSize::sList;
 
 NS_IMETHODIMP
 nsDOMWindowUtils::HandleFullscreenRequests(bool* aRetVal)
 {
+  PROFILER_MARKER("Enter fullscreen");
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   // Notify the pres shell that we are starting fullscreen change, and
   // set the window dimensions in advance. Since the resize message
   // comes after the fullscreen change call, doing so could avoid an
   // extra resize reflow after this point.
   nsRect screenRect;
   if (nsPresContext* presContext = GetPresContext()) {
     presContext->DeviceContext()->GetRect(screenRect);
   }
   nsSize oldSize;
-  FullscreenChangePrepare prepare(GetPresShell(), screenRect.Size(), &oldSize);
+  PrepareForFullscreenChange(GetPresShell(), screenRect.Size(), &oldSize);
   OldWindowSize::Set(doc->GetWindow(), oldSize);
 
   *aRetVal = nsIDocument::HandlePendingFullscreenRequests(doc);
   return NS_OK;
 }
 
 nsresult
 nsDOMWindowUtils::ExitFullscreen()
 {
+  PROFILER_MARKER("Exit fullscreen");
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_STATE(doc);
 
   // Although we would not use the old size if we have already exited
   // fullscreen, we still want to cleanup in case we haven't.
   nsSize oldSize = OldWindowSize::GetAndRemove(doc->GetWindow());
   if (!doc->GetFullscreenElement()) {
     return NS_OK;
   }
 
   // Notify the pres shell that we are starting fullscreen change, and
   // set the window dimensions in advance. Since the resize message
   // comes after the fullscreen change call, doing so could avoid an
   // extra resize reflow after this point.
-  FullscreenChangePrepare prepare(GetPresShell(), oldSize);
+  PrepareForFullscreenChange(GetPresShell(), oldSize);
   nsIDocument::ExitFullscreenInDocTree(doc);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
                                 bool *_retval)
 {
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7,16 +7,17 @@
 #include "nsGlobalWindow.h"
 
 #include <algorithm>
 
 #include "mozilla/MemoryReporting.h"
 
 // Local Includes
 #include "Navigator.h"
+#include "nsContentSecurityManager.h"
 #include "nsScreen.h"
 #include "nsHistory.h"
 #include "nsPerformance.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsIDOMStorageManager.h"
 #include "mozilla/dom/DOMStorage.h"
 #include "mozilla/dom/StorageEvent.h"
 #include "mozilla/dom/StorageEventBinding.h"
@@ -1174,16 +1175,17 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
     mAddActiveEventFuzzTime(true),
     mIsFrozen(false),
     mFullScreen(false),
     mFullscreenMode(false),
     mIsClosed(false),
     mInClose(false),
     mHavePendingClose(false),
     mHadOriginalOpener(false),
+    mOriginalOpenerWasSecureContext(false),
     mIsPopupSpam(false),
     mBlockScriptedClosingFlag(false),
     mWasOffline(false),
     mHasHadSlowScript(false),
     mNotifyIdleObserversIdleOnThaw(false),
     mNotifyIdleObserversActiveOnThaw(false),
     mCreatingInnerWindow(false),
     mIsChrome(false),
@@ -2341,26 +2343,202 @@ InitializeLegacyNetscapeObject(JSContext
   /* Define PrivilegeManager object with the necessary "static" methods. */
   obj = JS_DefineObject(aCx, obj, "PrivilegeManager", nullptr);
   NS_ENSURE_TRUE(obj, false);
 
   return JS_DefineFunctions(aCx, obj, EnablePrivilegeSpec);
 }
 
 /**
+ * Returns true if the "HTTPS state" of the document should be "modern". See:
+ *
+ * https://html.spec.whatwg.org/#concept-document-https-state
+ * https://fetch.spec.whatwg.org/#concept-response-https-state
+ *
+ * Note: this function only relates to figuring out HTTPS state, which is an
+ * input to the Secure Context algorithm.  We are not actually implementing any
+ * part of the Secure Context algorithm itself here.
+ *
+ * This is a bit of a hack.  Ideally we'd propagate HTTPS state through
+ * nsIChannel as described in the Fetch and HTML specs, but making channels
+ * know about whether they should inherit HTTPS state, propagating information
+ * about who the channel's "client" is, exposing GetHttpsState API on channels
+ * and modifying the various cache implementations to store and retrieve HTTPS
+ * state involves a huge amount of code (see bug 1220687).  We avoid that for
+ * now using this function.
+ *
+ * This function takes advantage of the observation that we can return true if
+ * nsIContentSecurityManager::IsOriginPotentiallyTrustworthy returns true for
+ * the document's origin (e.g. the origin has a scheme of 'https' or host
+ * 'localhost' etc.).  Since we generally propagate a creator document's origin
+ * onto data:, blob:, etc. documents, this works for them too.
+ *
+ * The scenario where this observation breaks down is sandboxing without the
+ * 'allow-same-origin' flag, since in this case a document is given a unique
+ * origin (IsOriginPotentiallyTrustworthy would return false).  We handle that
+ * by using the origin that the document would have had had it not been
+ * sandboxed.
+ *
+ * DEFICIENCIES: Note that this function uses nsIScriptSecurityManager's
+ * getChannelResultPrincipalIfNotSandboxed, and that method's ignoring of
+ * sandboxing is limited to the immediate sandbox.  In the case that aDocument
+ * should inherit its origin (e.g. data: URI) but its parent has ended up
+ * with a unique origin due to sandboxing further up the parent chain we may
+ * end up returning false when we would ideally return true (since we will
+ * examine the parent's origin for 'https' and not finding it.)  This means
+ * that we may restrict the privileges of some pages unnecessarily in this
+ * edge case.
+ */
+static bool HttpsStateIsModern(nsIDocument* aDocument)
+{
+  nsCOMPtr<nsIPrincipal> principal = aDocument->NodePrincipal();
+
+  if (principal->GetIsSystemPrincipal()) {
+    return true;
+  }
+
+  // If aDocument is sandboxed, try and get the principal that it would have
+  // been given had it not been sandboxed:
+  if (principal->GetIsNullPrincipal() &&
+      (aDocument->GetSandboxFlags() & SANDBOXED_ORIGIN)) {
+    nsIChannel* channel = aDocument->GetChannel();
+    if (channel) {
+      nsCOMPtr<nsIScriptSecurityManager> ssm =
+        nsContentUtils::GetSecurityManager();
+      nsresult rv =
+        ssm->GetChannelResultPrincipalIfNotSandboxed(channel,
+                                                     getter_AddRefs(principal));
+      if (NS_FAILED(rv)) {
+        return false;
+      }
+      if (principal->GetIsSystemPrincipal()) {
+        // If a document with the system principal is sandboxing a subdocument
+        // that would normally inherit the embedding element's principal (e.g.
+        // a srcdoc document) then the embedding document does not trust the
+        // content that is written to the embedded document.  Unlike when the
+        // embedding document is https, in this case we have no indication as
+        // to whether the embedded document's contents are delivered securely
+        // or not, and the sandboxing would possibly indicate that they were
+        // not.  To play it safe we return false here.  (See bug 1162772
+        // comment 73-80.)
+        return false;
+      }
+    }
+  }
+
+  if (principal->GetIsNullPrincipal()) {
+    return false;
+  }
+
+  MOZ_ASSERT(principal->GetIsCodebasePrincipal());
+
+  nsCOMPtr<nsIContentSecurityManager> csm =
+    do_GetService(NS_CONTENTSECURITYMANAGER_CONTRACTID);
+  NS_WARN_IF(!csm);
+  if (csm) {
+    bool isTrustworthyOrigin = false;
+    csm->IsOriginPotentiallyTrustworthy(principal, &isTrustworthyOrigin);
+    if (isTrustworthyOrigin) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool
+nsGlobalWindow::ComputeIsSecureContext(nsIDocument* aDocument)
+{
+  MOZ_ASSERT(IsOuterWindow());
+
+  nsCOMPtr<nsIPrincipal> principal = aDocument->NodePrincipal();
+  if (nsContentUtils::IsSystemPrincipal(principal)) {
+    return true;
+  }
+
+  // Implement https://w3c.github.io/webappsec-secure-contexts/#settings-object
+
+  bool hadNonSecureContextCreator = false;
+
+  nsPIDOMWindowOuter* parentOuterWin = GetScriptableParent();
+  MOZ_ASSERT(parentOuterWin, "How can we get here? No docShell somehow?");
+  if (nsGlobalWindow::Cast(parentOuterWin) != this) {
+    // There may be a small chance that parentOuterWin has navigated in
+    // the time that it took us to start loading this sub-document.  If that
+    // were the case then parentOuterWin->GetCurrentInnerWindow() wouldn't
+    // return the window for the document that is embedding us.  For this
+    // reason we only use the GetScriptableParent call above to check that we
+    // have a same-type parent, but actually get the inner window via the
+    // document that we know is embedding us.
+    nsIDocument* creatorDoc = aDocument->GetParentDocument();
+    if (!creatorDoc) {
+      return false; // we must be tearing down
+    }
+    nsGlobalWindow* parentWin =
+      nsGlobalWindow::Cast(creatorDoc->GetInnerWindow());
+    if (!parentWin) {
+      return false; // we must be tearing down
+    }
+    MOZ_ASSERT(parentWin ==
+               nsGlobalWindow::Cast(parentOuterWin->GetCurrentInnerWindow()),
+               "Creator window mismatch while setting Secure Context state");
+    hadNonSecureContextCreator = !parentWin->IsSecureContext();
+  } else if (mHadOriginalOpener) {
+    hadNonSecureContextCreator = !mOriginalOpenerWasSecureContext;
+  }
+
+  if (hadNonSecureContextCreator) {
+    return false;
+  }
+
+  if (HttpsStateIsModern(aDocument)) {
+    return true;
+  }
+
+  if (principal->GetIsNullPrincipal()) {
+    nsCOMPtr<nsIURI> uri = aDocument->GetOriginalURI();
+    // IsOriginPotentiallyTrustworthy doesn't care about origin attributes so
+    // it doesn't actually matter what we use here, but reusing the document
+    // principal's attributes is convenient.
+    const PrincipalOriginAttributes& attrs =
+      BasePrincipal::Cast(principal)->OriginAttributesRef();
+    // CreateCodebasePrincipal correctly gets a useful principal for blob: and
+    // other URI_INHERITS_SECURITY_CONTEXT URIs.
+    principal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
+    if (NS_WARN_IF(!principal)) {
+      return false;
+    }
+  }
+
+  nsCOMPtr<nsIContentSecurityManager> csm =
+    do_GetService(NS_CONTENTSECURITYMANAGER_CONTRACTID);
+  NS_WARN_IF(!csm);
+  if (csm) {
+    bool isTrustworthyOrigin = false;
+    csm->IsOriginPotentiallyTrustworthy(principal, &isTrustworthyOrigin);
+    if (isTrustworthyOrigin) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/**
  * Create a new global object that will be used for an inner window.
  * Return the native global and an nsISupports 'holder' that can be used
  * to manage the lifetime of it.
  */
 static nsresult
 CreateNativeGlobalForInner(JSContext* aCx,
                            nsGlobalWindow* aNewInner,
                            nsIURI* aURI,
                            nsIPrincipal* aPrincipal,
-                           JS::MutableHandle<JSObject*> aGlobal)
+                           JS::MutableHandle<JSObject*> aGlobal,
+                           bool aIsSecureContext)
 {
   MOZ_ASSERT(aCx);
   MOZ_ASSERT(aNewInner);
   MOZ_ASSERT(aNewInner->IsInnerWindow());
   MOZ_ASSERT(aPrincipal);
 
   // DOMWindow with nsEP is not supported, we have to make sure
   // no one creates one accidentally.
@@ -2380,16 +2558,18 @@ CreateNativeGlobalForInner(JSContext* aC
   if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
     options.creationOptions().setAddonId(MapURIToAddonID(aURI));
   }
 
   if (top && top->GetGlobalJSObject()) {
     options.creationOptions().setSameZoneAs(top->GetGlobalJSObject());
   }
 
+  options.creationOptions().setSecureContext(aIsSecureContext);
+
   xpc::InitGlobalObjectOptions(options, aPrincipal);
 
   // Determine if we need the Components object.
   bool needComponents = nsContentUtils::IsSystemPrincipal(aPrincipal) ||
                         TreatAsRemoteXUL(aPrincipal);
   uint32_t flags = needComponents ? 0 : nsIXPConnect::OMIT_COMPONENTS_OBJECT;
   flags |= nsIXPConnect::DONT_FIRE_ONNEWGLOBALHOOK;
 
@@ -2598,17 +2778,18 @@ nsGlobalWindow::SetNewDocument(nsIDocume
 
       Freeze();
       mCreatingInnerWindow = true;
       // Every script context we are initialized with must create a
       // new global.
       rv = CreateNativeGlobalForInner(cx, newInnerWindow,
                                       aDocument->GetDocumentURI(),
                                       aDocument->NodePrincipal(),
-                                      &newInnerGlobal);
+                                      &newInnerGlobal,
+                                      ComputeIsSecureContext(aDocument));
       NS_ASSERTION(NS_SUCCEEDED(rv) && newInnerGlobal &&
                    newInnerWindow->GetWrapperPreserveColor() == newInnerGlobal,
                    "Failed to get script global");
 
       mCreatingInnerWindow = false;
       createdInnerWindow = true;
       Thaw();
 
@@ -3039,17 +3220,21 @@ nsGlobalWindow::SetOpenerWindow(nsPIDOMW
                "SetOpenerWindow!");
   NS_ASSERTION(aOpener || !aOriginalOpener,
                "Shouldn't set mHadOriginalOpener if aOpener is null");
 
   mOpener = do_GetWeakReference(aOpener);
   NS_ASSERTION(mOpener || !aOpener, "Opener must support weak references!");
 
   if (aOriginalOpener) {
+    MOZ_ASSERT(!mHadOriginalOpener,
+               "Probably too late to call ComputeIsSecureContext again");
     mHadOriginalOpener = true;
+    mOriginalOpenerWasSecureContext =
+      nsGlobalWindow::Cast(aOpener->GetCurrentInnerWindow())->IsSecureContext();
   }
 
 #ifdef DEBUG
   mSetOpenerWindowCalled = true;
 #endif
 }
 
 static
@@ -3372,16 +3557,17 @@ nsGlobalWindow::PostHandleEvent(EventCha
     if (element && GetParentInternal() &&
         docShell && docShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
       // If we're not in chrome, or at a chrome boundary, fire the
       // onload event for the frame element.
 
       nsEventStatus status = nsEventStatus_eIgnore;
       WidgetEvent event(aVisitor.mEvent->IsTrusted(), eLoad);
       event.mFlags.mBubbles = false;
+      event.mFlags.mCancelable = false;
 
       // Most of the time we could get a pres context to pass in here,
       // but not always (i.e. if this window is not shown there won't
       // be a pres context available). Since we're not firing a GUI
       // event we don't need a pres context anyway so we just pass
       // null as the pres context all the time here.
       EventDispatcher::Dispatch(element, nullptr, &event, nullptr, &status);
     }
@@ -5979,28 +6165,51 @@ public:
   NS_IMETHOD Run() override;
 
 private:
   virtual ~FullscreenTransitionTask()
   {
     MOZ_COUNT_DTOR(FullscreenTransitionTask);
   }
 
+  /**
+   * The flow of fullscreen transition:
+   *
+   *         parent process         |         child process
+   * ----------------------------------------------------------------
+   *
+   *                                    | request/exit fullscreen
+   *                              <-----|
+   *         BeforeToggle stage |
+   *                            |
+   *  ToggleFullscreen stage *1 |----->
+   *                                    | HandleFullscreenRequests
+   *                                    |
+   *                              <-----| MozAfterPaint event
+   *       AfterToggle stage *2 |
+   *                            |
+   *                  End stage |
+   *
+   * Note we also start a timer at *1 so that if we don't get MozAfterPaint
+   * from the child process in time, we continue going to *2.
+   */
   enum Stage {
     // BeforeToggle stage happens before we enter or leave fullscreen
     // state. In this stage, the task triggers the pre-toggle fullscreen
     // transition on the widget.
     eBeforeToggle,
     // ToggleFullscreen stage actually executes the fullscreen toggle,
     // and wait for the next paint on the content to continue.
     eToggleFullscreen,
     // AfterToggle stage happens after we toggle the fullscreen state.
     // In this stage, the task triggers the post-toggle fullscreen
     // transition on the widget.
-    eAfterToggle
+    eAfterToggle,
+    // End stage is triggered after the final transition finishes.
+    eEnd
   };
 
   class Observer final : public nsIObserver
   {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
 
@@ -6036,20 +6245,22 @@ FullscreenTransitionTask::Run()
   mStage = Stage(mStage + 1);
   if (MOZ_UNLIKELY(mWidget->Destroyed())) {
     // If the widget has been destroyed before we get here, don't try to
     // do anything more. Just let it go and release ourselves.
     NS_WARNING("The widget to fullscreen has been destroyed");
     return NS_OK;
   }
   if (stage == eBeforeToggle) {
+    PROFILER_MARKER("Fullscreen transition start");
     mWidget->PerformFullscreenTransition(nsIWidget::eBeforeFullscreenToggle,
                                          mDuration.mFadeIn, mTransitionData,
                                          this);
   } else if (stage == eToggleFullscreen) {
+    PROFILER_MARKER("Fullscreen toggle start");
     if (MOZ_UNLIKELY(mWindow->mFullScreen != mFullscreen)) {
       // This could happen in theory if several fullscreen requests in
       // different direction happen continuously in a short time. We
       // need to ensure the fullscreen state matches our target here,
       // otherwise the widget would change the window state as if we
       // toggle for Fullscreen Mode instead of Fullscreen API.
       NS_WARNING("The fullscreen state of the window does not match");
       mWindow->mFullScreen = mFullscreen;
@@ -6079,16 +6290,18 @@ FullscreenTransitionTask::Run()
     mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
     uint32_t timeout =
       Preferences::GetUint("full-screen-api.transition.timeout", 500);
     mTimer->Init(observer, timeout, nsITimer::TYPE_ONE_SHOT);
   } else if (stage == eAfterToggle) {
     mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle,
                                          mDuration.mFadeOut, mTransitionData,
                                          this);
+  } else if (stage == eEnd) {
+    PROFILER_MARKER("Fullscreen transition end");
   }
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(FullscreenTransitionTask::Observer, nsIObserver)
 
 NS_IMETHODIMP
 FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject,
@@ -6099,26 +6312,28 @@ FullscreenTransitionTask::Observer::Obse
   if (strcmp(aTopic, FullscreenTransitionTask::kPaintedTopic) == 0) {
     nsCOMPtr<nsPIDOMWindowInner> win(do_QueryInterface(aSubject));
     nsCOMPtr<nsIWidget> widget = win ?
       nsGlobalWindow::Cast(win)->GetMainWidget() : nullptr;
     if (widget == mTask->mWidget) {
       // The paint notification arrives first. Cancel the timer.
       mTask->mTimer->Cancel();
       shouldContinue = true;
+      PROFILER_MARKER("Fullscreen toggle end");
     }
   } else {
 #ifdef DEBUG
     MOZ_ASSERT(strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC) == 0,
                "Should only get fullscreen-painted or timer-callback");
     nsCOMPtr<nsITimer> timer(do_QueryInterface(aSubject));
     MOZ_ASSERT(timer && timer == mTask->mTimer,
                "Should only trigger this with the timer the task created");
 #endif
     shouldContinue = true;
+    PROFILER_MARKER("Fullscreen toggle timeout");
   }
   if (shouldContinue) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     obs->RemoveObserver(this, kPaintedTopic);
     mTask->mTimer = nullptr;
     mTask->Run();
   }
   return NS_OK;
@@ -6241,38 +6456,41 @@ nsGlobalWindow::SetFullscreenInternal(Fu
     if (MakeWidgetFullscreen(this, aHMD, aReason, aFullScreen)) {
       // The rest of code for switching fullscreen is in nsGlobalWindow::
       // FinishFullscreenChange() which will be called after sizemodechange
       // event is dispatched.
       return NS_OK;
     }
   }
 
-  // If we didn't setup the widget, we may need to manually set this
-  // flag, or the assertion in FinishFullscreenChange is violated.
-  if (nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell()) {
-    if (!presShell->IsInFullscreenChange()) {
-      presShell->SetIsInFullscreenChange(true);
-    }
-  }
   FinishFullscreenChange(aFullScreen);
   return NS_OK;
 }
 
 bool
 nsGlobalWindow::SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
                                     nsIWidget* aWidget, nsIScreen* aScreen)
 {
   MOZ_ASSERT(IsOuterWindow());
   MOZ_ASSERT(this == GetTopInternal(), "Only topmost window should call this");
   MOZ_ASSERT(!AsOuter()->GetFrameElementInternal(), "Content window should not call this");
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
 
-  if (nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell()) {
-    presShell->SetIsInFullscreenChange(true);
+  if (!NS_WARN_IF(!IsChromeWindow())) {
+    auto chromeWin = static_cast<nsGlobalChromeWindow*>(this);
+    if (!NS_WARN_IF(chromeWin->mFullscreenPresShell)) {
+      if (nsIPresShell* shell = mDocShell->GetPresShell()) {
+        if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
+          chromeWin->mFullscreenPresShell = do_GetWeakReference(shell);
+          MOZ_ASSERT(chromeWin->mFullscreenPresShell);
+          rd->SetIsResizeSuppressed();
+          rd->Freeze();
+        }
+      }
+    }
   }
   nsresult rv = aReason == FullscreenReason::ForFullscreenMode ?
     // If we enter fullscreen for fullscreen mode, we want
     // the native system behavior.
     aWidget->MakeFullScreenWithNativeTransition(aIsFullscreen, aScreen) :
     aWidget->MakeFullScreen(aIsFullscreen, aScreen);
   return NS_SUCCEEDED(rv);
 }
@@ -6304,19 +6522,25 @@ nsGlobalWindow::FinishFullscreenChange(b
   // that the chrome can distinguish between browser fullscreen mode
   // and DOM fullscreen.
   FinishDOMFullscreenChange(mDoc, mFullScreen);
 
   // dispatch a "fullscreen" DOM event so that XUL apps can
   // respond visually if we are kicked into full screen mode
   DispatchCustomEvent(NS_LITERAL_STRING("fullscreen"));
 
-  if (nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell()) {
-    MOZ_ASSERT(presShell->IsInFullscreenChange());
-    presShell->SetIsInFullscreenChange(false);
+  if (!NS_WARN_IF(!IsChromeWindow())) {
+    auto chromeWin = static_cast<nsGlobalChromeWindow*>(this);
+    if (nsCOMPtr<nsIPresShell> shell =
+        do_QueryReferent(chromeWin->mFullscreenPresShell)) {
+      if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
+        rd->Thaw();
+      }
+      chromeWin->mFullscreenPresShell = nullptr;
+    }
   }
 
   if (!mWakeLock && mFullScreen) {
     RefPtr<power::PowerManagerService> pmService =
       power::PowerManagerService::GetInstance();
     if (!pmService) {
       return;
     }
@@ -13870,16 +14094,24 @@ nsGlobalWindow::GetConsole(ErrorResult& 
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
   }
 
   return mConsole;
 }
 
+bool
+nsGlobalWindow::IsSecureContext() const
+{
+  MOZ_RELEASE_ASSERT(IsInnerWindow());
+
+  return JS_GetIsSecureContext(js::GetObjectCompartment(GetWrapperPreserveColor()));
+}
+
 already_AddRefed<External>
 nsGlobalWindow::GetExternal(ErrorResult& aRv)
 {
   MOZ_RELEASE_ASSERT(IsInnerWindow());
 
 #ifdef HAVE_SIDEBAR
   if (!mExternal) {
     AutoJSContext cx;
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -919,16 +919,19 @@ public:
   already_AddRefed<nsIDOMOfflineResourceList> GetApplicationCache() override;
 
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
   int16_t Orientation() const;
 #endif
 
   mozilla::dom::Console* GetConsole(mozilla::ErrorResult& aRv);
 
+  // https://w3c.github.io/webappsec-secure-contexts/#dom-window-issecurecontext
+  bool IsSecureContext() const;
+
   void GetSidebar(mozilla::dom::OwningExternalOrWindowProxy& aResult,
                   mozilla::ErrorResult& aRv);
   already_AddRefed<mozilla::dom::External> GetExternal(mozilla::ErrorResult& aRv);
 
   // Exposed only for testing
   static bool
   TokenizeDialogOptions(nsAString& aToken, nsAString::const_iterator& aIter,
                         nsAString::const_iterator aEnd);
@@ -1659,16 +1662,20 @@ protected:
   void CheckForDPIChange();
 
 private:
   // Fire the JS engine's onNewGlobalObject hook.  Only used on inner windows.
   void FireOnNewGlobalObject();
 
   void DisconnectEventTargetObjects();
 
+  // Called only on outer windows to compute the value that will be returned by
+  // IsSecureContext() for the inner window that corresponds to aDocument.
+  bool ComputeIsSecureContext(nsIDocument* aDocument);
+
 protected:
   // This member is also used on both inner and outer windows, but
   // for slightly different purposes. On inner windows it means the
   // inner window is held onto by session history and should not
   // change. On outer windows it means that the window is in a state
   // where we don't want to force creation of a new inner window since
   // we're in the middle of doing just that.
   bool                          mIsFrozen : 1;
@@ -1679,16 +1686,17 @@ protected:
   bool                          mFullscreenMode : 1;
   bool                          mIsClosed : 1;
   bool                          mInClose : 1;
   // mHavePendingClose means we've got a termination function set to
   // close us when the JS stops executing or that we have a close
   // event posted.  If this is set, just ignore window.close() calls.
   bool                          mHavePendingClose : 1;
   bool                          mHadOriginalOpener : 1;
+  bool                          mOriginalOpenerWasSecureContext : 1;
   bool                          mIsPopupSpam : 1;
 
   // Indicates whether scripts are allowed to close this window.
   bool                          mBlockScriptedClosingFlag : 1;
 
   // Window offline status. Checked to see if we need to fire offline event
   bool                          mWasOffline : 1;
 
@@ -1966,16 +1974,20 @@ public:
   using nsGlobalWindow::NotifyDefaultButtonLoaded;
   using nsGlobalWindow::GetMessageManager;
   using nsGlobalWindow::GetGroupMessageManager;
   using nsGlobalWindow::BeginWindowMove;
 
   nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
   nsCOMPtr<nsIMessageBroadcaster> mMessageManager;
   nsInterfaceHashtable<nsStringHashKey, nsIMessageBroadcaster> mGroupMessageManagers;
+  // A weak pointer to the nsPresShell that we are doing fullscreen for.
+  // The pointer being set indicates we've set the IsInFullscreenChange
+  // flag on this pres shell.
+  nsWeakPtr mFullscreenPresShell;
 };
 
 /*
  * nsGlobalModalWindow inherits from nsGlobalWindow. It is the global
  * object created for a modal content windows only (i.e. not modal
  * chrome dialogs).
  */
 class nsGlobalModalWindow : public nsGlobalWindow,
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -6,16 +6,17 @@
 /*
  * A base class implementing nsIObjectLoadingContent for use by
  * various content nodes that want to provide plugin/document/image
  * loading functionality (eg <embed>, <object>, <applet>, etc).
  */
 
 // Interface headers
 #include "imgLoader.h"
+#include "nsIConsoleService.h"
 #include "nsIContent.h"
 #include "nsIContentInlines.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMCustomEvent.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLAppletElement.h"
@@ -81,16 +82,18 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/PluginCrashedEvent.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
+#include "mozilla/dom/HTMLSharedObjectElement.h"
+#include "nsChannelClassifier.h"
 
 #ifdef XP_WIN
 // Thanks so much, Microsoft! :(
 #ifdef CreateEvent
 #undef CreateEvent
 #endif
 #endif // XP_WIN
 
@@ -100,16 +103,17 @@
 // maybe on nsIObjectLoadingContext.
 #include "mozilla/dom/HTMLObjectElement.h"
 #endif
 
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 static const char *kPrefJavaMIME = "plugin.java.mime";
 static const char *kPrefYoutubeRewrite = "plugins.rewrite_youtube_embeds";
+static const char *kPrefBlockURIs = "browser.safebrowsing.blockedURIs.enabled";
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static LogModule*
 GetObjectLog()
 {
   static LazyLogModule sLog("objlc");
@@ -1148,30 +1152,16 @@ nsObjectLoadingContent::OnStopRequest(ns
   // We make a note of this object node by including it in a dedicated
   // array of blocked tracking nodes under its parent document.
   if (aStatusCode == NS_ERROR_TRACKING_URI) {
     nsCOMPtr<nsIContent> thisNode =
       do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
     if (thisNode && thisNode->IsInComposedDoc()) {
       thisNode->GetComposedDoc()->AddBlockedTrackingNode(thisNode);
     }
-  } else if (aStatusCode == NS_ERROR_BLOCKED_URI) {
-    // Logging is temporarily disabled until after experiment phase.
-    //
-    // nsAutoCString uri;
-    // mURI->GetSpec(uri);
-    // nsCOMPtr<nsIConsoleService> console(
-    //   do_GetService("@mozilla.org/consoleservice;1"));
-    // if (console) {
-    //   nsString message = NS_LITERAL_STRING("Blocking ") +
-    //     NS_ConvertASCIItoUTF16(uri) +
-    //     NS_LITERAL_STRING(" since it was found on an internal Firefox blocklist.");
-    //   console->LogStringMessage(message.get());
-    // }
-    Telemetry::Accumulate(Telemetry::PLUGIN_BLOCKED_FOR_STABILITY, 1);
   }
 
   NS_ENSURE_TRUE(nsContentUtils::LegacyIsCallerChromeOrNativeCode(), NS_ERROR_NOT_AVAILABLE);
 
   if (aRequest != mChannel) {
     return NS_BINDING_ABORTED;
   }
 
@@ -2281,16 +2271,42 @@ nsObjectLoadingContent::LoadObject(bool 
     }
     // If we're loading a type now, check ProcessPolicy. Note that we may check
     // both now in the case of plugins whose type is determined before opening a
     // channel.
     if (allowLoad && mType != eType_Loading) {
       allowLoad = CheckProcessPolicy(&contentPolicy);
     }
 
+    // This needs to be reverted once the plugin stability experiment is over (see bug #1268120).
+    if (allowLoad && Preferences::GetBool(kPrefBlockURIs)) {
+      RefPtr<nsChannelClassifier> channelClassifier = new nsChannelClassifier();
+      nsCOMPtr<nsIURIClassifier> classifier = do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID);
+      if (classifier) {
+        nsAutoCString tables;
+        Preferences::GetCString("urlclassifier.blockedTable", &tables);
+        nsAutoCString results;
+        rv = classifier->ClassifyLocalWithTables(mURI, tables, results);
+        if (NS_SUCCEEDED(rv) && !results.IsEmpty()) {
+          nsAutoCString uri;
+          mURI->GetSpec(uri);
+          nsCOMPtr<nsIConsoleService> console(
+            do_GetService("@mozilla.org/consoleservice;1"));
+          if (console) {
+            nsString message = NS_LITERAL_STRING("Blocking ") +
+              NS_ConvertASCIItoUTF16(uri) +
+              NS_LITERAL_STRING(" since it was found on an internal Firefox blocklist.");
+            console->LogStringMessage(message.get());
+          }
+          Telemetry::Accumulate(Telemetry::PLUGIN_BLOCKED_FOR_STABILITY, 1);
+          allowLoad = false;
+        }
+      }
+    }
+
     // Content policy implementations can mutate the DOM, check for re-entry
     if (!mIsLoading) {
       LOG(("OBJLC [%p]: We re-entered in content policy, leaving original load",
            this));
       return NS_OK;
     }
 
     // Load denied, switch to fallback and set disabled/suppressed if applicable
@@ -3088,34 +3104,45 @@ nsObjectLoadingContent::LoadFallback(Fal
   NS_ASSERTION(thisContent, "must be a content");
 
   if (!thisContent->IsHTMLElement() || mContentType.IsEmpty()) {
     // Don't let custom fallback handlers run outside HTML, tags without a
     // determined type should always just be alternate content
     aType = eFallbackAlternate;
   }
 
+  // We'll set this to null no matter what now, doing it here means we'll load
+  // child embeds as we find them in the upcoming loop.
+  mType = eType_Null;
+
+  // Do a breadth-first traverse of node tree with the current element as root,
+  // looking for the first embed we can find.
+  nsTArray<nsINodeList*> childNodes;
   if ((thisContent->IsHTMLElement(nsGkAtoms::object) ||
        thisContent->IsHTMLElement(nsGkAtoms::applet)) &&
       (aType == eFallbackUnsupported ||
        aType == eFallbackDisabled ||
        aType == eFallbackBlocklisted))
   {
-    // Show alternate content instead, if it exists
-    for (nsIContent* child = thisContent->GetFirstChild();
-         child; child = child->GetNextSibling()) {
-      if (!child->IsHTMLElement(nsGkAtoms::param) &&
+    for (nsIContent* child = thisContent->GetFirstChild(); child;
+         child = child->GetNextNode(thisContent)) {
+      if (aType != eFallbackAlternate &&
+          !child->IsHTMLElement(nsGkAtoms::param) &&
           nsStyleUtil::IsSignificantChild(child, true, false)) {
         aType = eFallbackAlternate;
-        break;
+      }
+      if (child->IsHTMLElement(nsGkAtoms::embed)) {
+        HTMLSharedObjectElement* object = static_cast<HTMLSharedObjectElement*>(child);
+        if (object) {
+          object->StartObjectLoad(true, true);
+        }
       }
     }
   }
 
-  mType = eType_Null;
   mFallbackType = aType;
 
   // Notify
   if (!aNotify) {
     return; // done
   }
 
   NotifyStateChanged(oldType, oldState, false, true);
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_bug1263696_frame_fail.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/REC-html401-19991224/strict.dtd">
+<html>
+ <head>
+  <title>Bug 1263696 - iframe that should not be loaded</title>
+ </head>
+ <body>
+   <script>
+    parent.SimpleTest.ok(false, "this iframe should not load");
+   </script>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_bug1263696_frame_pass.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/REC-html401-19991224/strict.dtd">
+<html>
+ <head>
+  <title>Bug 1263696 - iframe that should be loaded</title>
+ </head>
+ <body>
+   <script>
+    parent.index = parent.index + 1;
+    parent.SimpleTest.ok(true, "this iframe should load");
+   </script>
+ </body>
+</html>
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -152,16 +152,18 @@ support-files =
   file_bug787778.sjs
   file_bug804395.jar
   file_bug869432.eventsource
   file_bug869432.eventsource^headers^
   file_bug902350.html
   file_bug902350_frame.html
   file_bug907892.html
   file_bug945152.jar
+  file_bug1263696_frame_pass.html
+  file_bug1263696_frame_fail.html
   file_general_document.html
   file_html_in_xhr.html
   file_html_in_xhr.sjs
   file_html_in_xhr2.html
   file_html_in_xhr3.html
   file_htmlserializer_1.html
   file_htmlserializer_1_bodyonly.html
   file_htmlserializer_1_format.html
@@ -889,8 +891,9 @@ skip-if = buildapp == 'b2g' #no ssl supp
 [test_bug769117.html]
 [test_bug1250148.html]
 [test_bug1240471.html]
 [test_mozbrowser_apis_allowed.html]
 [test_mozbrowser_apis_blocked.html]
 [test_document_register.html]
 [test_bug962251.html]
 [test_bug1259588.html]
+[test_bug1263696.html]
--- a/dom/base/test/test_EventSource_redirects.html
+++ b/dom/base/test/test_EventSource_redirects.html
@@ -16,19 +16,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
 
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
   function doTest(test_id) {
-    oldPrefVal = SpecialPowers.getBoolPref("dom.server-events.enabled");
-    ok(true, "here we go");
-
     source = new EventSource("eventsource_redirect.resource");
     ok(source.url == "http://mochi.test:8888/tests/dom/base/test/eventsource_redirect.resource", "Test failed.");
     ok(source.readyState == 0 || source.readyState == 1, "Test failed.");
 
     source.onopen = function (event) {
       ok(true, "opened");
     };
 
@@ -42,17 +39,15 @@ https://bugzilla.mozilla.org/show_bug.cg
       ok(false, "received onError: " + event);
       source.close();
       SimpleTest.finish();
     };
 
   }
 
   SimpleTest.waitForExplicitFinish();
-  addLoadEvent(function() {
-    SpecialPowers.pushPrefEnv({"set": [['dom.server-events.enabled', true]]}, doTest);
-  });
+  addLoadEvent(doTest);
 </script>
 </pre>
 
 </body>
 </html>
 
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_bug1263696.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta><charset="utf-8"/>
+    <title>Test Embed/Object Node Conflicts</title>
+    <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+    <script type="application/javascript" src="plugin-utils.js"></script>
+    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+    <script type="application/javascript">
+     SimpleTest.waitForExplicitFinish();
+     var index = 0;
+     function startTest() {
+       is(index, 12, "Should have loaded all passing frames.");
+       SimpleTest.finish();
+     }
+    </script>
+  </head>
+  <body onload="startTest()">
+    <object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px">
+      <embed type="text/html" src="file_bug1263696_frame_fail.html" />
+    </object>
+    <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
+      <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+    </object>
+    <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
+      <div></div>
+      <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+    </object>
+    <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
+      <div>
+        <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+      </div>
+    </object>
+    <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
+      <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+      <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+      <object data="file_bug1263696_frame_pass.html">
+        <embed type="text/html" src="file_bug1263696_frame_fail.html" />
+      </object>
+      <object data="data:application/x-does-not-exist,test">
+        <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+      </object>
+    </object>
+    <div>
+      <object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object>
+      <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+    </div>
+    <div>
+      <embed type="text/html" src="file_bug1263696_frame_pass.html" />
+      <object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object>
+    </div>
+  </body>
+</html>
--- a/dom/base/test/test_bug338583.html
+++ b/dom/base/test/test_bug338583.html
@@ -616,17 +616,21 @@ https://bugzilla.mozilla.org/show_bug.cg
       document.getElementById('waitSpan').innerHTML = '';
       setTestHasFinished(test_id);
     }, parseInt(8000*stress_factor));
   }
 
   function doTest()
   {
     // Allow all cookies, then run the actual test
-    SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0], ["dom.server-events.enabled", true]]}, function() { SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], doTestCallback);});
+    SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]},
+    function() {
+      SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}],
+        doTestCallback);
+    });
   }
 
   function doTestCallback()
   {
 
     // we get a good stress_factor by testing 10 setTimeouts and some float
     // arithmetic taking my machine as stress_factor==1 (time=589)
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
@@ -83,26 +83,27 @@ BluetoothDaemonSocketModule::ConnectCmd(
   }
   Unused << pdu.release();
   return rv;
 }
 
 /* |DeleteTask| deletes a class instance on the I/O thread
  */
 template <typename T>
-class DeleteTask final : public Task
+class DeleteTask final : public Runnable
 {
 public:
   DeleteTask(T* aPtr)
   : mPtr(aPtr)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     mPtr = nullptr;
+    return NS_OK;
   }
 
 private:
   UniquePtr<T> mPtr;
 };
 
 /* |AcceptWatcher| specializes SocketMessageWatcher for Accept
  * operations by reading the socket messages from Bluedroid and
@@ -129,41 +130,41 @@ public:
                                                     GetConnectionStatus()));
     } else {
       ErrorRunnable::Dispatch(GetResultHandler(),
                               &BluetoothSocketResultHandler::OnError,
                               ConstantInitOp1<BluetoothStatus>(aStatus));
     }
 
     MessageLoopForIO::current()->PostTask(
-      FROM_HERE, new DeleteTask<AcceptWatcher>(this));
+      MakeAndAddRef<DeleteTask<AcceptWatcher>>(this));
   }
 };
 
 nsresult
 BluetoothDaemonSocketModule::AcceptCmd(int aFd,
                                        BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /* receive Bluedroid's socket-setup messages and client fd */
-  Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
+  XRE_GetIOMessageLoop()->PostTask(
+    MakeAndAddRef<SocketMessageWatcherTask>(new AcceptWatcher(aFd, aRes)));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonSocketModule::CloseCmd(BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /* stop the watcher corresponding to |aRes| */
-  Task* t = new DeleteSocketMessageWatcherTask(aRes);
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
+  XRE_GetIOMessageLoop()->PostTask(
+    MakeAndAddRef<DeleteSocketMessageWatcherTask>(aRes));
 
   return NS_OK;
 }
 
 void
 BluetoothDaemonSocketModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
                                        DaemonSocketPDU& aPDU,
                                        DaemonSocketResultHandler* aRes)
@@ -268,17 +269,17 @@ public:
                                                     GetConnectionStatus()));
     } else {
       ErrorRunnable::Dispatch(GetResultHandler(),
                               &BluetoothSocketResultHandler::OnError,
                               ConstantInitOp1<BluetoothStatus>(aStatus));
     }
 
     MessageLoopForIO::current()->PostTask(
-      FROM_HERE, new DeleteTask<ConnectWatcher>(this));
+      MakeAndAddRef<DeleteTask<ConnectWatcher>>(this));
   }
 };
 
 void
 BluetoothDaemonSocketModule::ConnectRsp(const DaemonSocketPDUHeader& aHeader,
                                         DaemonSocketPDU& aPDU,
                                         BluetoothSocketResultHandler* aRes)
 {
@@ -293,18 +294,18 @@ BluetoothDaemonSocketModule::ConnectRsp(
   fd = receiveFds[0];
   if (fd < 0) {
     ErrorRunnable::Dispatch(aRes, &BluetoothSocketResultHandler::OnError,
                             ConstantInitOp1<BluetoothStatus>(STATUS_FAIL));
     return;
   }
 
   /* receive Bluedroid's socket-setup messages */
-  Task* t = new SocketMessageWatcherTask(new ConnectWatcher(fd, aRes));
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
+  XRE_GetIOMessageLoop()->PostTask(
+    MakeAndAddRef<SocketMessageWatcherTask>(new ConnectWatcher(fd, aRes)));
 }
 
 //
 // Socket interface
 //
 
 BluetoothDaemonSocketInterface::BluetoothDaemonSocketInterface(
   BluetoothDaemonSocketModule* aModule)
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -167,28 +167,29 @@ public:
     return NS_OK;
   };
 
 private:
   nsCOMPtr<nsIInputStream> mInputStream;
   uint32_t mAvailablePacketSize;
 };
 
-class BluetoothOppManager::CloseSocketTask final : public Task
+class BluetoothOppManager::CloseSocketTask final : public Runnable
 {
 public:
   CloseSocketTask(BluetoothSocket* aSocket) : mSocket(aSocket)
   {
     MOZ_ASSERT(aSocket);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
     mSocket->Close();
+    return NS_OK;
   }
 
 private:
   RefPtr<BluetoothSocket> mSocket;
 };
 
 BluetoothOppManager::BluetoothOppManager() : mConnected(false)
                                            , mRemoteObexVersion(0)
@@ -1153,18 +1154,18 @@ BluetoothOppManager::ClientDataHandler(U
     SendDisconnectRequest();
     FileTransferComplete();
   } else if (mLastCommand == ObexRequestCode::Disconnect) {
     AfterOppDisconnected();
     // Most devices will directly terminate connection after receiving
     // Disconnect request, so we make a delay here. If the socket hasn't been
     // disconnected, we will close it.
     if (mSocket) {
-      MessageLoop::current()->
-        PostDelayedTask(FROM_HERE, new CloseSocketTask(mSocket), 1000);
+      MessageLoop::current()->PostDelayedTask(
+        MakeAndAddRef<CloseSocketTask>(mSocket), 1000);
     }
   } else if (mLastCommand == ObexRequestCode::Connect) {
     MOZ_ASSERT(!mFileName.IsEmpty());
     MOZ_ASSERT(mBlob);
 
     AfterOppConnected();
 
     // Ensure valid access to remote information
--- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp
@@ -195,61 +195,66 @@ private:
 class SocketConnectTask final : public SocketIOTask<DroidSocketImpl>
 {
 public:
   SocketConnectTask(DroidSocketImpl* aDroidSocketImpl, int aFd)
   : SocketIOTask<DroidSocketImpl>(aDroidSocketImpl)
   , mFd(aFd)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!GetIO()->IsConsumerThread());
     MOZ_ASSERT(!IsCanceled());
 
     GetIO()->Connect(mFd);
+
+    return NS_OK;
   }
 
 private:
   int mFd;
 };
 
 class SocketListenTask final : public SocketIOTask<DroidSocketImpl>
 {
 public:
   SocketListenTask(DroidSocketImpl* aDroidSocketImpl, int aFd)
   : SocketIOTask<DroidSocketImpl>(aDroidSocketImpl)
   , mFd(aFd)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!GetIO()->IsConsumerThread());
 
     if (!IsCanceled()) {
       GetIO()->Listen(mFd);
     }
+    return NS_OK;
   }
 
 private:
   int mFd;
 };
 
 class SocketConnectClientFdTask final
 : public SocketIOTask<DroidSocketImpl>
 {
   SocketConnectClientFdTask(DroidSocketImpl* aImpl)
   : SocketIOTask<DroidSocketImpl>(aImpl)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!GetIO()->IsConsumerThread());
 
     GetIO()->ConnectClientFd();
+
+    return NS_OK;
   }
 };
 
 void
 DroidSocketImpl::Connect(int aFd)
 {
   MOZ_ASSERT(aFd >= 0);
 
@@ -298,17 +303,17 @@ DroidSocketImpl::Accept(int aFd)
     int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags | O_NONBLOCK));
     NS_ENSURE_TRUE_VOID(!res);
   }
 
   SetFd(aFd);
   mConnectionStatus = SOCKET_IS_CONNECTED;
 
   GetConsumerThread()->PostTask(
-    FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
+    MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
 
   AddWatchers(READ_WATCHER, true);
   if (HasPendingData()) {
     AddWatchers(WRITE_WATCHER, false);
   }
 }
 
 void
@@ -342,22 +347,24 @@ DroidSocketImpl::OnSocketCanReceiveWitho
 class AcceptTask final : public SocketIOTask<DroidSocketImpl>
 {
 public:
   AcceptTask(DroidSocketImpl* aDroidSocketImpl, int aFd)
   : SocketIOTask<DroidSocketImpl>(aDroidSocketImpl)
   , mFd(aFd)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!GetIO()->IsConsumerThread());
     MOZ_ASSERT(!IsCanceled());
 
     GetIO()->Accept(mFd);
+
+    return NS_OK;
   }
 
 private:
   int mFd;
 };
 
 class AcceptResultHandler final : public BluetoothSocketResultHandler
 {
@@ -381,18 +388,18 @@ public:
     }
 
     if (aConnectionStatus != 0) {
       mImpl->mConsumer->NotifyError();
       return;
     }
 
     mImpl->mConsumer->SetAddress(aBdAddress);
-    mImpl->GetIOLoop()->PostTask(FROM_HERE,
-                                 new AcceptTask(mImpl, fd.forget()));
+    mImpl->GetIOLoop()->PostTask(
+      mozilla::MakeAndAddRef<AcceptTask>(mImpl, fd.forget()));
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
     BT_LOGR("BluetoothSocketInterface::Accept failed: %d", (int)aStatus);
 
     if (!mImpl->IsShutdownOnConsumerThread()) {
@@ -411,21 +418,23 @@ private:
 class InvokeAcceptTask final : public SocketTask<DroidSocketImpl>
 {
 public:
   InvokeAcceptTask(DroidSocketImpl* aImpl, int aListenFd)
     : SocketTask<DroidSocketImpl>(aImpl)
     , mListenFd(aListenFd)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(GetIO()->IsConsumerThread());
 
     GetIO()->mConsumer->Accept(mListenFd, new AcceptResultHandler(GetIO()));
+
+    return NS_OK;
   }
 
 private:
   int mListenFd;
 };
 
 void
 DroidSocketImpl::OnSocketCanAcceptWithoutBlocking(int aFd)
@@ -433,17 +442,17 @@ DroidSocketImpl::OnSocketCanAcceptWithou
   MOZ_ASSERT(!IsConsumerThread());
   MOZ_ASSERT(!mShuttingDownOnIOThread);
 
   /* When a listening socket is ready for receiving data,
    * we can call |Accept| on it.
    */
 
   RemoveWatchers(READ_WATCHER);
-  GetConsumerThread()->PostTask(FROM_HERE, new InvokeAcceptTask(this, aFd));
+  GetConsumerThread()->PostTask(MakeAndAddRef<InvokeAcceptTask>(this, aFd));
 }
 
 void
 DroidSocketImpl::OnFileCanWriteWithoutBlocking(int aFd)
 {
   if (mConnectionStatus == SOCKET_IS_CONNECTED) {
     OnSocketCanSendWithoutBlocking(aFd);
   } else if (mConnectionStatus == SOCKET_IS_CONNECTING) {
@@ -478,17 +487,17 @@ DroidSocketImpl::OnSocketCanConnectWitho
 
   /* We follow Posix behaviour here: Connect operations are
    * complete once we can write to the connecting socket.
    */
 
   mConnectionStatus = SOCKET_IS_CONNECTED;
 
   GetConsumerThread()->PostTask(
-    FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
+    MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
 
   AddWatchers(READ_WATCHER, true);
   if (HasPendingData()) {
     AddWatchers(WRITE_WATCHER, false);
   }
 }
 
 // |DataSocketIO|
@@ -514,43 +523,45 @@ DroidSocketImpl::QueryReceiveBuffer(
 class DroidSocketImpl::ReceiveTask final : public SocketTask<DroidSocketImpl>
 {
 public:
   ReceiveTask(DroidSocketImpl* aIO, UnixSocketBuffer* aBuffer)
     : SocketTask<DroidSocketImpl>(aIO)
     , mBuffer(aBuffer)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     DroidSocketImpl* io = SocketTask<DroidSocketImpl>::GetIO();
 
     MOZ_ASSERT(io->IsConsumerThread());
 
     if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
       // Since we've already explicitly closed and the close
       // happened before this, this isn't really an error.
-      return;
+      return NS_OK;
     }
 
     BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
     MOZ_ASSERT(bluetoothSocket);
 
     bluetoothSocket->ReceiveSocketData(mBuffer);
+
+    return NS_OK;
   }
 
 private:
   UniquePtr<UnixSocketBuffer> mBuffer;
 };
 
 void
 DroidSocketImpl::ConsumeBuffer()
 {
-  GetConsumerThread()->PostTask(FROM_HERE,
-                                new ReceiveTask(this, mBuffer.release()));
+  GetConsumerThread()->PostTask(
+    MakeAndAddRef<ReceiveTask>(this, mBuffer.release()));
 }
 
 void
 DroidSocketImpl::DiscardBuffer()
 {
   // Nothing to do.
 }
 
@@ -600,18 +611,18 @@ public:
     }
 
     if (aConnectionStatus != 0) {
       mImpl->mConsumer->NotifyError();
       return;
     }
 
     mImpl->mConsumer->SetAddress(aBdAddress);
-    mImpl->GetIOLoop()->PostTask(FROM_HERE,
-                                 new SocketConnectTask(mImpl, aFd));
+    mImpl->GetIOLoop()->PostTask(
+      mozilla::MakeAndAddRef<SocketConnectTask>(mImpl, aFd));
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
     BT_WARNING("Connect failed: %d", (int)aStatus);
 
     if (!mImpl->IsShutdownOnConsumerThread()) {
@@ -677,17 +688,18 @@ public:
   {
     MOZ_ASSERT(mImpl);
   }
 
   void Listen(int aFd) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
 
-    mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketListenTask(mImpl, aFd));
+    mImpl->GetIOLoop()->PostTask(
+      mozilla::MakeAndAddRef<SocketListenTask>(mImpl, aFd));
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
 
     BT_WARNING("Listen failed: %d", (int)aStatus);
   }
@@ -771,18 +783,18 @@ BluetoothSocket::ReceiveSocketData(Uniqu
 void
 BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
 {
   MOZ_ASSERT(mImpl);
   MOZ_ASSERT(mImpl->IsConsumerThread());
   MOZ_ASSERT(!mImpl->IsShutdownOnConsumerThread());
 
   mImpl->GetIOLoop()->PostTask(
-    FROM_HERE,
-    new SocketIOSendTask<DroidSocketImpl, UnixSocketIOBuffer>(mImpl, aBuffer));
+    MakeAndAddRef<SocketIOSendTask<DroidSocketImpl, UnixSocketIOBuffer>>(
+      mImpl, aBuffer));
 }
 
 // |SocketBase|
 
 void
 BluetoothSocket::Close()
 {
   if (!mImpl) {
@@ -855,16 +867,16 @@ BluetoothSocket::Cleanup()
   if (mCurrentRes) {
     mSocketInterface->Close(mCurrentRes);
   }
 
   // From this point on, we consider mImpl as being deleted. We
   // sever the relationship here so any future calls to listen
   // or connect will create a new implementation.
   mImpl->ShutdownOnConsumerThread();
-  mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mImpl));
+  mImpl->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mImpl));
   mImpl = nullptr;
 
   mSocketInterface = nullptr;
   mObserver = nullptr;
   mCurrentRes = nullptr;
   mDeviceAddress.Clear();
 }
--- a/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.cpp
@@ -272,41 +272,43 @@ SocketMessageWatcher::ReadBdAddress(unsi
 
 SocketMessageWatcherTask::SocketMessageWatcherTask(
   SocketMessageWatcher* aWatcher)
   : mWatcher(aWatcher)
 {
   MOZ_ASSERT(mWatcher);
 }
 
-void
+NS_IMETHODIMP
 SocketMessageWatcherTask::Run()
 {
   mWatcher->Watch();
+  return NS_OK;
 }
 
 //
 // DeleteSocketMessageWatcherTask
 //
 
 DeleteSocketMessageWatcherTask::DeleteSocketMessageWatcherTask(
   BluetoothSocketResultHandler* aRes)
   : mRes(aRes)
 {
   MOZ_ASSERT(mRes);
 }
 
-void
+NS_IMETHODIMP
 DeleteSocketMessageWatcherTask::Run()
 {
   // look up hash table for the watcher corresponding to |mRes|
   SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
   if (!wrapper) {
-    return;
+    return NS_OK;
   }
 
   // stop the watcher if it exists
   SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
   watcher->StopWatching();
   watcher->Proceed(STATUS_DONE);
+  return NS_OK;
 }
 
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.h
+++ b/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.h
@@ -79,36 +79,36 @@ private:
   unsigned char mLen;
   uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
   RefPtr<BluetoothSocketResultHandler> mRes;
 };
 
 /* |SocketMessageWatcherTask| starts a SocketMessageWatcher
  * on the I/O task
  */
-class SocketMessageWatcherTask final : public Task
+class SocketMessageWatcherTask final : public Runnable
 {
 public:
   SocketMessageWatcherTask(SocketMessageWatcher* aWatcher);
 
-  void Run() override;
+  NS_IMETHOD Run() override;
 
 private:
   SocketMessageWatcher* mWatcher;
 };
 
 /* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
  * on the I/O task
  */
-class DeleteSocketMessageWatcherTask final : public Task
+class DeleteSocketMessageWatcherTask final : public Runnable
 {
 public:
   DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes);
 
-  void Run() override;
+  NS_IMETHOD Run() override;
 
 private:
   BluetoothSocketResultHandler* mRes;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif // mozilla_dom_bluetooth_bluedroid_BluetoothSocketMessageWatcher_h
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -103,51 +103,53 @@ public:
     BT_WARNING("Unable to get value for '" AUDIO_VOLUME_BT_SCO_ID "'");
     return NS_OK;
   }
 
 protected:
   ~GetVolumeTask() { }
 };
 
-class BluetoothHfpManager::CloseScoTask : public Task
+class BluetoothHfpManager::CloseScoTask : public Runnable
 {
 private:
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(sBluetoothHfpManager);
     sBluetoothHfpManager->DisconnectSco();
+    return NS_OK;
   }
 };
 
 class BluetoothHfpManager::CloseScoRunnable : public Runnable
 {
 public:
   NS_IMETHOD Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     MessageLoop::current()->PostDelayedTask(
-      FROM_HERE, new CloseScoTask(), sBusyToneInterval);
+      MakeAndAddRef<CloseScoTask>(), sBusyToneInterval);
 
     return NS_OK;
   }
 };
 
-class BluetoothHfpManager::RespondToBLDNTask : public Task
+class BluetoothHfpManager::RespondToBLDNTask : public Runnable
 {
 private:
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(sBluetoothHfpManager);
 
     if (!sBluetoothHfpManager->mDialingRequestProcessed) {
       sBluetoothHfpManager->mDialingRequestProcessed = true;
       sBluetoothHfpManager->SendResponse(HFP_AT_RESPONSE_ERROR);
     }
+    return NS_OK;
   }
 };
 
 NS_IMPL_ISUPPORTS(BluetoothHfpManager::GetVolumeTask,
                   nsISettingsServiceCallback);
 
 /**
  *  Call
@@ -1592,28 +1594,26 @@ void BluetoothHfpManager::DialCallNotifi
   // We need to respond OK/Error for dial requests for every case listed above,
   // 1) and 2):         Respond in either RespondToBLDNTask or
   //                    HandleCallStateChanged()
   // 3):                Respond here
   if (message.IsEmpty()) {
     mDialingRequestProcessed = false;
     NotifyDialer(NS_LITERAL_STRING("BLDN"));
 
-    MessageLoop::current()->PostDelayedTask(FROM_HERE,
-                                            new RespondToBLDNTask(),
+    MessageLoop::current()->PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
                                             sWaitingForDialingInterval);
   } else if (message[0] == '>') {
     mDialingRequestProcessed = false;
 
     nsAutoCString newMsg("ATD");
     newMsg += StringHead(message, message.Length() - 1);
     NotifyDialer(NS_ConvertUTF8toUTF16(newMsg));
 
-    MessageLoop::current()->PostDelayedTask(FROM_HERE,
-                                            new RespondToBLDNTask(),
+    MessageLoop::current()->PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
                                             sWaitingForDialingInterval);
   } else {
     SendResponse(HFP_AT_RESPONSE_OK);
 
     nsAutoCString newMsg("ATD");
     newMsg += StringHead(message, message.Length() - 1);
     NotifyDialer(NS_ConvertUTF8toUTF16(newMsg));
   }
@@ -1761,15 +1761,14 @@ BluetoothHfpManager::KeyPressedNotificat
        */
       NotifyDialer(NS_LITERAL_STRING("CHUP"));
     }
   } else {
     // BLDN
 
     NotifyDialer(NS_LITERAL_STRING("BLDN"));
 
-    MessageLoop::current()->PostDelayedTask(FROM_HERE,
-                                            new RespondToBLDNTask(),
+    MessageLoop::current()->PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
                                             sWaitingForDialingInterval);
   }
 }
 
 NS_IMPL_ISUPPORTS(BluetoothHfpManager, nsIObserver)
--- a/dom/bluetooth/bluez/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp
@@ -379,19 +379,19 @@ static StaticAutoPtr<Monitor> sStopBluet
 // Protects against bug 969447.
 static StaticAutoPtr<Monitor> sGetPropertyMonitor;
 
 typedef void (*UnpackFunc)(DBusMessage*, DBusError*,
                            BluetoothValue&, nsAString&);
 typedef bool (*FilterFunc)(const BluetoothValue&);
 
 static void
-DispatchToDBusThread(Task* task)
+DispatchToDBusThread(already_AddRefed<Runnable> task)
 {
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, task);
+  XRE_GetIOMessageLoop()->PostTask(Move(task));
 }
 
 static nsresult
 DispatchToBtThread(nsIRunnable* aRunnable)
 {
   /* Due to the fact that the startup and shutdown of the Bluetooth
    * system can take an indefinite amount of time, a separate thread
    * is used for running blocking calls. The thread is not intended
@@ -623,43 +623,44 @@ public:
     hid->HandleInputPropertyChanged(mSignal);
     return NS_OK;
   }
 
 private:
   BluetoothSignal mSignal;
 };
 
-class TryFiringAdapterAddedTask : public Task
+class TryFiringAdapterAddedTask : public Runnable
 {
 public:
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
+    return NS_OK;
   }
 };
 
 class TryFiringAdapterAddedRunnable : public Runnable
 {
 public:
   TryFiringAdapterAddedRunnable(bool aDelay)
     : mDelay(aDelay)
   { }
 
   nsresult Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (mDelay) {
       MessageLoop::current()->
-        PostDelayedTask(FROM_HERE, new TryFiringAdapterAddedTask(),
+        PostDelayedTask(MakeAndAddRef<TryFiringAdapterAddedTask>(),
                         sWaitingForAdapterNameInterval);
     } else {
       MessageLoop::current()->
-        PostTask(FROM_HERE, new TryFiringAdapterAddedTask());
+        PostTask(MakeAndAddRef<TryFiringAdapterAddedTask>());
     }
 
     return NS_OK;
   }
 
 private:
   bool mDelay;
 };
@@ -1251,44 +1252,44 @@ AppendDeviceName(BluetoothSignal& aSigna
     BLUEZ_DBUS_BASE_IFC, NS_ConvertUTF16toUTF8(devicePath).get(),
     DBUS_DEVICE_IFACE, "GetProperties", DBUS_TYPE_INVALID);
 
   NS_ENSURE_TRUE_VOID(success);
 
   Unused << handler.forget(); // picked up by callback handler
 }
 
-class SetPairingConfirmationTask : public Task
+class SetPairingConfirmationTask : public Runnable
 {
 public:
   SetPairingConfirmationTask(const BluetoothAddress& aDeviceAddress,
                              bool aConfirm,
                              BluetoothReplyRunnable* aRunnable)
     : mDeviceAddress(aDeviceAddress)
     , mConfirm(aConfirm)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
 
     nsAutoString errorStr;
     BluetoothValue v = true;
     DBusMessage *msg = nullptr;
 
     if (!sPairingReqTable->Get(mDeviceAddress, &msg) && mRunnable) {
       BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
       errorStr.AssignLiteral("Couldn't get original request message.");
       DispatchBluetoothReply(mRunnable, v, errorStr);
 
-      return;
+      return NS_OK;
     }
 
     DBusMessage *reply;
 
     if (mConfirm) {
       reply = dbus_message_new_method_return(msg);
     } else {
       reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
@@ -1297,30 +1298,31 @@ public:
 
     if (!reply) {
       BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
       dbus_message_unref(msg);
       errorStr.AssignLiteral("Memory can't be allocated for the message.");
       if (mRunnable) {
         DispatchBluetoothReply(mRunnable, v, errorStr);
       }
-      return;
+      return NS_OK;
     }
 
     bool result = sDBusConnection->Send(reply);
     if (!result) {
       errorStr.AssignLiteral("Can't send message!");
     }
 
     dbus_message_unref(msg);
     dbus_message_unref(reply);
     sPairingReqTable->Remove(mDeviceAddress);
     if (mRunnable) {
       DispatchBluetoothReply(mRunnable, v, errorStr);
     }
+    return NS_OK;
   }
 
 private:
   BluetoothAddress mDeviceAddress;
   bool mConfirm;
   RefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
@@ -1504,18 +1506,18 @@ AgentEventFilter(DBusConnection *conn, D
       errorStr.AssignLiteral("Invalid arguments: RequestPairingConsent()");
       goto handle_error;
     }
 
     BluetoothAddress address;
     GetAddressFromObjectPath(NS_ConvertUTF8toUTF16(objectPath), address);
 
     sPairingReqTable->Put(address, msg);
-    Task* task = new SetPairingConfirmationTask(address, true, nullptr);
-    DispatchToDBusThread(task);
+    DispatchToDBusThread(
+      MakeAndAddRef<SetPairingConfirmationTask>(address, true, nullptr));
     // Increase dbus message reference counts, it will be decreased in
     // SetPairingConfirmationTask
     dbus_message_ref(msg);
     // Do not send a notification to upper layer
     return DBUS_HANDLER_RESULT_HANDLED;
   } else {
 #ifdef DEBUG
     BT_WARNING("agent handler %s: Unhandled event. Ignore.", __FUNCTION__);
@@ -1684,23 +1686,23 @@ private:
     NS_ENSURE_TRUE(success, false);
 
     Unused << handler.forget(); // picked up by callback handler
 
     return true;
   }
 };
 
-class AddReservedServiceRecordsTask : public Task
+class AddReservedServiceRecordsTask : public Runnable
 {
 public:
   AddReservedServiceRecordsTask()
   { }
 
-  void Run()
+  NS_IMETHOD Run() override
   {
     static const dbus_uint32_t sServices[] = {
       BluetoothServiceClass::HANDSFREE_AG,
       BluetoothServiceClass::HEADSET_AG,
       BluetoothServiceClass::OBJECT_PUSH
     };
 
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
@@ -1715,34 +1717,35 @@ public:
     bool success = sDBusConnection->SendWithReply(
       DBusReplyHandler::Callback, handler.get(), -1,
       BLUEZ_DBUS_BASE_IFC,
       NS_ConvertUTF16toUTF8(sAdapterPath).get(),
       DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
       DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
       &services, ArrayLength(sServices), DBUS_TYPE_INVALID);
 
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << handler.forget(); /* picked up by callback handler */
+
+    return NS_OK;
   }
 };
 
 class PrepareAdapterRunnable : public Runnable
 {
 public:
   PrepareAdapterRunnable()
   { }
 
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
-    Task* task = new AddReservedServiceRecordsTask();
-    DispatchToDBusThread(task);
+    DispatchToDBusThread(MakeAndAddRef<AddReservedServiceRecordsTask>());
 
     return NS_OK;
   }
 };
 
 class RequestPlayStatusTask : public Runnable
 {
 public:
@@ -2066,62 +2069,62 @@ BluetoothDBusService::IsReady()
 {
   if (!IsEnabled() || !sDBusConnection || IsToggling()) {
     BT_WARNING("Bluetooth service is not ready yet!");
     return false;
   }
   return true;
 }
 
-class StartDBusConnectionTask : public Task
+class StartDBusConnectionTask : public Runnable
 {
 public:
   StartDBusConnectionTask(RawDBusConnection* aConnection)
   : mConnection(aConnection)
   {
     MOZ_ASSERT(mConnection);
   }
 
-  void Run()
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
     if (sDBusConnection) {
       BT_WARNING("DBus connection has already been established.");
       RefPtr<Runnable> runnable = new BluetoothService::ToggleBtAck(true);
       if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
         BT_WARNING("Failed to dispatch to main thread!");
       }
-      return;
+      return NS_OK;
     }
 
     // Add a filter for all incoming messages_base
     if (!dbus_connection_add_filter(mConnection->GetConnection(),
                                     EventFilter, nullptr, nullptr)) {
       BT_WARNING("Cannot create DBus Event Filter for DBus Thread!");
       RefPtr<Runnable> runnable = new BluetoothService::ToggleBtAck(false);
       if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
         BT_WARNING("Failed to dispatch to main thread!");
       }
-      return;
+      return NS_OK;
     }
 
     mConnection->Watch();
 
     if (!sPairingReqTable) {
       sPairingReqTable = new nsDataHashtable<BluetoothAddressHashKey, DBusMessage* >;
     }
 
     sDBusConnection = mConnection.release();
 
     RefPtr<Runnable> runnable =
       new BluetoothService::ToggleBtAck(true);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
+    if (NS_FAILED(NS_DispatchToMainThread(runnable.forget()))) {
       BT_WARNING("Failed to dispatch to main thread!");
-      return;
+      return NS_OK;
     }
 
     /* Normally we'll receive the signal 'AdapterAdded' with the adapter object
      * path from the DBus daemon during start up. So, there's no need to query
      * the object path of default adapter here. However, if we restart from a
      * crash, the default adapter might already be available, so we ask the
      * daemon explicitly here.
      */
@@ -2131,16 +2134,17 @@ public:
                                                     BLUEZ_DBUS_BASE_IFC, "/",
                                                     DBUS_MANAGER_IFACE,
                                                     "DefaultAdapter",
                                                     DBUS_TYPE_INVALID);
       if (!success) {
         BT_WARNING("Failed to query default adapter!");
       }
     }
+    return NS_OK;
   }
 
 private:
   UniquePtr<RawDBusConnection> mConnection;
 };
 
 class StartBluetoothRunnable final : public Runnable
 {
@@ -2185,18 +2189,17 @@ public:
       dbus_bus_add_match(connection->GetConnection(),
                          sBluetoothDBusSignals[i],
                          &err);
       if (dbus_error_is_set(&err)) {
         LOG_AND_FREE_DBUS_ERROR(&err);
       }
     }
 
-    Task* task = new StartDBusConnectionTask(connection);
-    DispatchToDBusThread(task);
+    DispatchToDBusThread(MakeAndAddRef<StartDBusConnectionTask>(connection));
 
     return NS_OK;
   }
 };
 
 nsresult
 BluetoothDBusService::StartInternal(BluetoothReplyRunnable* aRunnable)
 {
@@ -2235,33 +2238,33 @@ public:
     nsresult rv = NS_DispatchToMainThread(runnable);
     if (NS_FAILED(rv)) {
       BT_WARNING("Failed to dispatch to main thread!");
     }
     return rv;
   }
 };
 
-class DeleteDBusConnectionTask final : public Task
+class DeleteDBusConnectionTask final : public Runnable
 {
 public:
   DeleteDBusConnectionTask()
   { }
 
-  void Run()
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
     if (!sDBusConnection) {
       BT_WARNING("DBus connection has not been established.");
       RefPtr<Runnable> runnable = new BluetoothService::ToggleBtAck(false);
       if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
         BT_WARNING("Failed to dispatch to main thread!");
       }
-      return;
+      return NS_OK;
     }
 
     for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
       dbus_bus_remove_match(sDBusConnection->GetConnection(),
                             sBluetoothDBusSignals[i], NULL);
     }
 
     dbus_connection_remove_filter(sDBusConnection->GetConnection(),
@@ -2294,33 +2297,34 @@ public:
 
     // We can only dispatch to the BT thread if we're on the main
     // thread. Thus we dispatch our runnable to the main thread
     // from where it will forward itself to the BT thread.
     RefPtr<Runnable> runnable = new DisableBluetoothRunnable();
     if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
       BT_WARNING("Failed to dispatch to BT thread!");
     }
+    return NS_OK;
   }
 };
 
 class StopBluetoothRunnable final : public Runnable
 {
 public:
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(!NS_IsMainThread()); // BT thread
 
     // This could block. It should never be run on the main thread.
     MonitorAutoLock lock(*sStopBluetoothMonitor);
     if (sConnectedDeviceCount > 0) {
       lock.Wait(PR_SecondsToInterval(TIMEOUT_FORCE_TO_DISABLE_BT));
     }
 
-    DispatchToDBusThread(new DeleteDBusConnectionTask());
+    DispatchToDBusThread(MakeAndAddRef<DeleteDBusConnectionTask>());
 
     return NS_OK;
   }
 };
 
 nsresult
 BluetoothDBusService::StopInternal(BluetoothReplyRunnable* aRunnable)
 {
@@ -2438,41 +2442,43 @@ protected:
     return true;
   }
 
 private:
   RefPtr<BluetoothReplyRunnable> mRunnable;
   nsString mAdapterPath;
 };
 
-class DefaultAdapterTask : public Task
+class DefaultAdapterTask : public Runnable
 {
 public:
   DefaultAdapterTask(BluetoothReplyRunnable* aRunnable)
     : mRunnable(aRunnable)
   {
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
 
     RefPtr<DefaultAdapterPathReplyHandler> handler =
       new DefaultAdapterPathReplyHandler(mRunnable);
 
     bool success = sDBusConnection->SendWithReply(
       DefaultAdapterPathReplyHandler::Callback,
       handler.get(), 1000, BLUEZ_DBUS_BASE_IFC,
       "/", DBUS_MANAGER_IFACE, "DefaultAdapter",
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << handler.forget(); // picked up by callback handler
+
+    return NS_OK;
   }
 
 private:
   RefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 nsresult
 BluetoothDBusService::GetAdaptersInternal(BluetoothReplyRunnable* aRunnable)
@@ -2484,18 +2490,17 @@ BluetoothDBusService::GetAdaptersInterna
    */
 
   if (!IsReady()) {
     NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
     DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
     return NS_OK;
   }
 
-  Task* task = new DefaultAdapterTask(aRunnable);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(MakeAndAddRef<DefaultAdapterTask>(aRunnable));
 
   return NS_OK;
 }
 
 static void
 OnSendDiscoveryMessageReply(DBusMessage *aReply, void *aData)
 {
   MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
@@ -2508,44 +2513,46 @@ OnSendDiscoveryMessageReply(DBusMessage 
 
   RefPtr<BluetoothReplyRunnable> runnable =
     dont_AddRef<BluetoothReplyRunnable>(
       static_cast<BluetoothReplyRunnable*>(aData));
 
   DispatchBluetoothReply(runnable.get(), BluetoothValue(true), errorStr);
 }
 
-class SendDiscoveryMessageTask : public Task
+class SendDiscoveryMessageTask : public Runnable
 {
 public:
   SendDiscoveryMessageTask(const char* aMessageName,
                            BluetoothReplyRunnable* aRunnable)
     : mMessageName(aMessageName)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mMessageName.IsEmpty());
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     bool success = sDBusConnection->SendWithReply(
       OnSendDiscoveryMessageReply,
       static_cast<void*>(mRunnable.get()), -1,
       BLUEZ_DBUS_BASE_IFC,
       NS_ConvertUTF16toUTF8(sAdapterPath).get(),
       DBUS_ADAPTER_IFACE, mMessageName.get(),
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << mRunnable.forget(); // picked up by callback handler
+
+    return NS_OK;
   }
 
 private:
   const nsCString mMessageName;
   RefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 nsresult
@@ -2557,18 +2564,18 @@ BluetoothDBusService::SendDiscoveryMessa
 
   if (!IsReady()) {
     NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
     DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
 
     return NS_OK;
   }
 
-  Task* task = new SendDiscoveryMessageTask(aMessageName, aRunnable);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<SendDiscoveryMessageTask>(aMessageName, aRunnable));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothDBusService::SendInputMessage(const nsAString& aDeviceAddress,
                                        const nsAString& aMessage)
 {
@@ -2582,17 +2589,17 @@ BluetoothDBusService::SendInputMessage(c
     return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(!sAdapterPath.IsEmpty());
   nsString objectPath = GetObjectPathFromAddress(sAdapterPath, aDeviceAddress);
   return SendAsyncDBusMessage(objectPath, DBUS_INPUT_IFACE, aMessage, callback);
 }
 
-class SendAsyncDBusMessageTask : public Task
+class SendAsyncDBusMessageTask : public Runnable
 {
 public:
   SendAsyncDBusMessageTask(DBusReplyCallback aCallback,
                            BluetoothServiceClass aServiceClass,
                            const nsACString& aObjectPath,
                            const char* aInterface,
                            const nsACString& aMessage)
     : mCallback(aCallback)
@@ -2601,28 +2608,30 @@ public:
     , mInterface(aInterface)
     , mMessage(aMessage)
   {
     MOZ_ASSERT(!mObjectPath.IsEmpty());
     MOZ_ASSERT(!mInterface.IsEmpty());
     MOZ_ASSERT(!mMessage.IsEmpty());
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
 
     static_assert(sizeof(BluetoothServiceClass) <= sizeof(intptr_t),
                   "BluetoothServiceClass cannot be passed via intptr_t");
     bool success = sDBusConnection->SendWithReply(
       mCallback, NS_INT32_TO_PTR(mServiceClass), -1,
       BLUEZ_DBUS_BASE_IFC, mObjectPath.get(), mInterface.get(),
       mMessage.get(), DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
+
+    return NS_OK;
   }
 
 private:
   DBusReplyCallback mCallback;
   BluetoothServiceClass mServiceClass;
   const nsCString mObjectPath;
   const nsCString mInterface;
   const nsCString mMessage;
@@ -2645,22 +2654,22 @@ BluetoothDBusService::SendAsyncDBusMessa
     serviceClass = BluetoothServiceClass::A2DP;
   } else if (!strcmp(aInterface, DBUS_INPUT_IFACE)) {
     serviceClass = BluetoothServiceClass::HID;
   } else {
     MOZ_ASSERT(false);
     return NS_ERROR_FAILURE;
   }
 
-  Task* task = new SendAsyncDBusMessageTask(aCallback,
+  DispatchToDBusThread(
+    MakeAndAddRef<SendAsyncDBusMessageTask>(aCallback,
                                             serviceClass,
                                             NS_ConvertUTF16toUTF8(aObjectPath),
                                             aInterface,
-                                            NS_ConvertUTF16toUTF8(aMessage));
-  DispatchToDBusThread(task);
+                                            NS_ConvertUTF16toUTF8(aMessage)));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothDBusService::SendSinkMessage(const nsAString& aDeviceAddress,
                                       const nsAString& aMessage)
 {
@@ -2819,34 +2828,36 @@ private:
   nsString mObjectPath;
   const nsTArray<BluetoothAddress> mDeviceAddresses;
   nsTArray<nsString>::size_type mProcessedDeviceAddresses;
   const FilterFunc mFilterFunc;
   RefPtr<BluetoothReplyRunnable> mRunnable;
   BluetoothValue mValues;
 };
 
-class ProcessRemainingDeviceAddressesTask : public Task
+class ProcessRemainingDeviceAddressesTask : public Runnable
 {
 public:
   ProcessRemainingDeviceAddressesTask(
     BluetoothArrayOfDevicePropertiesReplyHandler* aHandler,
     BluetoothReplyRunnable* aRunnable)
     : mHandler(aHandler)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(mHandler);
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
     mHandler->ProcessRemainingDeviceAddresses();
+
+    return NS_OK;
   }
 
 private:
   RefPtr<BluetoothArrayOfDevicePropertiesReplyHandler> mHandler;
   RefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 nsresult
@@ -2878,18 +2889,18 @@ BluetoothDBusService::GetConnectedDevice
     profile->GetAddress(address);
     deviceAddresses.AppendElement(address);
   }
 
   BluetoothArrayOfDevicePropertiesReplyHandler* handler =
     new BluetoothArrayOfDevicePropertiesReplyHandler(deviceAddresses,
                                                      GetConnectedDevicesFilter,
                                                      aRunnable);
-  Task* task = new ProcessRemainingDeviceAddressesTask(handler, aRunnable);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<ProcessRemainingDeviceAddressesTask>(handler, aRunnable));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothDBusService::GetPairedDevicePropertiesInternal(
   const nsTArray<BluetoothAddress>& aDeviceAddresses,
   BluetoothReplyRunnable* aRunnable)
@@ -2901,30 +2912,30 @@ BluetoothDBusService::GetPairedDevicePro
     DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
     return NS_OK;
   }
 
   BluetoothArrayOfDevicePropertiesReplyHandler* handler =
     new BluetoothArrayOfDevicePropertiesReplyHandler(aDeviceAddresses,
                                                      GetPairedDevicesFilter,
                                                      aRunnable);
-  Task* task = new ProcessRemainingDeviceAddressesTask(handler, aRunnable);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<ProcessRemainingDeviceAddressesTask>(handler, aRunnable));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothDBusService::FetchUuidsInternal(const BluetoothAddress& aDeviceAddress,
                                          BluetoothReplyRunnable* aRunnable)
 {
   return NS_OK;
 }
 
-class SetPropertyTask : public Task
+class SetPropertyTask : public Runnable
 {
 public:
   SetPropertyTask(BluetoothObjectType aType,
                   const nsACString& aName,
                   BluetoothReplyRunnable* aRunnable)
     : mType(aType)
     , mName(aName)
     , mRunnable(aRunnable)
@@ -2989,19 +3000,21 @@ public:
   SetUInt32PropertyTask(BluetoothObjectType aType,
                         const nsACString& aName,
                         uint32_t aValue,
                         BluetoothReplyRunnable* aRunnable)
     : SetPropertyTask(aType, aName, aRunnable)
     , mValue(aValue)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     Send(DBUS_TYPE_UINT32, &mValue);
+
+    return NS_OK;
   }
 
 private:
   dbus_uint32_t mValue;
 };
 
 class SetStringPropertyTask : public SetPropertyTask
 {
@@ -3009,20 +3022,22 @@ public:
   SetStringPropertyTask(BluetoothObjectType aType,
                         const nsACString& aName,
                         const nsACString& aValue,
                         BluetoothReplyRunnable* aRunnable)
     : SetPropertyTask(aType, aName, aRunnable)
     , mValue(aValue)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     const char* value = mValue.get();
     Send(DBUS_TYPE_STRING, &value);
+
+    return NS_OK;
   }
 
 private:
   const nsCString mValue;
 };
 
 class SetBooleanPropertyTask : public SetPropertyTask
 {
@@ -3031,19 +3046,21 @@ public:
                          const nsACString& aName,
                          dbus_bool_t aValue,
                          BluetoothReplyRunnable* aRunnable)
     : SetPropertyTask(aType, aName, aRunnable)
     , mValue(aValue)
   {
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     Send(DBUS_TYPE_BOOLEAN, &mValue);
+
+    return NS_OK;
   }
 
 private:
   dbus_bool_t mValue;
 };
 
 nsresult
 BluetoothDBusService::SetProperty(BluetoothObjectType aType,
@@ -3053,54 +3070,54 @@ BluetoothDBusService::SetProperty(Blueto
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!IsReady()) {
     NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
     DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
     return NS_OK;
   }
 
-  Task* task;
+  RefPtr<Runnable> task;
 
   if (aValue.value().type() == BluetoothValue::Tuint32_t) {
-    task = new SetUInt32PropertyTask(aType,
+    task = MakeAndAddRef<SetUInt32PropertyTask>(aType,
       NS_ConvertUTF16toUTF8(aValue.name()),
       aValue.value().get_uint32_t(), aRunnable);
   } else if (aValue.value().type() == BluetoothValue::TnsString) {
-    task = new SetStringPropertyTask(aType,
+    task = MakeAndAddRef<SetStringPropertyTask>(aType,
       NS_ConvertUTF16toUTF8(aValue.name()),
       NS_ConvertUTF16toUTF8(aValue.value().get_nsString()), aRunnable);
   } else if (aValue.value().type() == BluetoothValue::Tbool) {
-    task = new SetBooleanPropertyTask(aType,
+    task = MakeAndAddRef<SetBooleanPropertyTask>(aType,
       NS_ConvertUTF16toUTF8(aValue.name()),
       aValue.value().get_bool(), aRunnable);
   } else {
     BT_WARNING("Property type not handled!");
     return NS_ERROR_FAILURE;
   }
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(task.forget());
 
   return NS_OK;
 }
 
-class CreatePairedDeviceInternalTask : public Task
+class CreatePairedDeviceInternalTask : public Runnable
 {
 public:
   CreatePairedDeviceInternalTask(const BluetoothAddress& aDeviceAddress,
                                  int aTimeout,
                                  BluetoothReplyRunnable* aRunnable)
     : mDeviceAddress(aDeviceAddress)
     , mTimeout(aTimeout)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     nsString deviceAddressStr;
     AddressToString(mDeviceAddress, deviceAddressStr);
     auto utf8DeviceAddressStr = NS_ConvertUTF16toUTF8(deviceAddressStr);
@@ -3116,68 +3133,70 @@ public:
       BLUEZ_DBUS_BASE_IFC,
       NS_ConvertUTF16toUTF8(sAdapterPath).get(),
       DBUS_ADAPTER_IFACE,
       "CreatePairedDevice",
       DBUS_TYPE_STRING, &deviceAddress,
       DBUS_TYPE_OBJECT_PATH, &deviceAgentPath,
       DBUS_TYPE_STRING, &capabilities,
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << mRunnable.forget(); // picked up by callback handler
 
     /**
      * FIXME: Bug 820274
      *
      * If the user turns off Bluetooth in the middle of pairing process,
      * the callback function GetObjectPathCallback may still be called
      * while enabling next time by dbus daemon. To prevent this from
      * happening, added a flag to distinguish if Bluetooth has been
      * turned off. Nevertheless, we need a check if there is a better
      * solution.
      *
      * Please see Bug 818696 for more information.
      */
     sIsPairing++;
+
+    return NS_OK;
   }
 
 private:
   BluetoothAddress mDeviceAddress;
   int mTimeout;
   RefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 nsresult
 BluetoothDBusService::CreatePairedDeviceInternal(
   const BluetoothAddress& aDeviceAddress,
   int aTimeout,
   BluetoothReplyRunnable* aRunnable)
 {
-  Task* task = new CreatePairedDeviceInternalTask(aDeviceAddress,
+  DispatchToDBusThread(
+    MakeAndAddRef<CreatePairedDeviceInternalTask>(aDeviceAddress,
                                                   aTimeout,
-                                                  aRunnable);
-  DispatchToDBusThread(task);
+                                                  aRunnable));
 
   return NS_OK;
 }
 
-class RemoveDeviceTask : public Task
+class RemoveDeviceTask : public Runnable
 {
 public:
   RemoveDeviceTask(const BluetoothAddress& aDeviceAddress,
                    BluetoothReplyRunnable* aRunnable)
     : mDeviceAddress(aDeviceAddress)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     nsCString deviceObjectPath =
       NS_ConvertUTF16toUTF8(GetObjectPathFromAddress(sAdapterPath,
                                                      mDeviceAddress));
@@ -3185,19 +3204,21 @@ public:
 
     bool success = sDBusConnection->SendWithReply(
       OnRemoveDeviceReply, static_cast<void*>(mRunnable.get()), -1,
       BLUEZ_DBUS_BASE_IFC,
       NS_ConvertUTF16toUTF8(sAdapterPath).get(),
       DBUS_ADAPTER_IFACE, "RemoveDevice",
       DBUS_TYPE_OBJECT_PATH, &cstrDeviceObjectPath,
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << mRunnable.forget(); // picked up by callback handler
+
+    return NS_OK;
   }
 
 protected:
   static void OnRemoveDeviceReply(DBusMessage* aReply, void* aData)
   {
     nsAutoString errorStr;
 
     if (!aReply) {
@@ -3224,68 +3245,68 @@ BluetoothDBusService::RemoveDeviceIntern
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!IsReady()) {
     NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
     DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
     return NS_OK;
   }
 
-  Task* task = new RemoveDeviceTask(aDeviceAddress, aRunnable);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<RemoveDeviceTask>(aDeviceAddress, aRunnable));
 
   return NS_OK;
 }
 
-class SetPinCodeTask : public Task
+class SetPinCodeTask : public Runnable
 {
 public:
   SetPinCodeTask(const BluetoothAddress& aDeviceAddress,
                  const BluetoothPinCode& aPinCode,
                  BluetoothReplyRunnable* aRunnable)
     : mDeviceAddress(aDeviceAddress)
     , mPinCode(aPinCode)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
     nsAutoString errorStr;
     BluetoothValue v = true;
     DBusMessage *msg;
     if (!sPairingReqTable->Get(mDeviceAddress, &msg)) {
       BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
       errorStr.AssignLiteral("Couldn't get original request message.");
       DispatchBluetoothReply(mRunnable, v, errorStr);
-      return;
+      return NS_OK;
     }
 
     DBusMessage *reply = dbus_message_new_method_return(msg);
 
     if (!reply) {
       BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
       dbus_message_unref(msg);
       errorStr.AssignLiteral("Memory can't be allocated for the message.");
       DispatchBluetoothReply(mRunnable, v, errorStr);
-      return;
+      return NS_OK;
     }
 
     nsAutoString pinCodeStr;
     if (NS_FAILED(PinCodeToString(mPinCode, pinCodeStr))) {
       BT_WARNING("%s: Cannot convert pin code to string.", __FUNCTION__);
       dbus_message_unref(msg);
       dbus_message_unref(reply);
       errorStr.AssignLiteral("Cannot convert pin code to string.");
       DispatchBluetoothReply(mRunnable, v, errorStr);
-      return;
+      return NS_OK;
     }
 
     auto utf8PinCodeStr = NS_ConvertUTF16toUTF8(pinCodeStr);
 
     const char* pinCode = utf8PinCodeStr.get();
 
     if (!dbus_message_append_args(reply,
                                   DBUS_TYPE_STRING, &pinCode,
@@ -3297,16 +3318,18 @@ public:
       sDBusConnection->Send(reply);
     }
 
     dbus_message_unref(msg);
     dbus_message_unref(reply);
 
     sPairingReqTable->Remove(mDeviceAddress);
     DispatchBluetoothReply(mRunnable, v, errorStr);
+
+    return NS_OK;
   }
 
 private:
   const BluetoothAddress mDeviceAddress;
   const BluetoothPinCode mPinCode;
   RefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
@@ -3326,56 +3349,56 @@ BluetoothDBusService::SspReplyInternal(
   // Legacy interface used by Bluedroid only.
 }
 
 void
 BluetoothDBusService::SetPinCodeInternal(const BluetoothAddress& aDeviceAddress,
                                          const BluetoothPinCode& aPinCode,
                                          BluetoothReplyRunnable* aRunnable)
 {
-  Task* task = new SetPinCodeTask(aDeviceAddress, aPinCode, aRunnable);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<SetPinCodeTask>(aDeviceAddress, aPinCode, aRunnable));
 }
 
-class SetPasskeyTask : public Task
+class SetPasskeyTask : public Runnable
 {
 public:
   SetPasskeyTask(const BluetoothAddress& aDeviceAddress,
                  uint32_t aPasskey,
                  BluetoothReplyRunnable* aRunnable)
     : mDeviceAddress(aDeviceAddress)
     , mPasskey(aPasskey)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
     nsAutoString errorStr;
     BluetoothValue v = true;
     DBusMessage *msg;
     if (!sPairingReqTable->Get(mDeviceAddress, &msg)) {
       BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
       errorStr.AssignLiteral("Couldn't get original request message.");
       DispatchBluetoothReply(mRunnable, v, errorStr);
-      return;
+      return NS_OK;
     }
 
     DBusMessage *reply = dbus_message_new_method_return(msg);
 
     if (!reply) {
       BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
       dbus_message_unref(msg);
       errorStr.AssignLiteral("Memory can't be allocated for the message.");
       DispatchBluetoothReply(mRunnable, v, errorStr);
-      return;
+      return NS_OK;
     }
 
     uint32_t passkey = mPasskey;
 
     if (!dbus_message_append_args(reply,
                                   DBUS_TYPE_UINT32, &passkey,
                                   DBUS_TYPE_INVALID)) {
       BT_WARNING("%s: Couldn't append arguments to dbus message.", __FUNCTION__);
@@ -3385,48 +3408,50 @@ public:
       sDBusConnection->Send(reply);
     }
 
     dbus_message_unref(msg);
     dbus_message_unref(reply);
 
     sPairingReqTable->Remove(mDeviceAddress);
     DispatchBluetoothReply(mRunnable, v, errorStr);
+
+    return NS_OK;
   }
 
 private:
   BluetoothAddress mDeviceAddress;
   uint32_t mPasskey;
   RefPtr<BluetoothReplyRunnable> mRunnable;
 };
 
 void
 BluetoothDBusService::SetPasskeyInternal(
   const BluetoothAddress& aDeviceAddress,
   uint32_t aPasskey,
   BluetoothReplyRunnable* aRunnable)
 {
-  Task* task = new SetPasskeyTask(aDeviceAddress,
+  DispatchToDBusThread(
+    MakeAndAddRef<SetPasskeyTask>(aDeviceAddress,
                                   aPasskey,
-                                  aRunnable);
-  DispatchToDBusThread(task);
+                                  aRunnable));
 }
 
 void
 BluetoothDBusService::SetPairingConfirmationInternal(
   const BluetoothAddress& aDeviceAddress,
   bool aConfirm,
   BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  Task* task = new SetPairingConfirmationTask(aDeviceAddress,
+  DispatchToDBusThread(
+    MakeAndAddRef<SetPairingConfirmationTask>(aDeviceAddress,
                                               aConfirm,
-                                              aRunnable);
-  DispatchToDBusThread(task);
+                                              aRunnable));
 }
 
 static void
 NextBluetoothProfileController()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // First, remove the task at the front which has been already done.
@@ -3611,31 +3636,31 @@ public:
   }
 
 private:
   BluetoothAddress mDeviceAddress;
   BluetoothUuid mServiceUUID;
   BluetoothProfileManagerBase* mBluetoothProfileManager;
 };
 
-class GetServiceChannelTask : public Task
+class GetServiceChannelTask : public Runnable
 {
 public:
   GetServiceChannelTask(const BluetoothAddress& aDeviceAddress,
                         const BluetoothUuid& aServiceUUID,
                         BluetoothProfileManagerBase* aBluetoothProfileManager)
     : mDeviceAddress(aDeviceAddress)
     , mServiceUUID(aServiceUUID)
     , mBluetoothProfileManager(aBluetoothProfileManager)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mBluetoothProfileManager);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     static const int sProtocolDescriptorList = 0x0004;
 
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     const nsString objectPath =
@@ -3654,19 +3679,21 @@ public:
     bool success = sDBusConnection->SendWithReply(
       OnGetServiceChannelReplyHandler::Callback, handler, -1,
       BLUEZ_DBUS_BASE_IFC,
       NS_ConvertUTF16toUTF8(objectPath).get(),
       DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
       DBUS_TYPE_STRING, &cstrServiceUUID,
       DBUS_TYPE_UINT16, &sProtocolDescriptorList,
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << handler.forget(); // picked up by callback handler
+
+    return NS_OK;
   }
 
 private:
   BluetoothAddress mDeviceAddress;
   BluetoothUuid mServiceUUID;
   BluetoothProfileManagerBase* mBluetoothProfileManager;
 };
 
@@ -3680,20 +3707,20 @@ BluetoothDBusService::GetServiceChannel(
   if (!IsReady()) {
     NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
     return NS_OK;
   }
 
 #ifdef MOZ_WIDGET_GONK
   // GetServiceAttributeValue only exists in android's bluez dbus binding
   // implementation
-  Task* task = new GetServiceChannelTask(aDeviceAddress,
+  DispatchToDBusThread(
+    MakeAndAddRef<GetServiceChannelTask>(aDeviceAddress,
                                          aServiceUUID,
-                                         aManager);
-  DispatchToDBusThread(task);
+                                         aManager));
 #else
   // FIXME/Bug 793977 qdot: Just set something for desktop, until we have a
   // parser for the GetServiceAttributes xml block
   //
   // Even though we are on the main thread already, we need to dispatch a
   // runnable here. OnGetServiceChannel needs mRunnable to be set, which
   // happens after GetServiceChannel returns.
   RefPtr<Runnable> r = new OnGetServiceChannelRunnable(aDeviceAddress,
@@ -3701,29 +3728,29 @@ BluetoothDBusService::GetServiceChannel(
                                                          1,
                                                          aManager);
   NS_DispatchToMainThread(r);
 #endif
 
   return NS_OK;
 }
 
-class UpdateSdpRecordsTask : public Task
+class UpdateSdpRecordsTask : public Runnable
 {
 public:
   UpdateSdpRecordsTask(const BluetoothAddress& aDeviceAddress,
                        BluetoothProfileManagerBase* aBluetoothProfileManager)
     : mDeviceAddress(aDeviceAddress)
     , mBluetoothProfileManager(aBluetoothProfileManager)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mBluetoothProfileManager);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     const nsString objectPath =
       GetObjectPathFromAddress(sAdapterPath, mDeviceAddress);
 
@@ -3735,16 +3762,17 @@ public:
     sDBusConnection->SendWithReply(DiscoverServicesCallback,
                                    (void*)callbackRunnable, -1,
                                    BLUEZ_DBUS_BASE_IFC,
                                    NS_ConvertUTF16toUTF8(objectPath).get(),
                                    DBUS_DEVICE_IFACE,
                                    "DiscoverServices",
                                    DBUS_TYPE_STRING, &EmptyCString(),
                                    DBUS_TYPE_INVALID);
+    return NS_OK;
   }
 
 protected:
   static void DiscoverServicesCallback(DBusMessage* aMsg, void* aData)
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
     RefPtr<OnUpdateSdpRecordsRunnable> r(
@@ -3758,18 +3786,18 @@ private:
 };
 
 bool
 BluetoothDBusService::UpdateSdpRecords(const BluetoothAddress& aDeviceAddress,
                                        BluetoothProfileManagerBase* aManager)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  Task* task = new UpdateSdpRecordsTask(aDeviceAddress, aManager);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<UpdateSdpRecordsTask>(aDeviceAddress, aManager));
 
   return true;
 }
 
 void
 BluetoothDBusService::SendFile(const BluetoothAddress& aDeviceAddress,
                                BlobParent* aBlobParent,
                                BlobChild* aBlobChild,
@@ -3887,17 +3915,17 @@ BluetoothDBusService::IsScoConnected(Blu
     NS_NAMED_LITERAL_STRING(replyError, "Fail to get BluetoothHfpManager");
     DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
     return;
   }
 
   DispatchBluetoothReply(aRunnable, hfp->IsScoConnected(), EmptyString());
 }
 
-class SendMetadataTask : public Task
+class SendMetadataTask : public Runnable
 {
 public:
   SendMetadataTask(const BluetoothAddress& aDeviceAddress,
                    const nsACString& aTitle,
                    const nsACString& aArtist,
                    const nsACString& aAlbum,
                    int64_t aMediaNumber,
                    int64_t aTotalMediaCount,
@@ -3911,17 +3939,17 @@ public:
     , mTotalMediaCount(aTotalMediaCount)
     , mDuration(aDuration)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     // We currently don't support genre field in music player.
     // In order to send media metadata through AVRCP, we set genre to an empty
     // string to match the BlueZ method "UpdateMetaData" with signature
@@ -3960,19 +3988,21 @@ public:
       DBUS_TYPE_STRING, &title,
       DBUS_TYPE_STRING, &artist,
       DBUS_TYPE_STRING, &album,
       DBUS_TYPE_STRING, &mediaNumber,
       DBUS_TYPE_STRING, &totalMediaCount,
       DBUS_TYPE_STRING, &duration,
       DBUS_TYPE_STRING, &genre,
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << mRunnable.forget(); // picked up by callback handler
+
+    return NS_OK;
   }
 
 private:
   const BluetoothAddress mDeviceAddress;
   const nsCString mTitle;
   const nsCString mArtist;
   const nsCString mAlbum;
   int64_t mMediaNumber;
@@ -4016,32 +4046,32 @@ BluetoothDBusService::SendMetaData(const
       !aTitle.Equals(prevTitle) ||
       !aAlbum.Equals(prevAlbum)) {
     UpdateNotification(ControlEventId::EVENT_TRACK_CHANGED, aMediaNumber);
   }
 
   BluetoothAddress deviceAddress;
   avrcp->GetAddress(deviceAddress);
 
-  Task* task = new SendMetadataTask(
-    deviceAddress,
-    NS_ConvertUTF16toUTF8(aTitle),
-    NS_ConvertUTF16toUTF8(aArtist),
-    NS_ConvertUTF16toUTF8(aAlbum),
-    aMediaNumber,
-    aTotalMediaCount,
-    aDuration,
-    aRunnable);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<SendMetadataTask>(
+      deviceAddress,
+      NS_ConvertUTF16toUTF8(aTitle),
+      NS_ConvertUTF16toUTF8(aArtist),
+      NS_ConvertUTF16toUTF8(aAlbum),
+      aMediaNumber,
+      aTotalMediaCount,
+      aDuration,
+      aRunnable));
 
   avrcp->UpdateMetaData(aTitle, aArtist, aAlbum,
                         aMediaNumber, aTotalMediaCount, aDuration);
 }
 
-class SendPlayStatusTask : public Task
+class SendPlayStatusTask : public Runnable
 {
 public:
   SendPlayStatusTask(const BluetoothAddress& aDeviceAddress,
                      int64_t aDuration,
                      int64_t aPosition,
                      ControlPlayStatus aPlayStatus,
                      BluetoothReplyRunnable* aRunnable)
     : mDeviceAddress(aDeviceAddress)
@@ -4049,17 +4079,17 @@ public:
     , mPosition(aPosition)
     , mPlayStatus(aPlayStatus)
     , mRunnable(aRunnable)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
     MOZ_ASSERT(mRunnable);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     const nsCString objectPath = NS_ConvertUTF16toUTF8(
       GetObjectPathFromAddress(sAdapterPath, mDeviceAddress));
 
@@ -4069,19 +4099,21 @@ public:
       GetVoidCallback, static_cast<void*>(mRunnable.get()), -1,
       BLUEZ_DBUS_BASE_IFC,
       objectPath.get(),
       DBUS_CTL_IFACE, "UpdatePlayStatus",
       DBUS_TYPE_UINT32, &mDuration,
       DBUS_TYPE_UINT32, &mPosition,
       DBUS_TYPE_UINT32, &tempPlayStatus,
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
 
     Unused << mRunnable.forget(); // picked up by callback handler
+
+    return NS_OK;
   }
 
 private:
   const BluetoothAddress mDeviceAddress;
   int64_t mDuration;
   int64_t mPosition;
   ControlPlayStatus mPlayStatus;
   RefPtr<BluetoothReplyRunnable> mRunnable;
@@ -4129,22 +4161,22 @@ BluetoothDBusService::SendPlayStatus(int
                        aPlayStatus);
   } else if (aPosition != avrcp->GetPosition()) {
     UpdateNotification(ControlEventId::EVENT_PLAYBACK_POS_CHANGED, aPosition);
   }
 
   BluetoothAddress deviceAddress;
   avrcp->GetAddress(deviceAddress);
 
-  Task* task = new SendPlayStatusTask(deviceAddress,
+  DispatchToDBusThread(
+    MakeAndAddRef<SendPlayStatusTask>(deviceAddress,
                                       aDuration,
                                       aPosition,
                                       aPlayStatus,
-                                      aRunnable);
-  DispatchToDBusThread(task);
+                                      aRunnable));
 
   avrcp->UpdatePlayStatus(aDuration, aPosition, aPlayStatus);
 }
 
 static void
 ControlCallback(DBusMessage* aMsg, void* aParam)
 {
   NS_ENSURE_TRUE_VOID(aMsg);
@@ -4152,32 +4184,32 @@ ControlCallback(DBusMessage* aMsg, void*
   BluetoothValue v;
   nsAutoString replyError;
   UnpackVoidMessage(aMsg, nullptr, v, replyError);
   if (!v.get_bool()) {
     BT_WARNING(NS_ConvertUTF16toUTF8(replyError).get());
   }
 }
 
-class UpdatePlayStatusTask : public Task
+class UpdatePlayStatusTask : public Runnable
 {
 public:
   UpdatePlayStatusTask(const BluetoothAddress& aDeviceAddress,
                        int32_t aDuration,
                        int32_t aPosition,
                        ControlPlayStatus aPlayStatus)
     : mDeviceAddress(aDeviceAddress)
     , mDuration(aDuration)
     , mPosition(aPosition)
     , mPlayStatus(aPlayStatus)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     const nsCString objectPath = NS_ConvertUTF16toUTF8(
       GetObjectPathFromAddress(sAdapterPath, mDeviceAddress));
 
@@ -4187,17 +4219,19 @@ public:
       ControlCallback, nullptr, -1,
       BLUEZ_DBUS_BASE_IFC,
       objectPath.get(),
       DBUS_CTL_IFACE, "UpdatePlayStatus",
       DBUS_TYPE_UINT32, &mDuration,
       DBUS_TYPE_UINT32, &mPosition,
       DBUS_TYPE_UINT32, &tempPlayStatus,
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
+
+    return NS_OK;
   }
 
 private:
   const BluetoothAddress mDeviceAddress;
   int32_t mDuration;
   int32_t mPosition;
   ControlPlayStatus mPlayStatus;
 };
@@ -4213,37 +4247,37 @@ BluetoothDBusService::UpdatePlayStatus(u
   BluetoothAvrcpManager* avrcp = BluetoothAvrcpManager::Get();
   NS_ENSURE_TRUE_VOID(avrcp);
   MOZ_ASSERT(avrcp->IsConnected());
   MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
   BluetoothAddress deviceAddress;
   avrcp->GetAddress(deviceAddress);
 
-  Task* task = new UpdatePlayStatusTask(deviceAddress,
+  DispatchToDBusThread(
+    MakeAndAddRef<UpdatePlayStatusTask>(deviceAddress,
                                         aDuration,
                                         aPosition,
-                                        aPlayStatus);
-  DispatchToDBusThread(task);
+                                        aPlayStatus));
 }
 
-class UpdateNotificationTask : public Task
+class UpdateNotificationTask : public Runnable
 {
 public:
   UpdateNotificationTask(const BluetoothAddress& aDeviceAddress,
                          BluetoothDBusService::ControlEventId aEventId,
                          uint64_t aData)
     : mDeviceAddress(aDeviceAddress)
     , mEventId(aEventId)
     , mData(aData)
   {
     MOZ_ASSERT(!mDeviceAddress.IsCleared());
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
     const nsCString objectPath = NS_ConvertUTF16toUTF8(
       GetObjectPathFromAddress(sAdapterPath, mDeviceAddress));
 
@@ -4252,17 +4286,19 @@ public:
     bool success = sDBusConnection->SendWithReply(
       ControlCallback, nullptr, -1,
       BLUEZ_DBUS_BASE_IFC,
       objectPath.get(),
       DBUS_CTL_IFACE, "UpdateNotification",
       DBUS_TYPE_UINT16, &eventId,
       DBUS_TYPE_UINT64, &mData,
       DBUS_TYPE_INVALID);
-    NS_ENSURE_TRUE_VOID(success);
+    NS_ENSURE_TRUE(success, NS_OK);
+
+    return NS_OK;
   }
 
 private:
   const BluetoothAddress mDeviceAddress;
   int16_t mEventId;
   int32_t mData;
 };
 
@@ -4276,18 +4312,18 @@ BluetoothDBusService::UpdateNotification
   BluetoothAvrcpManager* avrcp = BluetoothAvrcpManager::Get();
   NS_ENSURE_TRUE_VOID(avrcp);
   MOZ_ASSERT(avrcp->IsConnected());
   MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
   BluetoothAddress deviceAddress;
   avrcp->GetAddress(deviceAddress);
 
-  Task* task = new UpdateNotificationTask(deviceAddress, aEventId, aData);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(
+    MakeAndAddRef<UpdateNotificationTask>(deviceAddress, aEventId, aData));
 }
 
 void
 BluetoothDBusService::StartLeScanInternal(
   const nsTArray<BluetoothUuid>& aServiceUuids,
   BluetoothReplyRunnable* aRunnable)
 {
 }
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -237,85 +237,88 @@ BluetoothHfpManager::Notify(const hal::B
   int level = round(aBatteryInfo.level() * 5.0);
   if (level != sCINDItems[CINDType::BATTCHG].value) {
     sCINDItems[CINDType::BATTCHG].value = level;
     SendCommand(RESPONSE_CIEV, CINDType::BATTCHG);
   }
 }
 
 #ifdef MOZ_B2G_RIL
-class BluetoothHfpManager::RespondToBLDNTask : public Task
+class BluetoothHfpManager::RespondToBLDNTask : public Runnable
 {
 private:
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(sBluetoothHfpManager);
 
     if (!sBluetoothHfpManager->mDialingRequestProcessed) {
       sBluetoothHfpManager->mDialingRequestProcessed = true;
       sBluetoothHfpManager->SendLine("ERROR");
     }
+    return NS_OK;
   }
 };
 
-class BluetoothHfpManager::SendRingIndicatorTask : public Task
+class BluetoothHfpManager::SendRingIndicatorTask : public Runnable
 {
 public:
   SendRingIndicatorTask(const nsAString& aNumber, int aType)
     : mNumber(aNumber)
     , mType(aType)
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     // Stop sending RING indicator
     if (sStopSendingRingFlag) {
-      return;
+      return NS_OK;
     }
 
     if (!sBluetoothHfpManager) {
       BT_WARNING("BluetoothHfpManager no longer exists, cannot send ring!");
-      return;
+      return NS_OK;
     }
 
     nsAutoCString ringMsg("RING");
     sBluetoothHfpManager->SendLine(ringMsg.get());
 
     if (!mNumber.IsEmpty()) {
       nsAutoCString clipMsg("+CLIP: \"");
       clipMsg.Append(NS_ConvertUTF16toUTF8(mNumber).get());
       clipMsg.AppendLiteral("\",");
       clipMsg.AppendInt(mType);
       sBluetoothHfpManager->SendLine(clipMsg.get());
     }
 
-    MessageLoop::current()->
-      PostDelayedTask(FROM_HERE,
-                      new SendRingIndicatorTask(mNumber, mType),
-                      sRingInterval);
+    MessageLoop::current()->PostDelayedTask(
+      MakeAndAddRef<SendRingIndicatorTask>(mNumber, mType), sRingInterval);
+
+    return NS_OK;
   }
 
 private:
   nsString mNumber;
   int mType;
 };
 #endif // MOZ_B2G_RIL
 
-class BluetoothHfpManager::CloseScoTask : public Task
+class BluetoothHfpManager::CloseScoTask : public Runnable
 {
 private:
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(sBluetoothHfpManager);
 
     sBluetoothHfpManager->DisconnectSco();
+
+    return NS_OK;
   }
 };
 
 #ifdef MOZ_B2G_RIL
 static bool
 IsValidDtmf(const char aChar) {
   // Valid DTMF: [*#0-9ABCD]
   if (aChar == '*' || aChar == '#') {
@@ -980,17 +983,17 @@ BluetoothHfpManager::ReceiveSocketData(B
 
     if (msg.Find("AT+BLDN") != -1) {
       NotifyDialer(NS_LITERAL_STRING("BLDN"));
     } else {
       NotifyDialer(NS_ConvertUTF8toUTF16(msg));
     }
 
     MessageLoop::current()->
-      PostDelayedTask(FROM_HERE, new RespondToBLDNTask(),
+      PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
                       sWaitingForDialingInterval);
 
     // Don't send response 'OK' here because we'll respond later in either
     // RespondToBLDNTask or HandleCallStateChanged()
     return;
   } else if (msg.Find("ATA") != -1) {
     NotifyDialer(NS_LITERAL_STRING("ATA"));
   } else if (msg.Find("AT+CHUP") != -1) {
@@ -1571,19 +1574,18 @@ BluetoothHfpManager::HandleCallStateChan
         }
 
         nsAutoString number(aNumber);
         if (!mCLIP) {
           number.Truncate();
         }
 
         MessageLoop::current()->PostDelayedTask(
-          FROM_HERE,
-          new SendRingIndicatorTask(number,
-                                    mCurrentCallArray[aCallIndex].mType),
+          MakeAndAddRef<SendRingIndicatorTask>(
+            number, mCurrentCallArray[aCallIndex].mType),
           sRingInterval);
       }
       break;
     case nsITelephonyService::CALL_STATE_DIALING:
       if (!mDialingRequestProcessed) {
         SendLine("OK");
         mDialingRequestProcessed = true;
       }
@@ -1681,18 +1683,17 @@ BluetoothHfpManager::HandleCallStateChan
       if (mCurrentCallArray.Length() - 1 ==
           GetNumberOfCalls(nsITelephonyService::CALL_STATE_DISCONNECTED)) {
         // In order to let user hear busy tone via connected Bluetooth headset,
         // we postpone the timing of dropping SCO.
         if (!(aError.Equals(NS_LITERAL_STRING("BusyError")))) {
           DisconnectSco();
         } else {
           // Close Sco later since Dialer is still playing busy tone via HF.
-          MessageLoop::current()->PostDelayedTask(FROM_HERE,
-                                                  new CloseScoTask(),
+          MessageLoop::current()->PostDelayedTask(MakeAndAddRef<CloseScoTask>(),
                                                   sBusyToneInterval);
         }
 
         ResetCallArray();
       }
       break;
     default:
       BT_WARNING("Not handling state changed");
--- a/dom/bluetooth/bluez/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothOppManager.cpp
@@ -162,32 +162,33 @@ public:
     return NS_OK;
   };
 
 private:
   nsCOMPtr<nsIInputStream> mInputStream;
   uint32_t mAvailablePacketSize;
 };
 
-class CloseSocketTask : public Task
+class CloseSocketTask : public Runnable
 {
 public:
   CloseSocketTask(BluetoothSocket* aSocket) : mSocket(aSocket)
   {
     MOZ_ASSERT(aSocket);
   }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (mSocket->GetConnectionStatus() ==
         SocketConnectionStatus::SOCKET_CONNECTED) {
       mSocket->Close();
     }
+    return NS_OK;
   }
 
 private:
   RefPtr<BluetoothSocket> mSocket;
 };
 
 BluetoothOppManager::BluetoothOppManager()
   : mConnected(false)
@@ -1071,17 +1072,17 @@ BluetoothOppManager::ClientDataHandler(U
     FileTransferComplete();
   } else if (mLastCommand == ObexRequestCode::Disconnect) {
     AfterOppDisconnected();
     // Most devices will directly terminate connection after receiving
     // Disconnect request, so we make a delay here. If the socket hasn't been
     // disconnected, we will close it.
     if (mSocket) {
       MessageLoop::current()->
-        PostDelayedTask(FROM_HERE, new CloseSocketTask(mSocket), 1000);
+        PostDelayedTask(MakeAndAddRef<CloseSocketTask>(mSocket), 1000);
     }
   } else if (mLastCommand == ObexRequestCode::Connect) {
     MOZ_ASSERT(!mFileName.IsEmpty());
     MOZ_ASSERT(mBlob);
 
     AfterOppConnected();
 
     // Ensure valid access to remote information
--- a/dom/bluetooth/bluez/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluez/BluetoothSocket.cpp
@@ -38,17 +38,17 @@ public:
   void GetSocketAddr(BluetoothAddress& aAddress) const;
 
   BluetoothSocket* GetBluetoothSocket();
   DataSocket* GetDataSocket();
 
   // Delayed-task handling
   //
 
-  void SetDelayedConnectTask(CancelableTask* aTask);
+  void SetDelayedConnectTask(CancelableRunnable* aTask);
   void ClearDelayedConnectTask();
   void CancelDelayedConnectTask();
 
   // Task callback methods
   //
 
   /**
    * Run bind/listen to prepare for further runs of accept()
@@ -121,17 +121,17 @@ private:
    * Address structure of the socket currently in use
    */
   struct sockaddr_storage mAddress;
 
   /**
    * Task member for delayed connect task. Should only be access on consumer
    * thread.
    */
-  CancelableTask* mDelayedConnectTask;
+  CancelableRunnable* mDelayedConnectTask;
 
   /**
    * I/O buffer for received data
    */
   UniquePtr<UnixSocketRawData> mBuffer;
 };
 
 BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO(
@@ -188,17 +188,17 @@ BluetoothSocket::BluetoothSocketIO::GetB
 
 DataSocket*
 BluetoothSocket::BluetoothSocketIO::GetDataSocket()
 {
   return GetBluetoothSocket();
 }
 
 void
-BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
+BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableRunnable* aTask)
 {
   MOZ_ASSERT(IsConsumerThread());
 
   mDelayedConnectTask = aTask;
 }
 
 void
 BluetoothSocket::BluetoothSocketIO::ClearDelayedConnectTask()
@@ -280,17 +280,17 @@ BluetoothSocket::BluetoothSocketIO::Send
 
 void
 BluetoothSocket::BluetoothSocketIO::OnConnected()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
 
   GetConsumerThread()->PostTask(
-    FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
+    MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
 
   AddWatchers(READ_WATCHER, true);
   if (HasPendingData()) {
     AddWatchers(WRITE_WATCHER, false);
   }
 }
 
 void
@@ -329,17 +329,17 @@ BluetoothSocket::BluetoothSocketIO::OnSo
     FireSocketError();
     return;
   }
 
   Close();
   SetSocket(fd, SOCKET_IS_CONNECTED);
 
   GetConsumerThread()->PostTask(
-    FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
+    MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
 
   AddWatchers(READ_WATCHER, true);
   if (HasPendingData()) {
     AddWatchers(WRITE_WATCHER, false);
   }
 }
 
 void
@@ -379,17 +379,17 @@ BluetoothSocket::BluetoothSocketIO::Fire
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
 
   // Clean up watchers, statuses, fds
   Close();
 
   // Tell the consumer thread we've errored
   GetConsumerThread()->PostTask(
-    FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_ERROR));
+    MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_ERROR));
 }
 
 // |DataSocketIO|
 
 nsresult
 BluetoothSocket::BluetoothSocketIO::QueryReceiveBuffer(
   UnixSocketIOBuffer** aBuffer)
 {
@@ -411,43 +411,45 @@ class BluetoothSocket::BluetoothSocketIO
   : public SocketTask<BluetoothSocketIO>
 {
 public:
   ReceiveTask(BluetoothSocketIO* aIO, UnixSocketBuffer* aBuffer)
     : SocketTask<BluetoothSocketIO>(aIO)
     , mBuffer(aBuffer)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     BluetoothSocketIO* io = SocketTask<BluetoothSocketIO>::GetIO();
 
     MOZ_ASSERT(io->IsConsumerThread());
 
     if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
       // Since we've already explicitly closed and the close
       // happened before this, this isn't really an error.
-      return;
+      return NS_OK;
     }
 
     BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
     MOZ_ASSERT(bluetoothSocket);
 
     bluetoothSocket->ReceiveSocketData(mBuffer);
+
+    return NS_OK;
   }
 
 private:
   UniquePtr<UnixSocketBuffer> mBuffer;
 };
 
 void
 BluetoothSocket::BluetoothSocketIO::ConsumeBuffer()
 {
-  GetConsumerThread()->PostTask(FROM_HERE,
-                                new ReceiveTask(this, mBuffer.release()));
+  GetConsumerThread()->PostTask(
+    MakeAndAddRef<ReceiveTask>(this, mBuffer.release()));
 }
 
 void
 BluetoothSocket::BluetoothSocketIO::DiscardBuffer()
 {
   // Nothing to do.
 }
 
@@ -500,66 +502,71 @@ BluetoothSocket::BluetoothSocketIO::Shut
 class BluetoothSocket::ListenTask final
   : public SocketIOTask<BluetoothSocketIO>
 {
 public:
   ListenTask(BluetoothSocketIO* aIO)
     : SocketIOTask<BluetoothSocketIO>(aIO)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!GetIO()->IsConsumerThread());
 
     if (!IsCanceled()) {
       GetIO()->Listen();
     }
+    return NS_OK;
   }
 };
 
 class BluetoothSocket::ConnectTask final
   : public SocketIOTask<BluetoothSocketIO>
 {
 public:
   ConnectTask(BluetoothSocketIO* aIO)
     : SocketIOTask<BluetoothSocketIO>(aIO)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!GetIO()->IsConsumerThread());
     MOZ_ASSERT(!IsCanceled());
 
     GetIO()->Connect();
+
+    return NS_OK;
   }
 };
 
 class BluetoothSocket::DelayedConnectTask final
   : public SocketIOTask<BluetoothSocketIO>
 {
 public:
   DelayedConnectTask(BluetoothSocketIO* aIO)
     : SocketIOTask<BluetoothSocketIO>(aIO)
   { }
 
-  void Run() override
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(GetIO()->IsConsumerThread());
 
     if (IsCanceled()) {
-      return;
+      return NS_OK;
     }
 
     BluetoothSocketIO* io = GetIO();
     if (io->IsShutdownOnConsumerThread()) {
-      return;
+      return NS_OK;
     }
 
     io->ClearDelayedConnectTask();
-    io->GetIOLoop()->PostTask(FROM_HERE, new ConnectTask(io));
+    io->GetIOLoop()->PostTask(MakeAndAddRef<ConnectTask>(io));
+
+    return NS_OK;
   }
 };
 
 //
 // BluetoothSocket
 //
 
 BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
@@ -665,21 +672,22 @@ BluetoothSocket::Connect(BluetoothUnixSo
   MOZ_ASSERT(aConsumerLoop);
   MOZ_ASSERT(aIOLoop);
   MOZ_ASSERT(!mIO);
 
   mIO = new BluetoothSocketIO(aConsumerLoop, aIOLoop, this, aConnector);
   SetConnectionStatus(SOCKET_CONNECTING);
 
   if (aDelayMs > 0) {
-    DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
+    RefPtr<DelayedConnectTask> connectTask =
+      MakeAndAddRef<DelayedConnectTask>(mIO);
     mIO->SetDelayedConnectTask(connectTask);
-    MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
+    MessageLoop::current()->PostDelayedTask(connectTask.forget(), aDelayMs);
   } else {
-    aIOLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
+    aIOLoop->PostTask(MakeAndAddRef<ConnectTask>(mIO));
   }
 
   return NS_OK;
 }
 
 nsresult
 BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
                          int aDelayMs)
@@ -695,17 +703,17 @@ BluetoothSocket::Listen(BluetoothUnixSoc
   MOZ_ASSERT(aConnector);
   MOZ_ASSERT(aConsumerLoop);
   MOZ_ASSERT(aIOLoop);
   MOZ_ASSERT(!mIO);
 
   mIO = new BluetoothSocketIO(aConsumerLoop, aIOLoop, this, aConnector);
   SetConnectionStatus(SOCKET_LISTENING);
 
-  aIOLoop->PostTask(FROM_HERE, new ListenTask(mIO));
+  aIOLoop->PostTask(MakeAndAddRef<ListenTask>(mIO));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector)
 {
   return Listen(aConnector, MessageLoop::current(), XRE_GetIOMessageLoop());
@@ -728,18 +736,17 @@ BluetoothSocket::GetAddress(BluetoothAdd
 void
 BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
 {
   MOZ_ASSERT(mIO);
   MOZ_ASSERT(mIO->IsConsumerThread());
   MOZ_ASSERT(!mIO->IsShutdownOnConsumerThread());
 
   mIO->GetIOLoop()->PostTask(
-    FROM_HERE,
-    new SocketIOSendTask<BluetoothSocketIO, UnixSocketIOBuffer>(mIO, aBuffer));
+    MakeAndAddRef<SocketIOSendTask<BluetoothSocketIO, UnixSocketIOBuffer>>(mIO, aBuffer));
 }
 
 // |SocketBase|
 
 void
 BluetoothSocket::Close()
 {
   if (!mIO) {
@@ -749,17 +756,17 @@ BluetoothSocket::Close()
   MOZ_ASSERT(mIO->IsConsumerThread());
 
   mIO->CancelDelayedConnectTask();
 
   // From this point on, we consider mIO as being deleted.
   // We sever the relationship here so any future calls to listen or connect
   // will create a new implementation.
   mIO->ShutdownOnConsumerThread();
-  mIO->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
+  mIO->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mIO));
   mIO = nullptr;
 
   NotifyDisconnect();
 }
 
 void
 BluetoothSocket::OnConnectSuccess()
 {
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -68,17 +68,18 @@ GetPrincipalFromWorkerPrivate(WorkerPriv
 }
 
 class InitializeRunnable final : public WorkerMainThreadRunnable
 {
 public:
   InitializeRunnable(WorkerPrivate* aWorkerPrivate, nsACString& aOrigin,
                      PrincipalInfo& aPrincipalInfo, bool& aPrivateBrowsing,
                      ErrorResult& aRv)
-    : WorkerMainThreadRunnable(aWorkerPrivate)
+    : WorkerMainThreadRunnable(aWorkerPrivate,
+                               NS_LITERAL_CSTRING("BroadcastChannel :: Initialize"))
     , mWorkerPrivate(GetCurrentThreadWorkerPrivate())
     , mOrigin(aOrigin)
     , mPrincipalInfo(aPrincipalInfo)
     , mPrivateBrowsing(aPrivateBrowsing)
     , mRv(aRv)
   {
     MOZ_ASSERT(mWorkerPrivate);
   }
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -264,17 +264,18 @@ class CreateImageFromRawDataInMainThread
 public:
   CreateImageFromRawDataInMainThreadSyncTask(uint8_t* aBuffer,
                                              uint32_t aBufferLength,
                                              uint32_t aStride,
                                              gfx::SurfaceFormat aFormat,
                                              const gfx::IntSize& aSize,
                                              const Maybe<IntRect>& aCropRect,
                                              layers::Image** aImage)
-  : WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate())
+  : WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate(),
+                               NS_LITERAL_CSTRING("ImageBitmap :: Create Image from Raw Data"))
   , mImage(aImage)
   , mBuffer(aBuffer)
   , mBufferLength(aBufferLength)
   , mStride(aStride)
   , mFormat(aFormat)
   , mSize(aSize)
   , mCropRect(aCropRect)
   {
@@ -1145,17 +1146,18 @@ class CreateImageBitmapFromBlobWorkerTas
   // This is a synchronous task.
   class DecodeBlobInMainThreadSyncTask final : public WorkerMainThreadRunnable
   {
   public:
     DecodeBlobInMainThreadSyncTask(WorkerPrivate* aWorkerPrivate,
                                    Blob& aBlob,
                                    Maybe<IntRect>& aCropRect,
                                    layers::Image** aImage)
-    : WorkerMainThreadRunnable(aWorkerPrivate)
+    : WorkerMainThreadRunnable(aWorkerPrivate,
+                               NS_LITERAL_CSTRING("ImageBitmap :: Create Image from Blob"))
     , mBlob(aBlob)
     , mCropRect(aCropRect)
     , mImage(aImage)
     {
     }
 
     bool MainThreadRun() override
     {
--- a/dom/downloads/tests/shim_app_as_test.js
+++ b/dom/downloads/tests/shim_app_as_test.js
@@ -1,16 +1,10 @@
 /**
- * Support logic to run a test file as an installed app.  This file is derived
- * from dom/requestsync/tests/test_basic_app.html but uses
- * DOMApplicationRegistry in a chrome script (shim_app_as_test_chrome.js) to
- * directly install the apps instead of mozApps.install because mozApps.install
- * can't install privileged/certified apps.  (This is the same mechanism used by
- * the Firefox OS Gaia email app's backend test runner.)
- *
+ * Support logic to run a test file as an installed app.
  * You really only want to do this if your test cares about the app's origin
  * or you REALLY want to double-check AvailableIn and other WebIDL-provided
  * security mechanisms.
  *
  * If you trust WebIDL, your life may be made significantly easier by just
  * setting the pref "dom.ignore_webidl_scope_checks" to true, which makes
  * BindingUtils.cpp's IsInPrivilegedApp and IsInCertifiedApp return true no
  * matter what *on the main thread*.  You are potentially out of luck on
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -967,17 +967,17 @@ DataTransfer::GetTransferables(nsIDOMNod
 {
   MOZ_ASSERT(aDragTarget);
 
   nsCOMPtr<nsINode> dragNode = do_QueryInterface(aDragTarget);
   if (!dragNode) {
     return nullptr;
   }
 
-  nsIDocument* doc = dragNode->GetUncomposedDoc();
+  nsIDocument* doc = dragNode->GetComposedDoc();
   if (!doc) {
     return nullptr;
   }
 
   return GetTransferables(doc->GetLoadContext());
 }
 
 already_AddRefed<nsISupportsArray>
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -192,8 +192,10 @@ skip-if = buildapp == 'b2g' || e10s
 [test_bug1096146.html]
 support-files =
   bug1096146_embedded.html
 [test_offsetxy.html]
 [test_eventhandler_scoping.html]
 [test_bug1013412.html]
 skip-if = buildapp == 'b2g' # no wheel events on b2g
 [test_dom_activate_event.html]
+[test_bug1264380.html]
+run-if = e10s # bug1264380 comment 20, nsDragService::InvokeDragSessionImpl behaves differently among platform implementations in non-e10s mode which prevents us to check the validity of nsIDragService::getCurrentSession() consistently via synthesize mouse clicks in non-e10s mode.
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1264380.html
@@ -0,0 +1,54 @@
+<html>
+<head>
+  <title>Test the dragstart event on the anchor in side shadow DOM</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+<script>
+
+SimpleTest.waitForExplicitFinish();
+
+SpecialPowers.pushPrefEnv({"set": [
+  ["dom.webcomponents.enabled", true]
+]});
+
+function runTests()
+{
+  let dragService = SpecialPowers.Cc["@mozilla.org/widget/dragservice;1"].
+    getService(SpecialPowers.Ci.nsIDragService);
+
+  let shadow = document.querySelector('#outter').createShadowRoot();
+  let target = document.createElement('a');
+  let linkText = document.createTextNode("Drag me if you can!");
+  target.appendChild(linkText);
+  target.href = "http://www.mozilla.org/";
+  shadow.appendChild(target);
+
+  let dataTransfer;
+  let trapDrag = function(event) {
+    ok(true, "Got dragstart event");
+    dataTransfer = event.dataTransfer;
+    ok(dataTransfer, "DataTransfer object is available.");
+    is(dataTransfer.mozItemCount, 1, "initial link item count");
+    is(dataTransfer.getData("text/uri-list"), "http://www.mozilla.org/", "link text/uri-list");
+    is(dataTransfer.getData("text/plain"), "http://www.mozilla.org/", "link text/plain");
+  }
+
+  ok(!dragService.getCurrentSession(), "There shouldn't be a drag session!");
+  window.addEventListener("dragstart", trapDrag, true);
+  synthesizeMouse(target, 2, 2, { type: "mousedown" });
+  synthesizeMouse(target, 11, 11, { type: "mousemove" });
+  synthesizeMouse(target, 20, 20, { type: "mousemove" });
+  window.removeEventListener("dragstart", trapDrag, true);
+  ok(dragService.getCurrentSession(), "Drag session is available.");
+  dragService.endDragSession(false);
+  ok(!dragService.getCurrentSession(), "There shouldn't be a drag session anymore!");
+  SimpleTest.finish();
+}
+
+</script>
+
+<body onload="window.setTimeout(runTests, 0);">
+<div id="outter"/>
+</body>
+</html>
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -713,17 +713,18 @@ public:
 };
 
 template <class Derived>
 class CancelPumpRunnable final : public WorkerMainThreadRunnable
 {
   FetchBody<Derived>* mBody;
 public:
   explicit CancelPumpRunnable(FetchBody<Derived>* aBody)
-    : WorkerMainThreadRunnable(aBody->mWorkerPrivate)
+    : WorkerMainThreadRunnable(aBody->mWorkerPrivate,
+                               NS_LITERAL_CSTRING("Fetch :: Cancel Pump"))
     , mBody(aBody)
   { }
 
   bool
   MainThreadRun() override
   {
     mBody->CancelPump();
     return true;
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -226,17 +226,18 @@ GetRequestURLFromWorker(const GlobalObje
 }
 
 class ReferrerSameOriginChecker final : public workers::WorkerMainThreadRunnable
 {
 public:
   ReferrerSameOriginChecker(workers::WorkerPrivate* aWorkerPrivate,
                             const nsAString& aReferrerURL,
                             nsresult& aResult)
-    : workers::WorkerMainThreadRunnable(aWorkerPrivate),
+    : workers::WorkerMainThreadRunnable(aWorkerPrivate,
+                                        NS_LITERAL_CSTRING("Fetch :: Referrer same origin check")),
       mReferrerURL(aReferrerURL),
       mResult(aResult)
   {
     mWorkerPrivate->AssertIsOnWorkerThread();
   }
 
   bool
   MainThreadRun() override
--- a/dom/html/HTMLSharedObjectElement.cpp
+++ b/dom/html/HTMLSharedObjectElement.cpp
@@ -15,18 +15,18 @@
 #include "nsIDOMDocument.h"
 #include "nsThreadUtils.h"
 #include "nsIScriptError.h"
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
 #ifdef XP_MACOSX
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/dom/Event.h"
+#endif
 #include "mozilla/dom/HTMLObjectElement.h"
-#endif
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
 
 namespace mozilla {
 namespace dom {
 
 HTMLSharedObjectElement::HTMLSharedObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
@@ -80,17 +80,17 @@ void
 HTMLSharedObjectElement::DoneAddingChildren(bool aHaveNotified)
 {
   if (!mIsDoneAddingChildren) {
     mIsDoneAddingChildren = true;
 
     // If we're already in a document, we need to trigger the load
     // Otherwise, BindToTree takes care of that.
     if (IsInComposedDoc()) {
-      StartObjectLoad(aHaveNotified);
+      StartObjectLoad(aHaveNotified, false);
     }
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLSharedObjectElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLSharedObjectElement,
                                                   nsGenericHTMLElement)
@@ -317,26 +317,26 @@ HTMLSharedObjectElement::GetAttributeMap
   if (mNodeInfo->Equals(nsGkAtoms::embed)) {
     return &MapAttributesIntoRuleExceptHidden;
   }
 
   return &MapAttributesIntoRule;
 }
 
 void
-HTMLSharedObjectElement::StartObjectLoad(bool aNotify)
+HTMLSharedObjectElement::StartObjectLoad(bool aNotify, bool aForceLoad)
 {
   // BindToTree can call us asynchronously, and we may be removed from the tree
   // in the interim
   if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
       BlockEmbedContentLoading()) {
     return;
   }
 
-  LoadObject(aNotify);
+  LoadObject(aNotify, aForceLoad);
   SetIsNetworkCreated(false);
 }
 
 EventStates
 HTMLSharedObjectElement::IntrinsicState() const
 {
   return nsGenericHTMLElement::IntrinsicState() | ObjectState();
 }
@@ -411,14 +411,23 @@ HTMLSharedObjectElement::BlockEmbedConte
     return false;
   }
   // Traverse up the node tree to see if we have any ancestors that may block us
   // from loading
   for (nsIContent* parent = GetParent(); parent; parent = parent->GetParent()) {
     if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
       return true;
     }
+    // If we have an ancestor that is an object with a source, it'll have an
+    // associated displayed type. If that type is not null, don't load content
+    // for the embed.
+    if (HTMLObjectElement* object = HTMLObjectElement::FromContent(parent)) {
+      uint32_t type = object->DisplayedType();
+      if (type != eType_Null) {
+        return true;
+      }
+    }
   }
   return false;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLSharedObjectElement.h
+++ b/dom/html/HTMLSharedObjectElement.h
@@ -75,17 +75,17 @@ public:
 
   // nsObjectLoadingContent
   virtual uint32_t GetCapabilities() const override;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
   nsresult CopyInnerTo(Element* aDest);
 
-  void StartObjectLoad() { StartObjectLoad(true); }
+  void StartObjectLoad() { StartObjectLoad(true, false); }
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLSharedObjectElement,
                                                      nsGenericHTMLElement)
 
   // WebIDL API for <applet>
   void GetAlign(DOMString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::align, aValue);
@@ -187,23 +187,22 @@ public:
   // height covered by <applet>
   // align covered by <applet>
   // name covered by <applet>
   nsIDocument* GetSVGDocument()
   {
     return GetContentDocument();
   }
 
-private:
-  virtual ~HTMLSharedObjectElement();
-
   /**
    * Calls LoadObject with the correct arguments to start the plugin load.
    */
-  void StartObjectLoad(bool aNotify);
+  void StartObjectLoad(bool aNotify, bool aForceLoad);
+private:
+  virtual ~HTMLSharedObjectElement();
 
   nsIAtom *URIAttrName() const
   {
     return mNodeInfo->Equals(nsGkAtoms::applet) ?
            nsGkAtoms::code :
            nsGkAtoms::src;
   }
 
@@ -223,16 +222,18 @@ private:
 
   /**
    * Decides whether we should load embed node content.
    *
    * If this is an embed node there are cases in which we should not try to load
    * the content:
    *
    * - If the embed node is the child of a media element
+   * - If the embed node is the child of an object node that already has
+   *   content being loaded.
    *
    * In these cases, this function will return false, which will cause
    * us to skip calling LoadObject.
    */
   bool BlockEmbedContentLoading();
 };
 
 } // namespace dom
--- a/dom/html/nsHTMLDNSPrefetch.cpp
+++ b/dom/html/nsHTMLDNSPrefetch.cpp
@@ -315,17 +315,17 @@ nsHTMLDNSPrefetch::nsDeferrals::SubmitQu
   while (mHead != mTail) {
     nsCOMPtr<nsIContent> content = do_QueryReferent(mEntries[mTail].mElement);
     if (content) {
       nsCOMPtr<Link> link = do_QueryInterface(content);
       // Only prefetch here if request was deferred and deferral not cancelled
       if (link && link->HasDeferredDNSPrefetchRequest()) {
         nsCOMPtr<nsIURI> hrefURI(link ? link->GetURI() : nullptr);
         bool isLocalResource = false;
-        nsresult rv;
+        nsresult rv = NS_OK;
 
         hostName.Truncate();
         if (hrefURI) {
           hrefURI->GetAsciiHost(hostName);
           rv = NS_URIChainHasFlags(hrefURI,
                                    nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
                                    &isLocalResource);
         }
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -676,17 +676,17 @@ IDBDatabase::Transaction(JSContext* aCx,
     case IDBTransactionMode::Readwriteflush:
       mode = IDBTransaction::READ_WRITE_FLUSH;
       break;
     case IDBTransactionMode::Cleanup:
       mode = IDBTransaction::CLEANUP;
       mQuotaExceeded = false;
       break;
     case IDBTransactionMode::Versionchange:
-      return NS_ERROR_DOM_INVALID_ACCESS_ERR;
+      return NS_ERROR_DOM_TYPE_ERR;
 
     default:
       MOZ_CRASH("Unknown mode!");
   }
 
   RefPtr<IDBTransaction> transaction =
     IDBTransaction::Create(aCx, this, sortedStoreNames, mode);
   if (NS_WARN_IF(!transaction)) {
--- a/dom/indexedDB/test/unit/test_transaction_error.js
+++ b/dom/indexedDB/test/unit/test_transaction_error.js
@@ -30,16 +30,24 @@ function testSteps() {
 
   request.onupgradeneeded = unexpectedSuccessHandler;
   request.onsuccess = grabEventAndContinueHandler;
 
   event = yield undefined;
 
   db = event.target.result;
 
+  try {
+    db.transaction(objectStoreName, "versionchange");
+    ok(false, "TypeError shall be thrown if transaction mode is wrong.");
+  } catch (e) {
+    ok(e instanceof DOMException, "got a database exception");
+    is(e.name, "TypeError", "correct error");
+  }
+
   let transaction = db.transaction(objectStoreName, "readwrite");
   transaction.onerror = grabEventAndContinueHandler;
   transaction.oncomplete = grabEventAndContinueHandler;
 
   objectStore = transaction.objectStore(objectStoreName);
 
   info("Adding duplicate entry with preventDefault()");
 
--- a/dom/ipc/NuwaChild.cpp
+++ b/dom/ipc/NuwaChild.cpp
@@ -89,17 +89,17 @@ void
 NuwaFork()
 {
   if (sNuwaForking) {           // No reentry.
       return;
   }
   sNuwaForking = true;
 
   MessageLoop* ioloop = XRE_GetIOMessageLoop();
-  ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork));
+  ioloop->PostTask(NewRunnableFunction(RunNuwaFork));
 }
 
 } // Anonymous namespace.
 
 #endif
 
 NuwaChild* NuwaChild::sSingleton;
 
--- a/dom/ipc/PreallocatedProcessManager.cpp
+++ b/dom/ipc/PreallocatedProcessManager.cpp
@@ -63,17 +63,17 @@ public:
   void OnNuwaReady();
   bool PreallocatedProcessReady();
   already_AddRefed<ContentParent> GetSpareProcess();
 
 private:
   void NuwaFork();
 
   // initialization off the critical path of app startup.
-  CancelableTask* mPreallocateAppProcessTask;
+  CancelableRunnable* mPreallocateAppProcessTask;
 
   // The array containing the preallocated processes. 4 as the inline storage size
   // should be enough so we don't need to grow the AutoTArray.
   AutoTArray<RefPtr<ContentParent>, 4> mSpareProcesses;
 
   // Nuwa process is ready for creating new process.
   bool mIsNuwaReady;
 #endif
@@ -238,17 +238,17 @@ PreallocatedProcessManagerImpl::Schedule
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mPreallocateAppProcessTask) {
     // Make sure there is only one request running.
     return;
   }
 
-  RefPtr<CancelableTask> task = NewRunnableMethod(
+  RefPtr<CancelableRunnable> task = NewRunnableMethod(
     this, &PreallocatedProcessManagerImpl::DelayedNuwaFork);
   mPreallocateAppProcessTask = task;
   MessageLoop::current()->PostDelayedTask(task.forget(),
     Preferences::GetUint("dom.ipc.processPrelaunch.delayMs",
                          DEFAULT_ALLOCATE_DELAY));
 }
 
 void
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaCallbackID.cpp
@@ -0,0 +1,50 @@
+#include "MediaCallbackID.h"
+
+namespace mozilla {
+
+char const* CallbackID::INVALID_TAG = "INVALID_TAG";
+int32_t const CallbackID::INVALID_ID = -1;
+
+CallbackID::CallbackID()
+  : mTag(INVALID_TAG), mID(INVALID_ID)
+{
+}
+
+CallbackID::CallbackID(char const* aTag, int32_t aID /* = 0*/)
+  : mTag(aTag), mID(aID)
+{
+}
+
+CallbackID&
+CallbackID::operator++()
+{
+  ++mID;
+  return *this;
+}
+
+CallbackID
+CallbackID::operator++(int)
+{
+  CallbackID ret = *this;
+  ++(*this); // call prefix++
+  return ret;
+}
+
+bool
+CallbackID::operator==(const CallbackID& rhs) const
+{
+  return (strcmp(mTag, rhs.mTag) == 0) && (mID == rhs.mID);
+}
+
+bool
+CallbackID::operator!=(const CallbackID& rhs) const
+{
+  return !(*this == rhs);
+}
+
+CallbackID::operator int() const
+{
+  return mID;
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaCallbackID.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 MediaCallbackID_h_
+#define MediaCallbackID_h_
+
+namespace mozilla {
+
+struct CallbackID
+{
+  static char const* INVALID_TAG;
+  static int32_t const INVALID_ID;
+
+  CallbackID();
+
+  explicit CallbackID(char const* aTag, int32_t aID = 0);
+
+  CallbackID& operator++();   // prefix++
+
+  CallbackID operator++(int); // postfix++
+
+  bool operator==(const CallbackID& rhs) const;
+
+  bool operator!=(const CallbackID& rhs) const;
+
+  operator int() const;
+
+private:
+  char const* mTag;
+  int32_t mID;
+};
+
+} // namespace mozilla
+
+#endif // MediaCallbackID_h_
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -217,18 +217,18 @@ private:
   // aligned and that it has sufficient end padding to allow for Alignment bytes
   // block read as required by some data decoders.
   // Returns false if memory couldn't be allocated.
   bool EnsureCapacity(size_t aLength)
   {
     const CheckedInt<size_t> sizeNeeded =
       CheckedInt<size_t>(aLength) * sizeof(Type) + AlignmentPaddingSize();
 
-    if (!sizeNeeded.isValid()) {
-      // overflow.
+    if (!sizeNeeded.isValid() || sizeNeeded.value() >= INT32_MAX) {
+      // overflow or over an acceptable size.
       return false;
     }
     if (mData && mCapacity >= sizeNeeded.value()) {
       return true;
     }
     auto newBuffer = MakeUniqueFallible<uint8_t[]>(sizeNeeded.value());
     if (!newBuffer) {
       return false;
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -139,16 +139,18 @@ private:
 };
 
 MediaDecoderReaderWrapper::MediaDecoderReaderWrapper(bool aIsRealTime,
                                                      AbstractThread* aOwnerThread,
                                                      MediaDecoderReader* aReader)
   : mForceZeroStartTime(aIsRealTime || aReader->ForceZeroStartTime())
   , mOwnerThread(aOwnerThread)
   , mReader(aReader)
+  , mAudioCallbackID("AudioCallbackID")
+  , mVideoCallbackID("VideoCallbackID")
 {}
 
 MediaDecoderReaderWrapper::~MediaDecoderReaderWrapper()
 {}
 
 media::TimeUnit
 MediaDecoderReaderWrapper::StartTime() const
 {
@@ -173,44 +175,76 @@ MediaDecoderReaderWrapper::ReadMetadata(
 RefPtr<HaveStartTimePromise>
 MediaDecoderReaderWrapper::AwaitStartTime()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
   return mStartTimeRendezvous->AwaitStartTime();
 }
 
-RefPtr<MediaDecoderReaderWrapper::MediaDataPromise>
+void
+MediaDecoderReaderWrapper::CancelAudioCallback(CallbackID aID)
+{
+  MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+  MOZ_ASSERT(aID == mAudioCallbackID);
+  ++mAudioCallbackID;
+  mRequestAudioDataCB = nullptr;
+}
+
+void
+MediaDecoderReaderWrapper::CancelVideoCallback(CallbackID aID)
+{
+  MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+  MOZ_ASSERT(aID == mVideoCallbackID);
+  ++mVideoCallbackID;
+  mRequestVideoDataCB = nullptr;
+}
+
+void
 MediaDecoderReaderWrapper::RequestAudioData()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
+  MOZ_ASSERT(mRequestAudioDataCB, "Request audio data without callback!");
 
   auto p = InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
                        &MediaDecoderReader::RequestAudioData);
 
   if (!mStartTimeRendezvous->HaveStartTime()) {
     p = p->Then(mOwnerThread, __func__, mStartTimeRendezvous.get(),
                 &StartTimeRendezvous::ProcessFirstSample<MediaData::AUDIO_DATA>,
                 &StartTimeRendezvous::FirstSampleRejected<MediaData::AUDIO_DATA>)
          ->CompletionPromise();
   }
 
-  return p->Then(mOwnerThread, __func__, this,
-                 &MediaDecoderReaderWrapper::OnSampleDecoded,
-                 &MediaDecoderReaderWrapper::OnNotDecoded)
-          ->CompletionPromise();
+  RefPtr<MediaDecoderReaderWrapper> self = this;
+  mAudioDataRequest.Begin(p->Then(mOwnerThread, __func__,
+    [self] (MediaData* aAudioSample) {
+      MOZ_ASSERT(self->mRequestAudioDataCB);
+      self->mAudioDataRequest.Complete();
+      self->OnSampleDecoded(self->mRequestAudioDataCB.get(), aAudioSample, TimeStamp());
+    },
+    [self] (MediaDecoderReader::NotDecodedReason aReason) {
+      MOZ_ASSERT(self->mRequestAudioDataCB);
+      self->mAudioDataRequest.Complete();
+      self->OnNotDecoded(self->mRequestAudioDataCB.get(), aReason);
+    }));
 }
 
-RefPtr<MediaDecoderReaderWrapper::MediaDataPromise>
+void
 MediaDecoderReaderWrapper::RequestVideoData(bool aSkipToNextKeyframe,
                                             media::TimeUnit aTimeThreshold)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
+  MOZ_ASSERT(mRequestVideoDataCB, "Request video data without callback!");
+
+  // Time the video decode and send this value back to callbacks who accept
+  // a TimeStamp as its second parameter.
+  TimeStamp videoDecodeStartTime = TimeStamp::Now();
 
   if (aTimeThreshold.ToMicroseconds() > 0 &&
       mStartTimeRendezvous->HaveStartTime()) {
     aTimeThreshold += StartTime();
   }
 
   auto p = InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
                        &MediaDecoderReader::RequestVideoData,
@@ -218,20 +252,42 @@ MediaDecoderReaderWrapper::RequestVideoD
 
   if (!mStartTimeRendezvous->HaveStartTime()) {
     p = p->Then(mOwnerThread, __func__, mStartTimeRendezvous.get(),
                 &StartTimeRendezvous::ProcessFirstSample<MediaData::VIDEO_DATA>,
                 &StartTimeRendezvous::FirstSampleRejected<MediaData::VIDEO_DATA>)
          ->CompletionPromise();
   }
 
-  return p->Then(mOwnerThread, __func__, this,
-                 &MediaDecoderReaderWrapper::OnSampleDecoded,
-                 &MediaDecoderReaderWrapper::OnNotDecoded)
-          ->CompletionPromise();
+  RefPtr<MediaDecoderReaderWrapper> self = this;
+  mVideoDataRequest.Begin(p->Then(mOwnerThread, __func__,
+    [self, videoDecodeStartTime] (MediaData* aVideoSample) {
+      MOZ_ASSERT(self->mRequestVideoDataCB);
+      self->mVideoDataRequest.Complete();
+      self->OnSampleDecoded(self->mRequestVideoDataCB.get(), aVideoSample, videoDecodeStartTime);
+    },
+    [self] (MediaDecoderReader::NotDecodedReason aReason) {
+      MOZ_ASSERT(self->mRequestVideoDataCB);
+      self->mVideoDataRequest.Complete();
+      self->OnNotDecoded(self->mRequestVideoDataCB.get(), aReason);
+    }));
+}
+
+bool
+MediaDecoderReaderWrapper::IsRequestingAudioData() const
+{
+  MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+  return mAudioDataRequest.Exists();
+}
+
+bool
+MediaDecoderReaderWrapper::IsRequestingVidoeData() const
+{
+  MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+  return mVideoDataRequest.Exists();
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
 MediaDecoderReaderWrapper::Seek(SeekTarget aTarget, media::TimeUnit aEndTime)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   aTarget.SetTime(aTarget.GetTime() + StartTime());
   return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
@@ -272,25 +328,34 @@ MediaDecoderReaderWrapper::SetIdle()
     NS_NewRunnableMethod(mReader, &MediaDecoderReader::SetIdle);
   mReader->OwnerThread()->Dispatch(r.forget());
 }
 
 void
 MediaDecoderReaderWrapper::ResetDecode()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+
+  mAudioDataRequest.DisconnectIfExists();
+  mVideoDataRequest.DisconnectIfExists();
+
   nsCOMPtr<nsIRunnable> r =
     NS_NewRunnableMethod(mReader, &MediaDecoderReader::ResetDecode);
   mReader->OwnerThread()->Dispatch(r.forget());
 }
 
 RefPtr<ShutdownPromise>
 MediaDecoderReaderWrapper::Shutdown()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+  MOZ_ASSERT(!mRequestAudioDataCB);
+  MOZ_ASSERT(!mRequestVideoDataCB);
+  MOZ_ASSERT(!mAudioDataRequest.Exists());
+  MOZ_ASSERT(!mVideoDataRequest.Exists());
+
   mShutdown = true;
   if (mStartTimeRendezvous) {
     mStartTimeRendezvous->Destroy();
     mStartTimeRendezvous = nullptr;
   }
   return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
                      &MediaDecoderReader::Shutdown);
 }
@@ -318,17 +383,30 @@ MediaDecoderReaderWrapper::OnMetadataRea
       },
       [] () {
         NS_WARNING("Setting start time on reader failed");
       });
   }
 }
 
 void
-MediaDecoderReaderWrapper::OnSampleDecoded(MediaData* aSample)
+MediaDecoderReaderWrapper::OnSampleDecoded(CallbackBase* aCallback,
+                                           MediaData* aSample,
+                                           TimeStamp aDecodeStartTime)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
-  if (!mShutdown) {
-    aSample->AdjustForStartTime(StartTime().ToMicroseconds());
-  }
+  MOZ_ASSERT(!mShutdown);
+
+  aSample->AdjustForStartTime(StartTime().ToMicroseconds());
+  aCallback->OnResolved(aSample, aDecodeStartTime);
+}
+
+void
+MediaDecoderReaderWrapper::OnNotDecoded(CallbackBase* aCallback,
+                                        MediaDecoderReader::NotDecodedReason aReason)
+{
+  MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+  MOZ_ASSERT(!mShutdown);
+
+  aCallback->OnRejected(aReason);
 }
 
 } // namespace mozilla
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -7,16 +7,17 @@
 #ifndef MediaDecoderReaderWrapper_h_
 #define MediaDecoderReaderWrapper_h_
 
 #include "mozilla/AbstractThread.h"
 #include "mozilla/RefPtr.h"
 #include "nsISupportsImpl.h"
 
 #include "MediaDecoderReader.h"
+#include "MediaCallbackID.h"
 
 namespace mozilla {
 
 class StartTimeRendezvous;
 
 typedef MozPromise<bool, bool, /* isExclusive = */ false> HaveStartTimePromise;
 
 /**
@@ -28,27 +29,230 @@ typedef MozPromise<bool, bool, /* isExcl
 class MediaDecoderReaderWrapper {
   typedef MediaDecoderReader::MetadataPromise MetadataPromise;
   typedef MediaDecoderReader::MediaDataPromise MediaDataPromise;
   typedef MediaDecoderReader::SeekPromise SeekPromise;
   typedef MediaDecoderReader::WaitForDataPromise WaitForDataPromise;
   typedef MediaDecoderReader::BufferedUpdatePromise BufferedUpdatePromise;
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReaderWrapper);
 
+  /*
+   * Type 1: void(MediaData*)
+   *         void(RefPtr<MediaData>)
+   */
+  template <typename T>
+  class ArgType1CheckHelper {
+    template<typename C, typename... Ts>
+    static TrueType
+    test(void(C::*aMethod)(Ts...),
+         decltype((DeclVal<C>().*aMethod)(DeclVal<MediaData*>()), 0));
+
+    template <typename F>
+    static TrueType
+    test(F&&, decltype(DeclVal<F>()(DeclVal<MediaData*>()), 0));
+
+    static FalseType test(...);
+  public:
+    typedef decltype(test(DeclVal<T>(), 0)) Type;
+  };
+
+  template <typename T>
+  struct ArgType1Check : public ArgType1CheckHelper<T>::Type {};
+
+  /*
+   * Type 2: void(MediaData*, TimeStamp)
+   *         void(RefPtr<MediaData>, TimeStamp)
+   *         void(MediaData*, TimeStamp&)
+   *         void(RefPtr<MediaData>, const TimeStamp&&)
+   */
+  template <typename T>
+  class ArgType2CheckHelper {
+
+    template<typename C, typename... Ts>
+    static TrueType
+    test(void(C::*aMethod)(Ts...),
+         decltype((DeclVal<C>().*aMethod)(DeclVal<MediaData*>(), DeclVal<TimeStamp>()), 0));
+
+    template <typename F>
+    static TrueType
+    test(F&&, decltype(DeclVal<F>()(DeclVal<MediaData*>(), DeclVal<TimeStamp>()), 0));
+
+    static FalseType test(...);
+  public:
+    typedef decltype(test(DeclVal<T>(), 0)) Type;
+  };
+
+  template <typename T>
+  struct ArgType2Check : public ArgType2CheckHelper<T>::Type {};
+
+  struct CallbackBase
+  {
+    virtual ~CallbackBase() {}
+    virtual void OnResolved(MediaData*, TimeStamp) = 0;
+    virtual void OnRejected(MediaDecoderReader::NotDecodedReason) = 0;
+  };
+
+  template<typename ThisType, typename ResolveMethodType, typename RejectMethodType>
+  struct MethodCallback : public CallbackBase
+  {
+    MethodCallback(ThisType* aThis, ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
+      : mThis(aThis), mResolveMethod(aResolveMethod), mRejectMethod(aRejectMethod)
+    {
+    }
+
+    template<typename F>
+    typename EnableIf<ArgType1Check<F>::value, void>::Type
+    CallHelper(MediaData* aSample, TimeStamp)
+    {
+      (mThis->*mResolveMethod)(aSample);
+    }
+
+    template<typename F>
+    typename EnableIf<ArgType2Check<F>::value, void>::Type
+    CallHelper(MediaData* aSample, TimeStamp aDecodeStartTime)
+    {
+      (mThis->*mResolveMethod)(aSample, aDecodeStartTime);
+    }
+
+    void OnResolved(MediaData* aSample, TimeStamp aDecodeStartTime) override
+    {
+      CallHelper<ResolveMethodType>(aSample, aDecodeStartTime);
+    }
+
+    void OnRejected(MediaDecoderReader::NotDecodedReason aReason) override
+    {
+      (mThis->*mRejectMethod)(aReason);
+    }
+
+    RefPtr<ThisType> mThis;
+    ResolveMethodType mResolveMethod;
+    RejectMethodType mRejectMethod;
+  };
+
+  template<typename ResolveFunctionType, typename RejectFunctionType>
+  struct FunctionCallback : public CallbackBase
+  {
+    FunctionCallback(ResolveFunctionType&& aResolveFuntion, RejectFunctionType&& aRejectFunction)
+      : mResolveFuntion(Move(aResolveFuntion)), mRejectFunction(Move(aRejectFunction))
+    {
+    }
+
+    template<typename F>
+    typename EnableIf<ArgType1Check<F>::value, void>::Type
+    CallHelper(MediaData* aSample, TimeStamp)
+    {
+      mResolveFuntion(aSample);
+    }
+
+    template<typename F>
+    typename EnableIf<ArgType2Check<F>::value, void>::Type
+    CallHelper(MediaData* aSample, TimeStamp aDecodeStartTime)
+    {
+      mResolveFuntion(aSample, aDecodeStartTime);
+    }
+
+    void OnResolved(MediaData* aSample, TimeStamp aDecodeStartTime) override
+    {
+      CallHelper<ResolveFunctionType>(aSample, aDecodeStartTime);
+    }
+
+    void OnRejected(MediaDecoderReader::NotDecodedReason aReason) override
+    {
+      mRejectFunction(aReason);
+    }
+
+    ResolveFunctionType mResolveFuntion;
+    RejectFunctionType mRejectFunction;
+  };
+
 public:
   MediaDecoderReaderWrapper(bool aIsRealTime,
                             AbstractThread* aOwnerThread,
                             MediaDecoderReader* aReader);
 
   media::TimeUnit StartTime() const;
   RefPtr<MetadataPromise> ReadMetadata();
   RefPtr<HaveStartTimePromise> AwaitStartTime();
-  RefPtr<MediaDataPromise> RequestAudioData();
-  RefPtr<MediaDataPromise> RequestVideoData(bool aSkipToNextKeyframe,
-                                            media::TimeUnit aTimeThreshold);
+
+  template<typename ThisType, typename ResolveMethodType, typename RejectMethodType>
+  CallbackID
+  SetAudioCallback(ThisType* aThisVal,
+                   ResolveMethodType aResolveMethod,
+                   RejectMethodType aRejectMethod)
+  {
+    MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+    MOZ_ASSERT(!mRequestAudioDataCB,
+               "Please cancel the original callback before setting a new one.");
+
+    mRequestAudioDataCB.reset(
+      new MethodCallback<ThisType, ResolveMethodType, RejectMethodType>(
+            aThisVal, aResolveMethod, aRejectMethod));
+
+    return mAudioCallbackID;
+  }
+
+  template<typename ResolveFunction, typename RejectFunction>
+  CallbackID
+  SetAudioCallback(ResolveFunction&& aResolveFunction,
+                   RejectFunction&& aRejectFunction)
+  {
+    MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+    MOZ_ASSERT(!mRequestAudioDataCB,
+               "Please cancel the original callback before setting a new one.");
+
+    mRequestAudioDataCB.reset(
+      new FunctionCallback<ResolveFunction, RejectFunction>(
+            Move(aResolveFunction), Move(aRejectFunction)));
+
+    return mAudioCallbackID;
+  }
+
+  template<typename ThisType, typename ResolveMethodType, typename RejectMethodType>
+  CallbackID
+  SetVideoCallback(ThisType* aThisVal,
+                   ResolveMethodType aResolveMethod,
+                   RejectMethodType aRejectMethod)
+  {
+    MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+    MOZ_ASSERT(!mRequestVideoDataCB,
+               "Please cancel the original callback before setting a new one.");
+
+    mRequestVideoDataCB.reset(
+      new MethodCallback<ThisType, ResolveMethodType, RejectMethodType>(
+            aThisVal, aResolveMethod, aRejectMethod));
+
+    return mVideoCallbackID;
+  }
+
+  template<typename ResolveFunction, typename RejectFunction>
+  CallbackID
+  SetVideoCallback(ResolveFunction&& aResolveFunction,
+                   RejectFunction&& aRejectFunction)
+  {
+    MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+    MOZ_ASSERT(!mRequestVideoDataCB,
+               "Please cancel the original callback before setting a new one.");
+
+    mRequestVideoDataCB.reset(
+      new FunctionCallback<ResolveFunction, RejectFunction>(
+            Move(aResolveFunction), Move(aRejectFunction)));
+
+    return mVideoCallbackID;
+  }
+
+  void CancelAudioCallback(CallbackID aID);
+  void CancelVideoCallback(CallbackID aID);
+
+  // NOTE: please set callbacks before requesting audio/video data!
+  void RequestAudioData();
+  void RequestVideoData(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
+
+  bool IsRequestingAudioData() const;
+  bool IsRequestingVidoeData() const;
+
   RefPtr<SeekPromise> Seek(SeekTarget aTarget, media::TimeUnit aEndTime);
   RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType);
   RefPtr<BufferedUpdatePromise> UpdateBufferedWithPromise();
   RefPtr<ShutdownPromise> Shutdown();
 
   void ReleaseMediaResources();
   void SetIdle();
   void ResetDecode();
@@ -91,22 +295,35 @@ public:
   void SetCDMProxy(CDMProxy* aProxy) { mReader->SetCDMProxy(aProxy); }
 #endif
 
 private:
   ~MediaDecoderReaderWrapper();
 
   void OnMetadataRead(MetadataHolder* aMetadata);
   void OnMetadataNotRead() {}
-  void OnSampleDecoded(MediaData* aSample);
-  void OnNotDecoded() {}
+  void OnSampleDecoded(CallbackBase* aCallback, MediaData* aSample,
+                       TimeStamp aVideoDecodeStartTime);
+  void OnNotDecoded(CallbackBase* aCallback,
+                    MediaDecoderReader::NotDecodedReason aReason);
 
   const bool mForceZeroStartTime;
   const RefPtr<AbstractThread> mOwnerThread;
   const RefPtr<MediaDecoderReader> mReader;
 
   bool mShutdown = false;
   RefPtr<StartTimeRendezvous> mStartTimeRendezvous;
+
+  UniquePtr<CallbackBase> mRequestAudioDataCB;
+  UniquePtr<CallbackBase> mRequestVideoDataCB;
+  MozPromiseRequestHolder<MediaDataPromise> mAudioDataRequest;
+  MozPromiseRequestHolder<MediaDataPromise> mVideoDataRequest;
+
+  /*
+   * These callback ids are used to prevent mis-canceling callback.
+   */
+  CallbackID mAudioCallbackID;
+  CallbackID mVideoCallbackID;
 };
 
 } // namespace mozilla
 
 #endif // MediaDecoderReaderWrapper_h_
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -347,16 +347,19 @@ MediaDecoderStateMachine::Initialization
   mWatchManager.Watch(mVideoCompleted, &MediaDecoderStateMachine::UpdateNextFrameStatus);
   mWatchManager.Watch(mVolume, &MediaDecoderStateMachine::VolumeChanged);
   mWatchManager.Watch(mLogicalPlaybackRate, &MediaDecoderStateMachine::LogicalPlaybackRateChanged);
   mWatchManager.Watch(mPreservesPitch, &MediaDecoderStateMachine::PreservesPitchChanged);
   mWatchManager.Watch(mEstimatedDuration, &MediaDecoderStateMachine::RecomputeDuration);
   mWatchManager.Watch(mExplicitDuration, &MediaDecoderStateMachine::RecomputeDuration);
   mWatchManager.Watch(mObservedDuration, &MediaDecoderStateMachine::RecomputeDuration);
   mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
+
+  // Configure MediaDecoderReaderWrapper.
+  SetMediaDecoderReaderWrapperCallback();
 }
 
 media::MediaSink*
 MediaDecoderStateMachine::CreateAudioSink()
 {
   RefPtr<MediaDecoderStateMachine> self = this;
   auto audioSinkCreator = [self] () {
     MOZ_ASSERT(self->OnTaskQueue());
@@ -555,17 +558,16 @@ MediaDecoderStateMachine::NeedToDecodeAu
 void
 MediaDecoderStateMachine::OnAudioDecoded(MediaData* aAudioSample)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
 
   RefPtr<MediaData> audio(aAudioSample);
   MOZ_ASSERT(audio);
-  mAudioDataRequest.Complete();
 
   // audio->GetEndTime() is not always mono-increasing in chained ogg.
   mDecodedAudioEndTime = std::max(audio->GetEndTime(), mDecodedAudioEndTime);
 
   SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d",
              (audio ? audio->mTime : -1),
              (audio ? audio->GetEndTime() : -1),
              (audio ? audio->mDiscontinuity : 0));
@@ -669,21 +671,16 @@ MediaDecoderStateMachine::OnNotDecoded(M
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
 
   SAMPLE_LOG("OnNotDecoded (aType=%u, aReason=%u)", aType, aReason);
   bool isAudio = aType == MediaData::AUDIO_DATA;
   MOZ_ASSERT_IF(!isAudio, aType == MediaData::VIDEO_DATA);
 
-  if (isAudio) {
-    mAudioDataRequest.Complete();
-  } else {
-    mVideoDataRequest.Complete();
-  }
   if (IsShutdown()) {
     // Already shutdown;
     return;
   }
 
   // If this is a decode error, delegate to the generic error path.
   if (aReason == MediaDecoderReader::DECODE_ERROR) {
     DecodeError();
@@ -788,17 +785,16 @@ void
 MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideoSample,
                                          TimeStamp aDecodeStartTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
 
   RefPtr<MediaData> video(aVideoSample);
   MOZ_ASSERT(video);
-  mVideoDataRequest.Complete();
 
   // Handle abnormal or negative timestamps.
   mDecodedVideoEndTime = std::max(mDecodedVideoEndTime, video->GetEndTime());
 
   SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d",
              (video ? video->mTime : -1),
              (video ? video->GetEndTime() : -1),
              (video ? video->mDiscontinuity : 0));
@@ -922,16 +918,43 @@ nsresult MediaDecoderStateMachine::Init(
   NS_ENSURE_SUCCESS(rv, rv);
 
   r = NS_NewRunnableMethod(this, &MediaDecoderStateMachine::ReadMetadata);
   OwnerThread()->Dispatch(r.forget());
 
   return NS_OK;
 }
 
+void
+MediaDecoderStateMachine::SetMediaDecoderReaderWrapperCallback()
+{
+  mAudioCallbackID =
+    mReader->SetAudioCallback(this,
+                              &MediaDecoderStateMachine::OnAudioDecoded,
+                              &MediaDecoderStateMachine::OnAudioNotDecoded);
+
+  mVideoCallbackID =
+    mReader->SetVideoCallback(this,
+                              &MediaDecoderStateMachine::OnVideoDecoded,
+                              &MediaDecoderStateMachine::OnVideoNotDecoded);
+
+  DECODER_LOG("MDSM set audio callbacks: mAudioCallbackID = %d\n", (int)mAudioCallbackID);
+  DECODER_LOG("MDSM set video callbacks: mVideoCallbackID = %d\n", (int)mVideoCallbackID);
+}
+
+void
+MediaDecoderStateMachine::CancelMediaDecoderReaderWrapperCallback()
+{
+    DECODER_LOG("MDSM cancel audio callbacks: mVideoCallbackID = %d\n", (int)mAudioCallbackID);
+    mReader->CancelAudioCallback(mAudioCallbackID);
+
+    DECODER_LOG("MDSM cancel video callbacks: mVideoCallbackID = %d\n", (int)mVideoCallbackID);
+    mReader->CancelVideoCallback(mVideoCallbackID);
+}
+
 void MediaDecoderStateMachine::StopPlayback()
 {
   MOZ_ASSERT(OnTaskQueue());
   DECODER_LOG("StopPlayback()");
 
   mOnPlaybackEvent.Notify(MediaEventType::PlaybackStopped);
 
   if (IsPlaying()) {
@@ -1144,20 +1167,17 @@ MediaDecoderStateMachine::SetDormant(boo
                                        SeekTarget::Accurate,
                                        MediaDecoderEventVisibility::Suppressed);
       // XXXbholley - Nobody is listening to this promise. Do we need to pass it
       // back to MediaDecoder when we come out of dormant?
       RefPtr<MediaDecoder::SeekPromise> unused = mQueuedSeek.mPromise.Ensure(__func__);
     }
 
     // Discard the current seek task.
-    if (mSeekTask) {
-      mSeekTask->Discard();
-      mSeekTask = nullptr;
-    }
+    DiscardSeekTaskIfExist();
 
     SetState(DECODER_STATE_DORMANT);
     if (IsPlaying()) {
       StopPlayback();
     }
 
     Reset();
 
@@ -1184,29 +1204,30 @@ MediaDecoderStateMachine::Shutdown()
   // Change state before issuing shutdown request to threads so those
   // threads can start exiting cleanly during the Shutdown call.
   ScheduleStateMachine();
   SetState(DECODER_STATE_SHUTDOWN);
 
   mBufferedUpdateRequest.DisconnectIfExists();
 
   mQueuedSeek.RejectIfExists(__func__);
-  if (mSeekTask) {
-    mSeekTask->Discard();
-    mSeekTask = nullptr;
-  }
+
+  DiscardSeekTaskIfExist();
 
 #ifdef MOZ_EME
   mCDMProxyPromise.DisconnectIfExists();
 #endif
 
   if (IsPlaying()) {
     StopPlayback();
   }
 
+  // To break the cycle-reference between MediaDecoderReaderWrapper and MDSM.
+  CancelMediaDecoderReaderWrapperCallback();
+
   Reset();
 
   mMediaSink->Shutdown();
 
   DECODER_LOG("Shutdown started");
 
   // Put a task in the decode queue to shutdown the reader.
   // the queue to spin down.
@@ -1452,22 +1473,23 @@ MediaDecoderStateMachine::DispatchDecode
 }
 
 void
 MediaDecoderStateMachine::InitiateSeek(SeekJob aSeekJob)
 {
   MOZ_ASSERT(OnTaskQueue());
 
   // Discard the existing seek task.
-  if (mSeekTask) {
-    mSeekTask->Discard();
-  }
+  DiscardSeekTaskIfExist();
 
   mSeekTaskRequest.DisconnectIfExists();
 
+  // SeekTask will register its callbacks to MediaDecoderReaderWrapper.
+  CancelMediaDecoderReaderWrapperCallback();
+
   // Create a new SeekTask instance for the incoming seek task.
   mSeekTask = SeekTask::CreateSeekTask(mDecoderID, OwnerThread(),
                                        mReader.get(), Move(aSeekJob),
                                        mInfo, Duration(), GetMediaTime());
 
   // Stop playback now to ensure that while we're outside the monitor
   // dispatching SeekingStarted, playback doesn't advance and mess with
   // mCurrentPosition that we've setting to seekTime here.
@@ -1520,19 +1542,16 @@ MediaDecoderStateMachine::OnSeekTaskReso
     StopPrerollingAudio();
   }
 
   if (aValue.mNeedToStopPrerollingVideo) {
     StopPrerollingVideo();
   }
 
   SeekCompleted();
-
-  mSeekTask->Discard();
-  mSeekTask = nullptr;
 }
 
 void
 MediaDecoderStateMachine::OnSeekTaskRejected(SeekTaskRejectValue aValue)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState == DECODER_STATE_SEEKING);
 
@@ -1553,18 +1572,29 @@ MediaDecoderStateMachine::OnSeekTaskReje
   }
 
   if (aValue.mNeedToStopPrerollingVideo) {
     StopPrerollingVideo();
   }
 
   DecodeError();
 
-  mSeekTask->Discard();
-  mSeekTask = nullptr;
+  DiscardSeekTaskIfExist();
+}
+
+void
+MediaDecoderStateMachine::DiscardSeekTaskIfExist()
+{
+  if (mSeekTask) {
+    mSeekTask->Discard();
+    mSeekTask = nullptr;
+
+    // Reset the MediaDecoderReaderWrapper's callbask.
+    SetMediaDecoderReaderWrapperCallback();
+  }
 }
 
 nsresult
 MediaDecoderStateMachine::DispatchAudioDecodeTaskIfNeeded()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   if (IsShutdown()) {
@@ -1587,17 +1617,17 @@ MediaDecoderStateMachine::EnsureAudioDec
   SAMPLE_LOG("EnsureAudioDecodeTaskQueued isDecoding=%d status=%s",
               IsAudioDecoding(), AudioRequestStatus());
 
   if (mState != DECODER_STATE_DECODING &&
       mState != DECODER_STATE_BUFFERING) {
     return NS_OK;
   }
 
-  if (!IsAudioDecoding() || mAudioDataRequest.Exists() ||
+  if (!IsAudioDecoding() || mReader->IsRequestingAudioData() ||
       mAudioWaitRequest.Exists()) {
     return NS_OK;
   }
 
   RequestAudioData();
   return NS_OK;
 }
 
@@ -1605,21 +1635,17 @@ void
 MediaDecoderStateMachine::RequestAudioData()
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
 
   SAMPLE_LOG("Queueing audio task - queued=%i, decoder-queued=%o",
              AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
 
-  mAudioDataRequest.Begin(
-    mReader->RequestAudioData()
-    ->Then(OwnerThread(), __func__, this,
-           &MediaDecoderStateMachine::OnAudioDecoded,
-           &MediaDecoderStateMachine::OnAudioNotDecoded));
+  mReader->RequestAudioData();
 }
 
 nsresult
 MediaDecoderStateMachine::DispatchVideoDecodeTaskIfNeeded()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   if (IsShutdown()) {
@@ -1642,55 +1668,45 @@ MediaDecoderStateMachine::EnsureVideoDec
   SAMPLE_LOG("EnsureVideoDecodeTaskQueued isDecoding=%d status=%s",
              IsVideoDecoding(), VideoRequestStatus());
 
   if (mState != DECODER_STATE_DECODING &&
       mState != DECODER_STATE_BUFFERING) {
     return NS_OK;
   }
 
-  if (!IsVideoDecoding() || mVideoDataRequest.Exists() ||
+  if (!IsVideoDecoding() || mReader->IsRequestingVidoeData() ||
       mVideoWaitRequest.Exists()) {
     return NS_OK;
   }
 
   RequestVideoData();
   return NS_OK;
 }
 
 void
 MediaDecoderStateMachine::RequestVideoData()
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
 
-  // Time the video decode, so that if it's slow, we can increase our low
-  // audio threshold to reduce the chance of an audio underrun while we're
-  // waiting for a video decode to complete.
-  TimeStamp videoDecodeStartTime = TimeStamp::Now();
-
   bool skipToNextKeyFrame = mSentFirstFrameLoadedEvent &&
     NeedToSkipToNextKeyframe();
 
   media::TimeUnit currentTime = media::TimeUnit::FromMicroseconds(GetMediaTime());
 
   SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld",
              VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame,
              currentTime.ToMicroseconds());
 
-  RefPtr<MediaDecoderStateMachine> self = this;
-  mVideoDataRequest.Begin(
-    mReader->RequestVideoData(skipToNextKeyFrame, currentTime)
-    ->Then(OwnerThread(), __func__,
-           [self, videoDecodeStartTime] (MediaData* aVideoSample) {
-             self->OnVideoDecoded(aVideoSample, videoDecodeStartTime);
-           },
-           [self] (MediaDecoderReader::NotDecodedReason aReason) {
-             self->OnVideoNotDecoded(aReason);
-           }));
+  // MediaDecoderReaderWrapper::RequestVideoData() records the decoding start
+  // time and sent it back to MDSM::OnVideoDecoded() so that if the decoding is
+  // slow, we can increase our low audio threshold to reduce the chance of an
+  // audio underrun while we're waiting for a video decode to complete.
+  mReader->RequestVideoData(skipToNextKeyFrame, currentTime);
 }
 
 void
 MediaDecoderStateMachine::StartMediaSink()
 {
   MOZ_ASSERT(OnTaskQueue());
   if (!mMediaSink->IsStarted()) {
     mAudioCompleted = false;
@@ -2001,16 +2017,25 @@ MediaDecoderStateMachine::SeekCompleted(
     DECODER_LOG("Changed state from SEEKING (to %lld) to DECODING", seekTime);
     nextState = DECODER_STATE_DECODING;
   }
 
   // We want to resolve the seek request prior finishing the first frame
   // to ensure that the seeked event is fired prior loadeded.
   mSeekTask->GetSeekJob().Resolve(nextState == DECODER_STATE_COMPLETED, __func__);
 
+  // Discard and nullify the seek task.
+  // Reset the MediaDecoderReaderWrapper's callbask.
+  DiscardSeekTaskIfExist();
+
+  // NOTE: Discarding the mSeekTask must be done before here. The following code
+  // might ask the MediaDecoderReaderWrapper to request media data, however, the
+  // SeekTask::Discard() will ask MediaDecoderReaderWrapper to discard media
+  // data requests.
+
   if (mDecodingFirstFrame) {
     // We were resuming from dormant, or initiated a seek early.
     // We can fire loadeddata now.
     FinishDecodeFirstFrame();
   }
 
   if (nextState == DECODER_STATE_DECODING) {
     StartDecoding();
@@ -2153,18 +2178,18 @@ nsresult MediaDecoderStateMachine::RunSt
                       (mQuickBuffering ? "(quick exit)" : ""));
           ScheduleStateMachineIn(USECS_PER_S);
           return NS_OK;
         }
       } else if (OutOfDecodedAudio() || OutOfDecodedVideo()) {
         MOZ_ASSERT(mReader->IsWaitForDataSupported(),
                    "Don't yet have a strategy for non-heuristic + non-WaitForData");
         DispatchDecodeTasksIfNeeded();
-        MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedAudio(), mAudioDataRequest.Exists() || mAudioWaitRequest.Exists());
-        MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedVideo(), mVideoDataRequest.Exists() || mVideoWaitRequest.Exists());
+        MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedAudio(), mReader->IsRequestingAudioData() || mAudioWaitRequest.Exists());
+        MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedVideo(), mReader->IsRequestingVidoeData() || mVideoWaitRequest.Exists());
         DECODER_LOG("In buffering mode, waiting to be notified: outOfAudio: %d, "
                     "mAudioStatus: %s, outOfVideo: %d, mVideoStatus: %s",
                     OutOfDecodedAudio(), AudioRequestStatus(),
                     OutOfDecodedVideo(), VideoRequestStatus());
         return NS_OK;
       }
 
       DECODER_LOG("Changed state from BUFFERING to DECODING");
@@ -2248,19 +2273,17 @@ MediaDecoderStateMachine::Reset()
   mDecodedVideoEndTime = 0;
   mDecodedAudioEndTime = 0;
   mAudioCompleted = false;
   mVideoCompleted = false;
   AudioQueue().Reset();
   VideoQueue().Reset();
 
   mMetadataRequest.DisconnectIfExists();
-  mAudioDataRequest.DisconnectIfExists();
   mAudioWaitRequest.DisconnectIfExists();
-  mVideoDataRequest.DisconnectIfExists();
   mVideoWaitRequest.DisconnectIfExists();
   mSeekTaskRequest.DisconnectIfExists();
 
   mPlaybackOffset = 0;
 
   mReader->ResetDecode();
 }
 
@@ -2719,16 +2742,42 @@ MediaDecoderStateMachine::CanonicalBuffe
 }
 
 MediaEventSource<void>&
 MediaDecoderStateMachine::OnMediaNotSeekable() const
 {
   return mReader->OnMediaNotSeekable();
 }
 
+const char*
+MediaDecoderStateMachine::AudioRequestStatus() const
+{
+  MOZ_ASSERT(OnTaskQueue());
+  if (mReader->IsRequestingAudioData()) {
+    MOZ_DIAGNOSTIC_ASSERT(!mAudioWaitRequest.Exists());
+    return "pending";
+  } else if (mAudioWaitRequest.Exists()) {
+    return "waiting";
+  }
+  return "idle";
+}
+
+const char*
+MediaDecoderStateMachine::VideoRequestStatus() const
+{
+  MOZ_ASSERT(OnTaskQueue());
+  if (mReader->IsRequestingVidoeData()) {
+    MOZ_DIAGNOSTIC_ASSERT(!mVideoWaitRequest.Exists());
+    return "pending";
+  } else if (mVideoWaitRequest.Exists()) {
+    return "waiting";
+  }
+  return "idle";
+}
+
 } // namespace mozilla
 
 // avoid redefined macro in unified build
 #undef LOG
 #undef DECODER_LOG
 #undef VERBOSE_LOG
 #undef DECODER_WARN
 #undef DECODER_WARN_HELPER
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -82,16 +82,17 @@ hardware (via AudioStream).
 #if !defined(MediaDecoderStateMachine_h__)
 #define MediaDecoderStateMachine_h__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/StateMirroring.h"
 
 #include "nsThreadUtils.h"
+#include "MediaCallbackID.h"
 #include "MediaDecoder.h"
 #include "MediaDecoderReader.h"
 #include "MediaDecoderOwner.h"
 #include "MediaEventSource.h"
 #include "MediaMetadataManager.h"
 #include "MediaStatistics.h"
 #include "MediaTimer.h"
 #include "ImageContainer.h"
@@ -138,16 +139,19 @@ public:
   typedef MediaDecoderOwner::NextFrameStatus NextFrameStatus;
   typedef mozilla::layers::ImageContainer::FrameID FrameID;
   MediaDecoderStateMachine(MediaDecoder* aDecoder,
                            MediaDecoderReader* aReader,
                            bool aRealTime = false);
 
   nsresult Init(MediaDecoder* aDecoder);
 
+  void SetMediaDecoderReaderWrapperCallback();
+  void CancelMediaDecoderReaderWrapperCallback();
+
   // Enumeration for the valid decoding states
   enum State {
     DECODER_STATE_DECODING_METADATA,
     DECODER_STATE_WAIT_FOR_CDM,
     DECODER_STATE_DORMANT,
     DECODER_STATE_DECODING,
     DECODER_STATE_SEEKING,
     DECODER_STATE_BUFFERING,
@@ -674,16 +678,20 @@ private:
 
   // mSeekTask is responsible for executing the current seek request.
   RefPtr<SeekTask> mSeekTask;
   MozPromiseRequestHolder<SeekTask::SeekTaskPromise> mSeekTaskRequest;
 
   void OnSeekTaskResolved(SeekTaskResolveValue aValue);
   void OnSeekTaskRejected(SeekTaskRejectValue aValue);
 
+  // This method discards the seek task and then get the ownership of
+  // MedaiDecoderReaderWarpper back via registering MDSM's callback into it.
+  void DiscardSeekTaskIfExist();
+
   // Media Fragment end time in microseconds. Access controlled by decoder monitor.
   int64_t mFragmentEndTime;
 
   // The media sink resource.  Used on the state machine thread.
   RefPtr<media::MediaSink> mMediaSink;
 
   const RefPtr<MediaDecoderReaderWrapper> mReader;
 
@@ -802,43 +810,23 @@ private:
   // playback. The flags below are true when the corresponding stream is
   // being "prerolled".
   bool mIsAudioPrerolling;
   bool mIsVideoPrerolling;
 
   // Only one of a given pair of ({Audio,Video}DataPromise, WaitForDataPromise)
   // should exist at any given moment.
 
-  MozPromiseRequestHolder<MediaDecoderReader::MediaDataPromise> mAudioDataRequest;
+  CallbackID mAudioCallbackID;
   MozPromiseRequestHolder<MediaDecoderReader::WaitForDataPromise> mAudioWaitRequest;
-  const char* AudioRequestStatus()
-  {
-    MOZ_ASSERT(OnTaskQueue());
-    if (mAudioDataRequest.Exists()) {
-      MOZ_DIAGNOSTIC_ASSERT(!mAudioWaitRequest.Exists());
-      return "pending";
-    } else if (mAudioWaitRequest.Exists()) {
-      return "waiting";
-    }
-    return "idle";
-  }
+  const char* AudioRequestStatus() const;
 
+  CallbackID mVideoCallbackID;
   MozPromiseRequestHolder<MediaDecoderReader::WaitForDataPromise> mVideoWaitRequest;
-  MozPromiseRequestHolder<MediaDecoderReader::MediaDataPromise> mVideoDataRequest;
-  const char* VideoRequestStatus()
-  {
-    MOZ_ASSERT(OnTaskQueue());
-    if (mVideoDataRequest.Exists()) {
-      MOZ_DIAGNOSTIC_ASSERT(!mVideoWaitRequest.Exists());
-      return "pending";
-    } else if (mVideoWaitRequest.Exists()) {
-      return "waiting";
-    }
-    return "idle";
-  }
+  const char* VideoRequestStatus() const;
 
   MozPromiseRequestHolder<MediaDecoderReader::WaitForDataPromise>& WaitRequestRef(MediaData::Type aType)
   {
     MOZ_ASSERT(OnTaskQueue());
     return aType == MediaData::AUDIO_DATA ? mAudioWaitRequest : mVideoWaitRequest;
   }
 
   // True if we shouldn't play our audio (but still write it to any capturing
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -515,17 +515,20 @@ MediaFormatReader::RequestVideoData(bool
   }
 
   if (mShutdown) {
     NS_WARNING("RequestVideoData on shutdown MediaFormatReader!");
     return MediaDataPromise::CreateAndReject(CANCELED, __func__);
   }
 
   media::TimeUnit timeThreshold{media::TimeUnit::FromMicroseconds(aTimeThreshold)};
-  if (ShouldSkip(aSkipToNextKeyframe, timeThreshold)) {
+  // Ensure we have no pending seek going as ShouldSkip could return out of date
+  // information.
+  if (!mVideo.HasInternalSeekPending() &&
+      ShouldSkip(aSkipToNextKeyframe, timeThreshold)) {
     // Cancel any pending demux request.
     mVideo.mDemuxRequest.DisconnectIfExists();
 
     // I think it's still possible for an output to have been sent from the decoder
     // and is currently sitting in our event queue waiting to be processed. The following
     // flush won't clear it, and when we return to the event loop it'll be added to our
     // output queue and be used.
     // This code will count that as dropped, which was the intent, but not quite true.
@@ -742,16 +745,17 @@ MediaFormatReader::NeedInput(DecoderData
   // decoded sample. To account for H.264 streams which may require a longer
   // run of input than we input, decoders fire an "input exhausted" callback,
   // which overrides our "few more samples" threshold.
   return
     !aDecoder.mDraining &&
     !aDecoder.mError &&
     aDecoder.mDecodingRequested &&
     !aDecoder.mDemuxRequest.Exists() &&
+    !aDecoder.mSeekRequest.Exists() &&
     aDecoder.mOutput.Length() <= aDecoder.mDecodeAhead &&
     (aDecoder.mInputExhausted || !aDecoder.mQueuedSamples.IsEmpty() ||
      aDecoder.mTimeThreshold.isSome() ||
      aDecoder.mNumSamplesInput - aDecoder.mNumSamplesOutput <= aDecoder.mDecodeAhead);
 }
 
 void
 MediaFormatReader::ScheduleUpdate(TrackType aTrack)
@@ -779,16 +783,31 @@ MediaFormatReader::UpdateReceivedNewData
 
   if (!decoder.mReceivedNewData) {
     return false;
   }
 
   // Update our cached TimeRange.
   decoder.mTimeRanges = decoder.mTrackDemuxer->GetBuffered();
 
+  // We do not want to clear mWaitingForData while there are pending
+  // demuxing or seeking operations that could affect the value of this flag.
+  // This is in order to ensure that we will retry once they complete as we may
+  // now have new data that could potentially allow those operations to
+  // successfully complete if tried again.
+  if (decoder.mSeekRequest.Exists()) {
+    // Nothing more to do until this operation complete.
+    return true;
+  }
+  if (decoder.mDemuxRequest.Exists()) {
+    // We may have pending operations to process, so we want to continue
+    // after UpdateReceivedNewData returns.
+    return false;
+  }
+
   if (decoder.mDrainComplete || decoder.mDraining) {
     // We do not want to clear mWaitingForData or mDemuxEOS while
     // a drain is in progress in order to properly complete the operation.
     return false;
   }
 
   bool hasLastEnd;
   media::TimeUnit lastEnd = decoder.mTimeRanges.GetEnd(&hasLastEnd);
@@ -804,20 +823,29 @@ MediaFormatReader::UpdateReceivedNewData
   if (decoder.mTimeThreshold) {
     decoder.mTimeThreshold.ref().mWaiting = false;
   }
   decoder.mWaitingForData = false;
 
   if (decoder.mError) {
     return false;
   }
-  if (decoder.HasWaitingPromise()) {
-    MOZ_ASSERT(!decoder.HasPromise());
-    LOG("We have new data. Resolving WaitingPromise");
-    decoder.mWaitingPromise.Resolve(decoder.mType, __func__);
+
+  bool hasPendingSeek =
+    decoder.mTimeThreshold && !decoder.mTimeThreshold.ref().mHasSeeked;
+  if (hasPendingSeek || decoder.HasWaitingPromise()) {
+    if (hasPendingSeek) {
+      LOG("Attempting Internal Seek");
+      InternalSeek(aTrack, decoder.mTimeThreshold.ref());
+    }
+    if (decoder.HasWaitingPromise()) {
+      MOZ_ASSERT(!decoder.HasPromise());
+      LOG("We have new data. Resolving WaitingPromise");
+      decoder.mWaitingPromise.Resolve(decoder.mType, __func__);
+    }
     return true;
   }
   if (!mSeekPromise.IsEmpty()) {
     MOZ_ASSERT(!decoder.HasPromise());
     if (mVideo.mSeekRequest.Exists() || mAudio.mSeekRequest.Exists()) {
       // Already waiting for a seek to complete. Nothing more to do.
       return true;
     }
@@ -968,45 +996,52 @@ MediaFormatReader::HandleDemuxedSamples(
   // We have serviced the decoder's request for more data.
   decoder.mInputExhausted = false;
 }
 
 void
 MediaFormatReader::InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget)
 {
   MOZ_ASSERT(OnTaskQueue());
+  LOG("%s internal seek to %f",
+      TrackTypeToStr(aTrack), aTarget.mTime.ToSeconds());
+
   auto& decoder = GetDecoderData(aTrack);
   decoder.mTimeThreshold = Some(aTarget);
   RefPtr<MediaFormatReader> self = this;
   decoder.ResetDemuxer();
   decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref().mTime)
              ->Then(OwnerThread(), __func__,
                     [self, aTrack] (media::TimeUnit aTime) {
                       auto& decoder = self->GetDecoderData(aTrack);
                       decoder.mSeekRequest.Complete();
+                      MOZ_ASSERT(decoder.mTimeThreshold);
+                      decoder.mTimeThreshold.ref().mHasSeeked = true;
                       self->NotifyDecodingRequested(aTrack);
                     },
                     [self, aTrack] (DemuxerFailureReason aResult) {
                       auto& decoder = self->GetDecoderData(aTrack);
                       decoder.mSeekRequest.Complete();
                       switch (aResult) {
                         case DemuxerFailureReason::WAITING_FOR_DATA:
                           self->NotifyWaitingForData(aTrack);
                           break;
                         case DemuxerFailureReason::END_OF_STREAM:
+                          decoder.mTimeThreshold.reset();
                           self->NotifyEndOfStream(aTrack);
                           break;
                         case DemuxerFailureReason::CANCELED:
                         case DemuxerFailureReason::SHUTDOWN:
+                          decoder.mTimeThreshold.reset();
                           break;
                         default:
+                          decoder.mTimeThreshold.reset();
                           self->NotifyError(aTrack);
                           break;
                       }
-                      decoder.mTimeThreshold.reset();
                     }));
 }
 
 void
 MediaFormatReader::DrainDecoder(TrackType aTrack)
 {
   MOZ_ASSERT(OnTaskQueue());
 
@@ -1119,17 +1154,18 @@ MediaFormatReader::Update(TrackType aTra
         if (!decoder.mReceivedNewData) {
           LOG("Rejecting %s promise: WAITING_FOR_DATA", TrackTypeToStr(aTrack));
           decoder.RejectPromise(WAITING_FOR_DATA, __func__);
         }
       }
       // Now that draining has completed, we check if we have received
       // new data again as the result may now be different from the earlier
       // run.
-      if (UpdateReceivedNewData(aTrack)) {
+      if (UpdateReceivedNewData(aTrack) ||
+          (decoder.mTimeThreshold && decoder.mSeekRequest.Exists())) {
         LOGV("Nothing more to do");
         return;
       }
     }
   }
 
   if (decoder.mNeedDraining) {
     DrainDecoder(aTrack);
@@ -1240,18 +1276,16 @@ MediaFormatReader::WaitForData(MediaData
 }
 
 nsresult
 MediaFormatReader::ResetDecode()
 {
   MOZ_ASSERT(OnTaskQueue());
   LOGV("");
 
-  mAudio.mSeekRequest.DisconnectIfExists();
-  mVideo.mSeekRequest.DisconnectIfExists();
   mSeekPromise.RejectIfExists(NS_OK, __func__);
   mSkipRequest.DisconnectIfExists();
 
   // Do the same for any data wait promises.
   mAudio.mWaitingPromise.RejectIfExists(WaitForDataRejectValue(MediaData::AUDIO_DATA, WaitForDataRejectValue::CANCELED), __func__);
   mVideo.mWaitingPromise.RejectIfExists(WaitForDataRejectValue(MediaData::VIDEO_DATA, WaitForDataRejectValue::CANCELED), __func__);
 
   // Reset miscellaneous seeking state.
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -132,22 +132,25 @@ private:
   bool DecodeDemuxedSamples(TrackType aTrack,
                             MediaRawData* aSample);
 
   struct InternalSeekTarget {
     InternalSeekTarget(const media::TimeUnit& aTime, bool aDropTarget)
       : mTime(aTime)
       , mDropTarget(aDropTarget)
       , mWaiting(false)
+      , mHasSeeked(false)
     {}
 
     media::TimeUnit mTime;
     bool mDropTarget;
     bool mWaiting;
+    bool mHasSeeked;
   };
+
   // Perform an internal seek to aTime. If aDropTarget is true then
   // the first sample past the target will be dropped.
   void InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget);
 
   // Drain the current decoder.
   void DrainDecoder(TrackType aTrack);
   void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
   void NotifyInputExhausted(TrackType aTrack);
@@ -322,16 +325,17 @@ private:
     virtual bool HasPromise() = 0;
     virtual void RejectPromise(MediaDecoderReader::NotDecodedReason aReason,
                                const char* aMethodName) = 0;
 
     void ResetDemuxer()
     {
       // Clear demuxer related data.
       mDemuxRequest.DisconnectIfExists();
+      mSeekRequest.DisconnectIfExists();
       mTrackDemuxer->Reset();
     }
 
     void ResetState()
     {
       MOZ_ASSERT(mOwner->OnTaskQueue());
       mDemuxEOS = false;
       mWaitingForData = false;
@@ -348,16 +352,21 @@ private:
       mLastSampleTime.reset();
       mOutput.Clear();
       mNumSamplesInput = 0;
       mNumSamplesOutput = 0;
       mSizeOfQueue = 0;
       mNextStreamSourceID.reset();
     }
 
+    bool HasInternalSeekPending() const
+    {
+      return mTimeThreshold && !mTimeThreshold.ref().mHasSeeked;
+    }
+
     // Used by the MDSM for logging purposes.
     Atomic<size_t> mSizeOfQueue;
     // Used by the MDSM to determine if video decoding is hardware accelerated.
     // This value is updated after a frame is successfully decoded.
     Atomic<bool> mIsHardwareAccelerated;
     // Sample format monitoring.
     uint32_t mLastStreamSourceID;
     Maybe<uint32_t> mNextStreamSourceID;
--- a/dom/media/SeekTask.cpp
+++ b/dom/media/SeekTask.cpp
@@ -81,16 +81,19 @@ SeekTask::SeekTask(const void* aDecoderI
   seekTime = std::min(seekTime, end);
   seekTime = std::max(int64_t(0), seekTime);
   NS_ASSERTION(seekTime >= 0 && seekTime <= end,
                "Can only seek in range [0,duration]");
   mSeekJob.mTarget.SetTime(media::TimeUnit::FromMicroseconds(seekTime));
 
   mDropAudioUntilNextDiscontinuity = HasAudio();
   mDropVideoUntilNextDiscontinuity = HasVideo();
+
+  // Configure MediaDecoderReaderWrapper.
+  SetMediaDecoderReaderWrapperCallback();
 }
 
 SeekTask::~SeekTask()
 {
   MOZ_ASSERT(mIsDiscarded);
 }
 
 void
@@ -147,22 +150,21 @@ void
 SeekTask::Discard()
 {
   // Disconnect MediaDecoder.
   mSeekJob.RejectIfExists(__func__);
 
   // Disconnect MDSM.
   RejectIfExist(__func__);
 
-  // Disconnect MediaDecoderReader.
+  // Disconnect MediaDecoderReaderWrapper.
   mSeekRequest.DisconnectIfExists();
-  mAudioDataRequest.DisconnectIfExists();
-  mVideoDataRequest.DisconnectIfExists();
   mAudioWaitRequest.DisconnectIfExists();
   mVideoWaitRequest.DisconnectIfExists();
+  CancelMediaDecoderReaderWrapperCallback();
 
   mIsDiscarded = true;
 }
 
 bool
 SeekTask::NeedToResetMDSM() const
 {
   return true;
@@ -211,17 +213,17 @@ nsresult
 SeekTask::EnsureAudioDecodeTaskQueued()
 {
   AssertOwnerThread();
 
   SAMPLE_LOG("EnsureAudioDecodeTaskQueued isDecoding=%d status=%s",
               IsAudioDecoding(), AudioRequestStatus());
 
   if (!IsAudioDecoding() ||
-      mAudioDataRequest.Exists() ||
+      mReader->IsRequestingAudioData() ||
       mAudioWaitRequest.Exists() ||
       mSeekRequest.Exists()) {
     return NS_OK;
   }
 
   RequestAudioData();
   return NS_OK;
 }
@@ -230,81 +232,76 @@ nsresult
 SeekTask::EnsureVideoDecodeTaskQueued()
 {
   AssertOwnerThread();
 
   SAMPLE_LOG("EnsureVideoDecodeTaskQueued isDecoding=%d status=%s",
              IsVideoDecoding(), VideoRequestStatus());
 
   if (!IsVideoDecoding() ||
-      mVideoDataRequest.Exists() ||
+      mReader->IsRequestingVidoeData() ||
       mVideoWaitRequest.Exists() ||
       mSeekRequest.Exists()) {
     return NS_OK;
   }
 
   RequestVideoData();
   return NS_OK;
 }
 
 const char*
 SeekTask::AudioRequestStatus()
 {
   AssertOwnerThread();
-  if (mAudioDataRequest.Exists()) {
+  if (mReader->IsRequestingAudioData()) {
     MOZ_DIAGNOSTIC_ASSERT(!mAudioWaitRequest.Exists());
     return "pending";
   } else if (mAudioWaitRequest.Exists()) {
     return "waiting";
   }
   return "idle";
 }
 
 const char*
 SeekTask::VideoRequestStatus()
 {
   AssertOwnerThread();
-  if (mVideoDataRequest.Exists()) {
+  if (mReader->IsRequestingVidoeData()) {
     MOZ_DIAGNOSTIC_ASSERT(!mVideoWaitRequest.Exists());
     return "pending";
   } else if (mVideoWaitRequest.Exists()) {
     return "waiting";
   }
   return "idle";
 }
 
 void
 SeekTask::RequestAudioData()
 {
   AssertOwnerThread();
 
   SAMPLE_LOG("Queueing audio task - queued=%i, decoder-queued=%o",
              !!mSeekedAudioData, mReader->SizeOfAudioQueueInFrames());
 
-  mAudioDataRequest.Begin(mReader->RequestAudioData()
-    ->Then(OwnerThread(), __func__, this,
-           &SeekTask::OnAudioDecoded, &SeekTask::OnAudioNotDecoded));
+  mReader->RequestAudioData();
 }
 
 void
 SeekTask::RequestVideoData()
 {
   AssertOwnerThread();
   //These two variables are not used in the SEEKING state.
   const bool skipToNextKeyFrame = false;
   const media::TimeUnit currentTime = media::TimeUnit::FromMicroseconds(0);
 
   SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld",
                !!mSeekedVideoData, mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame,
                currentTime.ToMicroseconds());
 
-  mVideoDataRequest.Begin(
-    mReader->RequestVideoData(skipToNextKeyFrame, currentTime)
-    ->Then(OwnerThread(), __func__, this,
-           &SeekTask::OnVideoDecoded, &SeekTask::OnVideoNotDecoded));
+  mReader->RequestVideoData(skipToNextKeyFrame, currentTime);
 }
 
 nsresult
 SeekTask::DropAudioUpToSeekTarget(MediaData* aSample)
 {
   AssertOwnerThread();
   RefPtr<AudioData> audio(aSample->As<AudioData>());
   MOZ_ASSERT(audio && mSeekJob.Exists() && mSeekJob.mTarget.IsAccurate());
@@ -495,17 +492,16 @@ SeekTask::OnSeekRejected(nsresult aResul
 }
 
 void
 SeekTask::OnAudioDecoded(MediaData* aAudioSample)
 {
   AssertOwnerThread();
   RefPtr<MediaData> audio(aAudioSample);
   MOZ_ASSERT(audio);
-  mAudioDataRequest.Complete();
 
   // The MDSM::mDecodedAudioEndTime will be updated once the whole SeekTask is
   // resolved.
 
   SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d",
              (audio ? audio->mTime : -1),
              (audio ? audio->GetEndTime() : -1),
              (audio ? audio->mDiscontinuity : 0));
@@ -548,17 +544,16 @@ SeekTask::OnAudioDecoded(MediaData* aAud
   CheckIfSeekComplete();
 }
 
 void
 SeekTask::OnAudioNotDecoded(MediaDecoderReader::NotDecodedReason aReason)
 {
   AssertOwnerThread();
   SAMPLE_LOG("OnAduioNotDecoded (aReason=%u)", aReason);
-  mAudioDataRequest.Complete();
 
   if (aReason == MediaDecoderReader::DECODE_ERROR) {
     // If this is a decode error, delegate to the generic error path.
     RejectIfExist(__func__);
     return;
   }
 
   // If the decoder is waiting for data, we tell it to call us back when the
@@ -597,17 +592,16 @@ SeekTask::OnAudioNotDecoded(MediaDecoder
 }
 
 void
 SeekTask::OnVideoDecoded(MediaData* aVideoSample)
 {
   AssertOwnerThread();
   RefPtr<MediaData> video(aVideoSample);
   MOZ_ASSERT(video);
-  mVideoDataRequest.Complete();
 
   // The MDSM::mDecodedVideoEndTime will be updated once the whole SeekTask is
   // resolved.
 
   SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d",
              (video ? video->mTime : -1),
              (video ? video->GetEndTime() : -1),
              (video ? video->mDiscontinuity : 0));
@@ -652,17 +646,16 @@ SeekTask::OnVideoDecoded(MediaData* aVid
   CheckIfSeekComplete();
 }
 
 void
 SeekTask::OnVideoNotDecoded(MediaDecoderReader::NotDecodedReason aReason)
 {
   AssertOwnerThread();
   SAMPLE_LOG("OnVideoNotDecoded (aReason=%u)", aReason);
-  mVideoDataRequest.Complete();
 
   if (aReason == MediaDecoderReader::DECODE_ERROR) {
     // If this is a decode error, delegate to the generic error path.
     RejectIfExist(__func__);
     return;
   }
 
   // If the decoder is waiting for data, we tell it to call us back when the
@@ -705,9 +698,33 @@ SeekTask::OnVideoNotDecoded(MediaDecoder
     }
 
     mIsVideoQueueFinished = true;
     mDropVideoUntilNextDiscontinuity = false; // To make IsVideoSeekComplete() return TRUE.
     CheckIfSeekComplete();
   }
 }
 
+void
+SeekTask::SetMediaDecoderReaderWrapperCallback()
+{
+  mAudioCallbackID =
+    mReader->SetAudioCallback(this, &SeekTask::OnAudioDecoded,
+                                    &SeekTask::OnAudioNotDecoded);
+
+  mVideoCallbackID =
+    mReader->SetVideoCallback(this, &SeekTask::OnVideoDecoded,
+                                    &SeekTask::OnVideoNotDecoded);
+
+  DECODER_LOG("SeekTask set audio callbacks: mAudioCallbackID = %d\n", (int)mAudioCallbackID);
+  DECODER_LOG("SeekTask set video callbacks: mVideoCallbackID = %d\n", (int)mAudioCallbackID);
+}
+
+void
+SeekTask::CancelMediaDecoderReaderWrapperCallback()
+{
+    DECODER_LOG("SeekTask cancel audio callbacks: mVideoCallbackID = %d\n", (int)mAudioCallbackID);
+    mReader->CancelAudioCallback(mAudioCallbackID);
+
+    DECODER_LOG("SeekTask cancel video callbacks: mVideoCallbackID = %d\n", (int)mVideoCallbackID);
+    mReader->CancelVideoCallback(mVideoCallbackID);
+}
 } // namespace mozilla
--- a/dom/media/SeekTask.h
+++ b/dom/media/SeekTask.h
@@ -3,16 +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 SEEK_TASK_H
 #define SEEK_TASK_H
 
 #include "mozilla/MozPromise.h"
+#include "MediaCallbackID.h"
 #include "MediaDecoderReader.h"
 #include "SeekJob.h"
 
 namespace mozilla {
 
 class AbstractThread;
 class MediaData;
 class MediaDecoderReaderWrapper;
@@ -122,16 +123,20 @@ protected:
   virtual void OnAudioDecoded(MediaData* aAudioSample);
 
   virtual void OnAudioNotDecoded(MediaDecoderReader::NotDecodedReason aReason);
 
   virtual void OnVideoDecoded(MediaData* aVideoSample);
 
   virtual void OnVideoNotDecoded(MediaDecoderReader::NotDecodedReason aReason);
 
+  void SetMediaDecoderReaderWrapperCallback();
+
+  void CancelMediaDecoderReaderWrapperCallback();
+
   /*
    * Data shared with MDSM.
    */
   const void* mDecoderID; // For logging.
   const RefPtr<AbstractThread> mOwnerThread;
   const RefPtr<MediaDecoderReaderWrapper> mReader;
 
   /*
@@ -152,18 +157,18 @@ protected:
   // the seek target, we will still have a frame that we can display as the
   // last frame in the media.
   RefPtr<MediaData> mFirstVideoFrameAfterSeek;
 
   /*
    * Track the current seek promise made by the reader.
    */
   MozPromiseRequestHolder<MediaDecoderReader::SeekPromise> mSeekRequest;
-  MozPromiseRequestHolder<MediaDecoderReader::MediaDataPromise> mAudioDataRequest;
-  MozPromiseRequestHolder<MediaDecoderReader::MediaDataPromise> mVideoDataRequest;
+  CallbackID mAudioCallbackID;
+  CallbackID mVideoCallbackID;
   MozPromiseRequestHolder<MediaDecoderReader::WaitForDataPromise> mAudioWaitRequest;
   MozPromiseRequestHolder<MediaDecoderReader::WaitForDataPromise> mVideoWaitRequest;
 
   /*
    * Information which are going to be returned to MDSM.
    */
   RefPtr<MediaData> mSeekedAudioData;
   RefPtr<MediaData> mSeekedVideoData;
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -210,33 +210,33 @@ GetAppPaths(nsCString &aAppPath, nsCStri
   // soft links.
   aAppPath = GetNativeTarget(app);
   appBinaryPath = GetNativeTarget(appBinary);
 
   return true;
 }
 
 bool
-GMPChild::SetMacSandboxInfo()
+GMPChild::SetMacSandboxInfo(MacSandboxPluginType aPluginType)
 {
   if (!mGMPLoader) {
     return false;
   }
   nsAutoCString pluginDirectoryPath, pluginFilePath;
   if (!GetPluginPaths(mPluginPath, pluginDirectoryPath, pluginFilePath)) {
     return false;
   }
   nsAutoCString appPath, appBinaryPath;
   if (!GetAppPaths(appPath, appBinaryPath)) {
     return false;
   }
 
   MacSandboxInfo info;
   info.type = MacSandboxType_Plugin;
-  info.pluginInfo.type = MacSandboxPluginType_GMPlugin_Default;
+  info.pluginInfo.type = aPluginType;
   info.pluginInfo.pluginPath.assign(pluginDirectoryPath.get());
   info.pluginInfo.pluginBinaryPath.assign(pluginFilePath.get());
   info.appPath.assign(appPath.get());
   info.appBinaryPath.assign(appBinaryPath.get());
 
   mGMPLoader->SetSandboxInfo(&info);
   return true;
 }
@@ -370,27 +370,37 @@ GMPChild::AnswerStartPlugin(const nsStri
 
   mGMPLoader = GMPProcessChild::GetGMPLoader();
   if (!mGMPLoader) {
     NS_WARNING("Failed to get GMPLoader");
     delete platformAPI;
     return false;
   }
 
+#ifdef MOZ_WIDEVINE_EME
+  bool isWidevine = aAdapter.EqualsLiteral("widevine");
+#endif
+
 #if defined(MOZ_GMP_SANDBOX) && defined(XP_MACOSX)
-  if (!SetMacSandboxInfo()) {
+  MacSandboxPluginType pluginType = MacSandboxPluginType_GMPlugin_Default;
+#ifdef MOZ_WIDEVINE_EME
+  if (isWidevine) {
+      pluginType = MacSandboxPluginType_GMPlugin_EME_Widevine;
+  }
+#endif
+  if (!SetMacSandboxInfo(pluginType)) {
     NS_WARNING("Failed to set Mac GMP sandbox info");
     delete platformAPI;
     return false;
   }
 #endif
 
   GMPAdapter* adapter = nullptr;
 #ifdef MOZ_WIDEVINE_EME
-  if (aAdapter.EqualsLiteral("widevine")) {
+  if (isWidevine) {
     adapter = new WidevineAdapter();
   }
 #endif
   if (!mGMPLoader->Load(libPath.get(),
                         libPath.Length(),
                         mNodeId.BeginWriting(),
                         mNodeId.Length(),
                         platformAPI,
--- a/dom/media/gmp/GMPChild.h
+++ b/dom/media/gmp/GMPChild.h
@@ -36,17 +36,17 @@ public:
   // Main thread only.
   GMPTimerChild* GetGMPTimers();
   GMPStorageChild* GetGMPStorage();
 
   // GMPAsyncShutdownHost
   void ShutdownComplete() override;
 
 #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
-  bool SetMacSandboxInfo();
+  bool SetMacSandboxInfo(MacSandboxPluginType aPluginType);
 #endif
 
 private:
   friend class GMPContentChild;
 
   bool PreLoadPluginVoucher();
   void PreLoadSandboxVoucher();
 
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -570,16 +570,33 @@ GMPParent::SupportsAPI(const nsCString& 
 {
   for (uint32_t i = 0; i < mCapabilities.Length(); i++) {
     if (!mCapabilities[i].mAPIName.Equals(aAPI)) {
       continue;
     }
     nsTArray<nsCString>& tags = mCapabilities[i].mAPITags;
     for (uint32_t j = 0; j < tags.Length(); j++) {
       if (tags[j].Equals(aTag)) {
+#ifdef XP_WIN
+        // Clearkey on Windows advertises that it can decode in its GMP info
+        // file, but uses Windows Media Foundation to decode. That's not present
+        // on Windows XP, and on some Vista, Windows N, and KN variants without
+        // certain services packs.
+        if (tags[j].EqualsLiteral("org.w3.clearkey")) {
+          if (mCapabilities[i].mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER)) {
+            if (!WMFDecoderModule::HasH264()) {
+              continue;
+            }
+          } else if (mCapabilities[i].mAPIName.EqualsLiteral(GMP_API_AUDIO_DECODER)) {
+            if (!WMFDecoderModule::HasAAC()) {
+              continue;
+            }
+          }
+        }
+#endif
         return true;
       }
     }
   }
   return false;
 }
 
 bool
@@ -883,35 +900,16 @@ GMPParent::ReadGMPInfoFile(nsIFile* aFil
       // SSE2 isn't supported.
       if (cap.mAPITags.Contains(NS_LITERAL_CSTRING("com.adobe.primetime")) &&
           !mozilla::supports_sse2()) {
         return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
       }
 #endif // XP_WIN
     }
 
-#ifdef XP_WIN
-    // Clearkey on Windows advertises that it can decode in its GMP info
-    // file, but uses Windows Media Foundation to decode. That's not present
-    // on Windows XP, and on some Vista, Windows N, and KN variants without
-    // certain services packs. So don't add the decoding capability to
-    // gmp-clearkey's GMPParent if it's not going to be able to use WMF to
-    // decode.
-    if (cap.mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER) &&
-        cap.mAPITags.Contains(NS_LITERAL_CSTRING("org.w3.clearkey")) &&
-        !WMFDecoderModule::HasH264()) {
-      continue;
-    }
-    if (cap.mAPIName.EqualsLiteral(GMP_API_AUDIO_DECODER) &&
-        cap.mAPITags.Contains(NS_LITERAL_CSTRING("org.w3.clearkey")) &&
-        !WMFDecoderModule::HasAAC()) {
-      continue;
-    }
-#endif
-
     mCapabilities.AppendElement(Move(cap));
   }
 
   if (mCapabilities.IsEmpty()) {
     return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
 
   return GenericPromise::CreateAndResolve(true, __func__);
--- a/dom/media/gmp/GMPPlatform.cpp
+++ b/dom/media/gmp/GMPPlatform.cpp
@@ -19,48 +19,48 @@ static GMPChild* sChild = nullptr;
 
 static bool
 IsOnChildMainThread()
 {
   return sMainLoop && sMainLoop == MessageLoop::current();
 }
 
 // We just need a refcounted wrapper for GMPTask objects.
-class Runnable final
+class GMPRunnable final
 {
 public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Runnable)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPRunnable)
 
-  explicit Runnable(GMPTask* aTask)
+  explicit GMPRunnable(GMPTask* aTask)
   : mTask(aTask)
   {
     MOZ_ASSERT(mTask);
   }
 
   void Run()
   {
     mTask->Run();
     mTask->Destroy();
     mTask = nullptr;
   }
 
 private:
-  ~Runnable()
+  ~GMPRunnable()
   {
   }
 
   GMPTask* mTask;
 };
 
-class SyncRunnable final
+class GMPSyncRunnable final
 {
 public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SyncRunnable)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPSyncRunnable)
 
-  SyncRunnable(GMPTask* aTask, MessageLoop* aMessageLoop)
+  GMPSyncRunnable(GMPTask* aTask, MessageLoop* aMessageLoop)
   : mDone(false)
   , mTask(aTask)
   , mMessageLoop(aMessageLoop)
   , mMonitor("GMPSyncRunnable")
   {
     MOZ_ASSERT(mTask);
     MOZ_ASSERT(mMessageLoop);
   }
@@ -68,17 +68,17 @@ public:
   void Post()
   {
     // We assert here for two reasons.
     // 1) Nobody should be blocking the main thread.
     // 2) This prevents deadlocks when doing sync calls to main which if the
     //    main thread tries to do a sync call back to the calling thread.
     MOZ_ASSERT(!IsOnChildMainThread());
 
-    mMessageLoop->PostTask(NewRunnableMethod(this, &SyncRunnable::Run));
+    mMessageLoop->PostTask(NewRunnableMethod(this, &GMPSyncRunnable::Run));
     MonitorAutoLock lock(mMonitor);
     while (!mDone) {
       lock.Wait();
     }
   }
 
   void Run()
   {
@@ -86,17 +86,17 @@ public:
     mTask->Destroy();
     mTask = nullptr;
     MonitorAutoLock lock(mMonitor);
     mDone = true;
     lock.Notify();
   }
 
 private:
-  ~SyncRunnable()
+  ~GMPSyncRunnable()
   {
   }
 
   bool mDone;
   GMPTask* mTask;
   MessageLoop* mMessageLoop;
   Monitor mMonitor;
 };
@@ -115,30 +115,30 @@ CreateThread(GMPThread** aThread)
 
 GMPErr
 RunOnMainThread(GMPTask* aTask)
 {
   if (!aTask || !sMainLoop) {
     return GMPGenericErr;
   }
 
-  RefPtr<Runnable> r = new Runnable(aTask);
-  sMainLoop->PostTask(NewRunnableMethod(r.get(), &Runnable::Run));
+  RefPtr<GMPRunnable> r = new GMPRunnable(aTask);
+  sMainLoop->PostTask(NewRunnableMethod(r.get(), &GMPRunnable::Run));
 
   return GMPNoErr;
 }
 
 GMPErr
 SyncRunOnMainThread(GMPTask* aTask)
 {
   if (!aTask || !sMainLoop || IsOnChildMainThread()) {
     return GMPGenericErr;
   }
 
-  RefPtr<SyncRunnable> r = new SyncRunnable(aTask, sMainLoop);
+  RefPtr<GMPSyncRunnable> r = new GMPSyncRunnable(aTask, sMainLoop);
 
   r->Post();
 
   return GMPNoErr;
 }
 
 GMPErr
 CreateMutex(GMPMutex** aMutex)
@@ -247,19 +247,19 @@ GMPThreadImpl::Post(GMPTask* aTask)
   if (!mThread.IsRunning()) {
     bool started = mThread.Start();
     if (!started) {
       NS_WARNING("Unable to start GMPThread!");
       return;
     }
   }
 
-  RefPtr<Runnable> r = new Runnable(aTask);
+  RefPtr<GMPRunnable> r = new GMPRunnable(aTask);
 
-  mThread.message_loop()->PostTask(NewRunnableMethod(r.get(), &Runnable::Run));
+  mThread.message_loop()->PostTask(NewRunnableMethod(r.get(), &GMPRunnable::Run));
 }
 
 void
 GMPThreadImpl::Join()
 {
   {
     MutexAutoLock lock(mMutex);
     if (mThread.IsRunning()) {
--- a/dom/media/mediasource/MediaSourceDecoder.cpp
+++ b/dom/media/mediasource/MediaSourceDecoder.cpp
@@ -263,17 +263,17 @@ MediaSourceDecoder::NextFrameBufferedSta
   }
 
   // Next frame hasn't been decoded yet.
   // Use the buffered range to consider if we have the next frame available.
   TimeUnit currentPosition = TimeUnit::FromMicroseconds(CurrentPosition());
   TimeInterval interval(currentPosition,
                         currentPosition + media::TimeUnit::FromMicroseconds(DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED),
                         MediaSourceDemuxer::EOS_FUZZ);
-  return GetBuffered().Contains(interval)
+  return GetBuffered().Contains(ClampIntervalToEnd(interval))
     ? MediaDecoderOwner::NEXT_FRAME_AVAILABLE
     : MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
 }
 
 bool
 MediaSourceDecoder::CanPlayThrough()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -296,15 +296,25 @@ MediaSourceDecoder::CanPlayThrough()
   }
   // If we have data up to the mediasource's duration or 30s ahead, we can
   // assume that we can play without interruption.
   TimeUnit timeAhead =
     std::min(duration, currentPosition + TimeUnit::FromSeconds(30));
   TimeInterval interval(currentPosition,
                         timeAhead,
                         MediaSourceDemuxer::EOS_FUZZ);
-  return GetBuffered().Contains(interval);
+  return GetBuffered().Contains(ClampIntervalToEnd(interval));
+}
+
+TimeInterval
+MediaSourceDecoder::ClampIntervalToEnd(const TimeInterval& aInterval)
+{
+  if (!mEnded) {
+    return aInterval;
+  }
+  TimeInterval interval(TimeUnit(), TimeUnit::FromSeconds(GetDuration()));
+  return aInterval.Intersection(interval);
 }
 
 #undef MSE_DEBUG
 #undef MSE_DEBUGV
 
 } // namespace mozilla
--- a/dom/media/mediasource/MediaSourceDecoder.h
+++ b/dom/media/mediasource/MediaSourceDecoder.h
@@ -78,16 +78,17 @@ public:
 
   void AddSizeOfResources(ResourceSizes* aSizes) override;
 
   MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus() override;
   bool CanPlayThrough() override;
 
 private:
   void DoSetMediaSourceDuration(double aDuration);
+  media::TimeInterval ClampIntervalToEnd(const media::TimeInterval& aInterval);
 
   // The owning MediaSource holds a strong reference to this decoder, and
   // calls Attach/DetachMediaSource on this decoder to set and clear
   // mMediaSource.
   dom::MediaSource* mMediaSource;
   RefPtr<MediaSourceDemuxer> mDemuxer;
   RefPtr<MediaFormatReader> mReader;
 
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3dad336e8e22b5444da55cbf3e874ed72b7628a7
GIT binary patch
literal 66806
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
V(S`~!bQIEPhf)3+*Z;4d{|9m#+S>pC
new file mode 100644
--- /dev/null
+++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video1.m4s^headers^
@@ -0,0 +1,1 @@
+Cache-Control: no-store
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..dd7491241f89daf088896df8abfb5c345168316f
GIT binary patch
literal 65292
zc$}2H2V7H4w>LUT=)Fqs9YsJy5P{G^1QAd{K)Q&c6h%QP3B3qXL@6R57NjUxC`w6a
ziU@)QQ4kUkMQI5=5R&=gQ{LzK&OP^>d-I!}z4ywR*)#vO*34QndjbFuJs*B4^z3>6
zK*0F?KA$~*Dw1)z<NPWA-{;>S1VDIY1H?YV|J(z54?u{SWdC`)bv7g<fN{ZhHXzXd
zFCHX=?j3&4=MQ@LZ#wetyua`L!~eYFk!F19ho8F;3;-uHgCfev%JgRuBB226tzyud
z{>;aI=g(`A5CE7S{Zkj#xqs2O{-NuL{EOcG51kAAi*Ea`a%%sfGnfBEXEXj6o&R6_
z2me)0*FSXj5C7r^|KdOPFMig4=qv;O;_vtuf5e}3&PD)GrGJut-!nV@g-POH_zL}n
zuk3H!|AhHp7z3N%U#@>*jQov1qYYa#j5EuBIT&?9c>FGpaftmlzyCMKR^M5FpWn|B
zQn5FYt`rqwZ2%udnZ!pqhFi&e3_6qQIC~G{EX=~pk4jlN*w1m`>+L*)&W|@mWB?X`
zZMT$~WM#b|ocLJ=<PJo%QAz*rY4*{J|1sfcX-qsv_hDJDb2gMctT1>XOP`Ab+km$`
zI~EH(ftG;VOR%ly_?)6zA7-)U1ncuJc|14rF=Rpc1g&Fc@6Db-S|Qgf&J-af8Hs0F
zO#;@tghi&#7cj%YI>5&YRKvM;H}M_cEdToRKwM1{ZavFct!9J*77J2)&sVaTeJb50
zcYW}sS=LV%x-4gy2#IzoRP4R9*k1kM(1JHzT3Ib|rAdc{`mm=j9F)%C6EG97j@ysM
zo0Zilob<mE!CGHdyy&DP+&!$x7xg^d;;2iv145)Mp8D~7jAd=^VCTm`TfQ+|J^O{b
zERK$3-#lXne%QzhJCcZq02hSAoL1PrCW8y~g$z7%Jgb<)So99sXT6}ZO+=T3KYqVK
z`R%^@JQ>5@eCCz<hOKSYy}F-Kg&B|dgJe&BRXwEfBVgBy;t3YaKGpB(-eTp?HB+GL
z*{f$+ZtV|z`Mnv=Nw6}1lA3*YKzd1@UyRFNw#O+~3uhu&pmu&%_Iz8(k^;Z0`j^Vk
zj^^`O!l<IU>&pP(5g_pzV3&KWzW@Fwq|aRzbc~G-hrHf1v6T07NN-ISzc|tIUeXpY
zw2<E=+GCo1Pa)3#u-5h$i{*8%wq&?iXH=yR^<Xb2+?t<a3zv(?;2e&z^X~>I6~}5%
z`g>O`=VV)v;GsLTH*Ef06Siy*T?r6M%CbQAd{qA_eCP{8C;uV1g0d4Y&*DkiQok;^
z{?o_iqMi3kn%t|jtQwGgyzr)&hGlHF$pG2S*7->&sJqlIHsT|H{NVs5CjP2cyu5$L
z({(ETsP7MKwFs9ZvS?+SPDcH~Qop;yV+gaF&eMmL2p$<-I2R%!LEFzSpO&d8#@e?{
z&f`eC%+g4Pwj<B;YwNSfVB|W>>&U5kFH)_fNn)2`K85eJgKKFAZ@;Y&?S7eemYD08
z%b$3u2vZxrwgd0kf``M`$1Thh<T4V)IGl7~ao9i%aYgLi^|&u=9j9R=_YE%LP9@Gp
zTi7-s&*&}qIPLSKOcyiGx$7YfRyMXU>xRpSLzmv?DUD*r4U+p(_fc4cs7J5rgx?4c
zdxY@k6v9$Pms14~ykon#-Hh@~x02n2)lNrb-+5M-%Z*!2JQec3rdH2sFS~Rq1v>1T
z8)Hba{IV|^MG_1ao8=BI9>;d~K%>keZ6T~#kOxG61?E2ArA?lm4pCr{y7m>v`EtXo
z*no}c^FF$OsQ>YqgyXHjaT>ZTqB+h<g%7=<x5f@_?lmoy9{Yu59kJsFLle-kdFPRy
zJaQb?`{#v<<^n>sR`1>XhCa6%muNhkc**R{?dGG$cH3#b$r|{&#9VPKEt%`&dZPc7
zsNRuV3o{buyX2SZ8V>HW-2QxnKea~q^v5Qj<Mk6HOvj0><St=p^8u~{t;UDYrowqj
ziV3J413flqQM=op&Xm>l7ah~>BrmfRupQF^l*IGQ%!S95RrQB~VzQXX<+9<Bn6h<Q
zCY^&wXZss`9z>?>PI=N{@%iOEX_P06i0-L#JGyXXeu!l=AtO0;wWsc#&OGTVNAHGq
zJdNaz6!jRo*Yk86y-pY3ap>;Fk{riJ-UzOzy{gNWUfgyD>h(U4MkuBvX?1N~xi%gY
z7U9i;<g>&7+h#7v_Nk_h4+h9MW3zQ0`@9X6TAb*|V7Me%0TR!}q*#c5qAn^t7WvLK
zh`zSOWWd+l%{<$(i2XFy{>#QLIh*gdp|IGB#9qHc>xvZBl8X2Wit*0ab6vcp*~q}K
zcP{B%7r*psMh56`n5g!?u00}7n$%KW1^1#4`$Lp;O~B17)>3TSX(aZ8yLM{(Tpe$+
zBr0ho+kI@!tQvs0F5jxDE0)fK571=FQ6VBoPLUF_Qq`vFJ8C_<?_Hb~O4(}BQC6Kf
zI<wc{nUl9=PVDp95`kj>WBT=XUJBnSwo-p&^X!Nb$MfZ<I_&9Qh<!j<^Dgh65;YmQ
zho-5r?V&zX=AMe!Z9b*Z--KWrIH#R6_ycGWzFAtd_-)Uloisl57AItv&E*zoHxj%*
zlz7}ZzeCRtlC<s`@`NRZ&Un09!~U}2|IW0kk-I)G$R@vhwEV~iT<qiyah}I)Gr`Iy
zJjovF>LQ9Ws_~;9u`C?kqjYh}@FSB6QuRw$3jT)WaM2uhs<qakW7h}W68b}tHa<B~
zRooZXM|ilk<9)aaD<0P$hBQ)Qg_wwI-K!8o`2)SX`uu+*QzQLbPviugyau&bi}-H;
zVt2GJ8W%4JcQmM1NEW_HSVl0fPl4oPc-zxYIyj3#uBgA~Z<|?4`0R}cW1HqhaqX-k
z$$9G%ea;`vm$!A_#1Es`&2mOATPi=tGVK~rz0)rot*iC3YACrmXo3}cNc)mjeGTUO
zxqfqse>@L}PWEHXN#1tkWNu@v)@hUz<#*3tp>J9`V7qrtL|HuV>;$Xx7{%7-+NJ8i
z*>7gcK15D@T5e0Y<JriQcBY-W`^VqjX>5(-)H)J^;apfT?=a7}`PJF^r>BDHcP2{5
zuh%!OQOSFlTEKQIP4pi8p5YoUxwRIBUNnbZ(D!mwsQ<>EBWVf~6Am3G@ceb(tFHb)
zFq0205$iBv*SZe-gc)Mz+O_-<C|w8UAq*OVtR!#bV#c+rk@*Se8`8CbrW7O}-`hw-
zORP{Z22L931gQX4e-U(1-G0So+(On%o}HK4&tT^9LEtX7{I-$A*;n*cA7#MCoXDf6
zrOPdKU9t8Hl`e`BOU(c$Y7b4^yC};MiEIzazN8;CaFF#?N2RauJy#d(X-##mTCCl@
z!k@=nbby#CuTJIT*8ABq&`><pr7O?7v@)iT>2^APbiXLyN8Zg;Y*;R$gGh^b28K#S
zdHoBD6aj@D3$S)r?(@I0n0i^AoP<kMZtOD-E1)=T*D$P}njN4o0w`eR^l?P-{aU1+
zxonZjN4JBoHL0B?%b^5>Zoy!`(1phbcmY#SvJ1z3Ur((^#ao}_Yn4B1m5h*+em*G~
zZ3sT3RJOt5%qg~CttCv2VVUwfirwCQV}JKn!L-kliAi(c(^5$DG?ncso;!wyElT=5
zFS?WWMST%zVH9dE#$oXJ?kWX4@r4>z;KgyjQiOnK1tyoUiEd}Ec+#syd*yi+izmP8
z1$EK^Z<#fEhzls8y4^4l=l~^(T>*;sxyOxjCfD@{0F^|+yN`Wq{@U>s^U};QrH1rX
z`^K%PUZv`%Ffh3MC*@_><J;j`utkhKrf!>N(<J8GyXQYXTQhB<jZDDc4r;;<Gr-Th
z*IFkkl%>yV=dPEE40oG-DDztSP6~REuWuYnT??3Wm!`-pDC$u=BSUb6$PjKinK0W%
z9+x1k4j;epSK8V?&$9DXD8i{%v#w9EQ6KQ$o6_0hnoz5RCldkZ0R+KUYOUbpr3U@B
zmmZHP5<6|!Ca5H{fI&s8y@W4=mLg@MjgfbT=5h}>Y&ojY5hT2}nZaWXbZv}Nfg=#?
zuG>cx<h>a``E9+SVh4NBIpW8q9=$q2S<N%znuo0E6z!7mQn)nMP$c;LCT1L!@0xC)
zawS+xSy}kL(Rx&$d2C+i5NYn9dd;Z*yb0o_g_XpLU~Y+CM^e%B4%Kfmn<uddfq+Bp
z;nxNbBTVPs)+Fw0TSDSic#3+6qQr=d9dn7RLi^XrVC(3SFawc=?>TGo(i$PuILV7x
zv!R(Rms)S%loONU7*B^6rU}y(chT&1f+J^ciJxNaOuqYgI?b+>)n83P$dzJE!v~|k
zWuGc(oI`oD*i58WPT@9tg&#;ov@mK2iJ_GgV8Em(+LRUOCO>bwJ|232{iL=g1d=D&
zF@lx8;~kA~?U@=8{KUuS7hP2~Q0eq1tnU}vkK%ln)Ho&8Kflpf{dtDvjDb9JDqs=r
z_Hr8ZMFicj0=9QW&hotxunU#x+B@(CFM`;fe0KS?H*?M9qgTenA&%vB#V=DS2qSqj
zt}HFd<RIzI{ZE)Tw4tH&i3<6iQk*BZ;~wwEo#^R?mL|(3QHbPJ_Smx?RCuOcML4CJ
z(9?P|Nejei%9RpNvfDdQK&*1H`;_1CxKDCKp?3GGHilw1!klw;J9VFbk(<jUQ#6_1
z@+S-Cb4v9vQS|mL*Zk7qvRYe&B0nmcj76OC-Zy97#^#Oi2@2idi<wW@;?7rO3U#1<
z;`~HHI`5YqA5)buX^pp-k*ZxLu?o|#p}$}jM(z2&CK47^b5O>iYDZ14e0E>nBt@~=
zH_EO?K^igfAW&y++Sg^I)Kf>~r1<{4^|JY9wh)Hw5YIcLbyaY-TYaXl_1G`%$DAK6
zqV(^NvY)X~j(G$e5Wn^!8m3$eBOt>j6Z2CK$-I;G-MJzY)%a=$P~+HPAE{b#rjIG!
zD&{~i1spAW!m<6%b^8r=+mp`tPwrgG?mb4H^(!VxTe8LUf+2eX-87}<!+V)T;#tYa
zn&Z{9(VvMinhiO)T7>mM^Yoi0#h;wjtqsuK?FV|VChvuB*}Q#|F8tQ7r&kBrE<Y<<
zjmkTE=9ADpBIszUo^j(c(Kv@ksHSgjnO_XU1SY%Y`eEsEZ)1D#?1$s$Kz)|&yQm+y
zY2d;1NUX8H^4Xc9*m@=mb<JtJM1zzvyiD5DBQlk;Mb;bdIx!)1x%K&}o|<?PMJq@!
zfHUIN)_R;}-kXU#W*D1TK|wOBw|4&Hv|))yCUul|1+_0_CNnVYlRd@Sz1C@t)9aP+
z%})<ibs)VX471a6w@Pm{U^PUPo80Qk-YN5l-P6O@9DDR?)K{j?Op9Yo`OFrW-Fogr
z7hd}6t>eC3aFgS~_WQFJfck{{W08nGNGWZ>swtJ&xak~=lhdvDw_QBo*p;TzVC?_y
zjRJ<+IC$xd+*}8G{Y@tYY)?}<Uzyxp53(QfPxa|>tcZ27Nd&x9J@NcYft66B_;~q}
zto@-5F}N1M2;jgC+3JTc_b1y7RssdWS$V!=3zJsEb}mHJe8Lk6vu}`4V8<Tu{V7``
zd|rd*?eGUoujEySTvqWChn`(y*SS&^C-Gy}WOv@ALcO~TcP)k8kqIeRfR+B~xBX+x
zg<-h<)yL5lv{;HwlYht@Pq>K927X8T)Hvrx-RW4Q**QrpDWayVUE)31EpL|R_EYJ5
z{T&Nj_bUw3S0Esf-4#ZdQFFMQ^*n@0bH5^g*y&rB@AMsX7EXzH@QiPbMJA&A+m;eu
zD2ow_$Wo7|r1x(jOOKWX3v-!$kavM=dfp&U{-kRC;DI+mltmd{-WDFfga;;o!*p}9
zjxG=l^v(z*-g+H=9n*#aBC4oXJEPZDk0uT1kJGnU7=Es-cS94xBPdhl0!0gtOikyv
z=;>OkhPUC6UsXq&D7`{4)$BzYedeabZH1RONbyMl+@nmlRnCnmc@cMW|ENl<O<Tuw
z;Np?Q9VZIYHTEVgB)I%BTELa^Aiq{g;B`xT&zOTtP30~8LsOTiUL#M682auHwd$+q
ze+uCvl&&<u-SO2yQdhFI@(Ip-?;pFmz*6L4yu+somR1eSQos$eFP0l>i&n{Jxx660
zck;7yG4dpXTidmUGSiRx=`M+-eC9v#nWySZvX#_jTCkx&;KcbgTRzgO^l@HTE*`Lm
z=`=xH^yqYWQc`=I=P>_;7YRc|k4)_}0rz~I<78FGRNm@p3pY9My@mN@I1tU;x#3jO
zDErHSc2_dO>2#_}BaTGfO&5%(fWf0>)vaC9wMfHXiK7ulo+u}guM2%dj6r|lV|G2I
zy}dgO?WNPQXvVxVvPwN%X0%i9;++ydY4~%f$2`$MESngq>`k>49Ob%OqMo_#zIAc2
z>;U(*`0cSRywL(5S%d4Jy!#m$6l_8rd$E7SUgkQDg|+{T#6WgtDZD3VYRthHxp&x}
z)0(|RLlCP^-!Y8ccSnX!8RW|>_}RPX3updHd3{k=v;^Is?KfJuEf939Kwh=V$dhF>
zSI5kGXx?gIsZQ^eYct`FT-Bu+^EBL`fa9r<2inZJT`c<v7ea%t-i~NECL*izj#+Pu
zSlCefg10SxABV&Z&E&f-^ftKZD0i^WuMFS}eC@A0xIAJ$&CxvWI79whr1KUHi@Pbw
z?E?rq)^o1SAxl5x?)lc$VHV-gmwRFt@3Z6qy{#Vk2kDF|<zCxmS~;_hW%_k2x#o;h
z9lJ9E?N%%iUXP94Js<yp-S6UN!TiX4FHhLStd^VVW5IU;>nJ)F7b~R7YWgrkZ}(Uj
zx99|xne_QMK}^644<1=OzV2#gOU<=G?7dOT%3UxW9+Ji)7@Q`{71~58CEsdVZzYHx
zP{^Fs@o=Ms8!9WKuZmd$nZ4O4Cgq?*W;QAhf8}peI#2h;UkndaQ0b6^7EFEeuiM?6
z!CwH*7WD<lr{5X+mATNCO1ew#6mFJ{m3^x7;m7&~-6?6m$(*>K>S=!2*MvC<$Zv>6
z6@!}*V=y43BP!kdgDiK7I@^me(;2e-n}V}z&O<~==_T!gLR2ZWrriCl)3E5kM?Ztl
z-~0OEP2xTQs}We5oSNpneTfI`&MVC29&m}n{V)}_Fr8WdN3zTZY|T;z+F5GrB{X~S
zrBc2mgrTy=d(#s#RH~Kv(PIoD!{NAGwF}=7QUV_1yhx%3`K|F;`*OLn&x#jZU<B<U
z#qMC0cXYsQx!w+q>Geg#kJZG`tyj<0Sj$a(8x+<!8ZcB69N#|S1dw6^7t&+3PNZIw
z%dtS6=3BBkKzn<`wg9<pA$K4Fct>Qnj!HA%)iTapR16p_L&F?_jw~#bLBq=aCZ@||
zG$fTt)d}p5-%VDuI04Iq$k8v-g!kT_c86;@C2U-Fi#tS<an1633d6q6;So16y&K8z
zI6n5jt%VdKyJA!*|ExV0ad`XWD!?ZNStE1IUisf)pA$8X>v=QmPii=*OGncJ)PZC+
z!0tZ@p|=+nHTMB@*eaLj!&50c!d$I%bE<>F?plw7SI+m*6jd4QIR&oj>>-Kk;6(nd
zL#10YN<H@@F}MomX5#Fdd?t}**KN$-nLM(W{L@~M$Yc<eAvgNr9*4rG(wB-Nk01~c
zy&76{$;`=StV}P}U*Ci8n%V;x#8MuR1Xi{kAk<HgPwvHP`5aRHy7g1A;8OllRP$Vh
zwf+Ia+p3DeLx0VR3T2K|BshNGd5Ujgqiv#~X1j29?5d0x-0*Rf1pM56@-4YB$y&L`
z04Fd#I+V-RsD`%;yctWz+9)ROH+~UW_`n1mMWQQtgY2)#3Rj_{ZPXAx?2E}ew^|J?
zYdR1~y<<q1?3}F&9^{a`cxd<0>Ng`N=>RZs%54<%dL3SHX$|yQguI;{cz|F@y*&FM
zeqAtz^5_NZu;Kz5+whC0N8Hw_MEgS1C5=TH+ByZeX`;HTPX!ScFh^GP+gRpzugnl2
z%+lWWAptIvU4sdGXZ&N}c}NC73%ajnsx7Wlm`6_i8p1%e*+(q^@V6=<CW+WM41_7=
zSdgSKPK8;Jw*W|q*#+<xNI#BOL@yjp1Uv1<k{&vJ6^($9_rh0jl9jTOV$q1H7Ow&b
zgkU4=!cg{`ASw$ieU1bw9Xx$|$q8VY{rf3TZ;3AinTT5TdF}g5=i0}3O4eOPKOHfN
zqy{<}L%~6IaloEjwOu*CO(5G*O~^3Fw6)Z#c6fe2pWRC{)k_!>CRfog0+O?_AP|%F
z1$|KfKPkcuz`-kTcPsPaowMohU)cm`AyU|E0oyL2yJ{R}*>~mklfjdt#pN=^oPmoG
zG)QTKbO9B03xGtN3Ly&hv&~0<T`8X-TiQX$O5U+p>6HaATNp|VR?Kbo>UiEDFwbcu
zc>^cndWsAr=a0MxTwDi-n^KBn{EnCaS%Ztb?SD2|esvVX3xvfNUaKPBq%b#I%j~u$
zK?0T0&@1ilH*FN{)!$+0th|dDx_}}Om-)8lFqT-SpVYMn3sfwp#RWly9PQrK?7ovJ
zj4X**6vRMwHo(&7A1*a==dkI{sk?k4_Ze<3e^@XVTES-5_3otA=S+YL{S9`KfrHrB
zlkX~b>}>D)-ky>=3Ac=GfM|A|ycF*qcJ~SPE#RG8<a1yAcS<gh!7}x6o5`4MzAi#>
zOu#M%syT>A;FWP~$tTpgua=ZRy#lvdydQxb;2_aUpTxIos*ZL6&x~dN$~i4H$>MQC
z<`EXjaC0v$6#i;1!7@b827s&_32qr40(D&4ZZumD=1BV@(r5<Dcb)^USKlXS9UwDU
zF7c+oiEp@=b(lhz;bS;F-ar;00*xm_+9;cV&2xc-!=heV>~<2Cbg-3!i|FOI?5}U@
zbl)u7DelcnOCTeBK0~iF6+gf>nSoXJ6KFjOsGGyoHaIT}M3Md<Yb6lM`(_B^5%`qJ
z;e!i@j`k&b#S;H9%8!7J#ZS|t`mru9S<k8V2z-sEVrA2<tq8JtZPf|+kP=x2u;3Ok
zGEe@jON2K7*cAZyq`&?S!ucI_hmS{03vNuCU(o_}bWGK#+6E4f`1~<{f$}I7jw)Ys
ziztP#4Vk;+$$^tMFpw7|Ppa+uUOP;Yc=lo8A%qm?-;Nm+P(ADdSbRBGBd_q?J;sp@
zkSy-0NeHQCIzq+dfICr(#ff;Po#PInE-vSW){*7I)+2OHzl8<O&BFVlvflf3(x%Ts
z*Ea<wss)u7OD8{;(kJl+ZN0j^F6d{0gU`Q&SE&p`-!Q+V!@!X9L6mG}j@kVF(o!t*
zq(gO8kQa4?n=V)qQkOi=?8@R(-c_~aB@-tX&)%}rujBmZ*!LFOL@hN9OdVb7U;54v
zEY0cbTR%&gm{BIdwxM@-It_`!#-*vicaj|(S@h~#LnNA0DWngY1p-As?LteX9eXWq
zyyZp-gz??H)`h0x7L;cKvma!by{=juc9W#x7iEzKJUkX7MV~k}t{g1$qtU!OP~8$M
z(1M>-Cv)FpW)yy94n0?*DAZ=$d|0J*`x`Md8aA*w04A<=F&-2@^%t;7wE>d5I4|V9
z3mxB@Mr5BIXjk;Nx#U2lt1E}I9SMqN0hT*iKJrx^r?6XS@9uB?CG3>0{kzK=dsb&h
zcib5hL19XhIbQL621BLo4)pl>;)vkv$Kx1yQm~`E4B;o&JQRk~I{e&Wgv}<SZs-UX
zW)^E#@TxdV>E!lOM2g9wX{_@5_1I<a6UTCLkoVf{+ah9C;YWUBHc<}#3o3^mWR9qz
zA#0aO{FB?9J>S_KV31E*)LtX48ajzKqW+7c0Ej)=ws1tY_<H%^li-%^;e4^Q&!Mk#
zMLyR+(Yo!$+mx>&<4JA20)T%oG@`!}yJ$tjy<>`+<KZBFH?&cUjEUI#MUfRi{!meQ
zelcwrwv$u&o<9B5ROEzCaE356P)-Q24=JF~T5RoS9;PblH4IA&k*Kc=>c5!09Q)Q=
z$8nTr=aC$I+zbs0Uyi@K9bts`7L(!Al(SWv%J#XPRydE!SF?QH@Y1lV-}e_4Viv&Z
zlyt>oEsmsNLaAtx<l8*<uYGwvFBgAH-xY)l*oIyx;7=yFVpTYHe;l^@dhiu(Muww+
zjm}%V`T_9ctx2j$!d}RZ_k+w{t{<t9hz!1V=XE-h78x;B7S+k+Qzk7CbN-CeoH@m=
z6>!B)AC`p44Vn-jB@qJqIhXvcmG2Vf#BD8dOF+Ud{&$T%N{Uk~QWn4G#vFwO8Q)$j
zaAGM^fW7UK#cb&Yjz%vvsptqIB22RvW<I(11sZW(X~XGZ_F=HhPm%8wV&nudy_aWe
zpNZnAQj>M}DpiL%j;t*vuYFEls`-AdnAjl`WxD>VhV8v2y1lQhX&)gpSn{flPVR@H
z+1HyfrBv!>+))nuO}6OPMQ-%jhECQZzF8M;k}<Y(KbKp2l*x$+QqtUgalLf{CVYEv
zC$4q#)LVxY7Q$236T&g#!LuaXyly+UGqb)_f(&FY(~F~hLZ08f-Z+SDqD6aWe`uFs
z{$8Cq9k`yLn{$QS4R1@=zU5t-#gK>}w@Y3KIq%?7mEx)}`+oY(pdETkB^mkcLYPW&
zNk<&!M!b@T#ypw(RSo~$B=m3w`fS0tr^E0Uh-)M@ac_lYA4#|t8!w}IBt=p|CwKVG
zxQXwzZY&9~CN@=MM)Kp=4#wgLBfLxb95ros2(+?oLMy+<SnFPhYM#k9n@1ih&)Lso
zo|=FT<n|GAPgU!x$9`i!@lz(M@g*Al)YE3{q@TdcOgO?zb^p$G$d13B%c-x!v<dxC
zj6nCAVzJkqEg4Cw%iNJHeQIX)iY>rAIqDs6_xj-WQSmIo`Zq0*n3ntHjZ0;LN_5$9
z%jg1%24h~%UvZlwZU2y|i)kOjakX!|#>NOl*@qg-?Z4z#N8<?3kBYr?vX@=G{Bus5
z^>T*d>Sd{$Fo_NMNvK{|yva7Ud9O#^G*UEbyv3)r(eDyLx=wz-BovGJ9MQPoFuWc^
zXPM~vrn6VW$n$})HwkB6s_7Sx84>bcHWRLzXr0FYB~8tByw-aw*85V`)Z6aiQh&<y
z)FV=3Lc}-O*Gt8hTStQ8#qV?Yt^2JU3UtI;*EWFjxj=&5WkDA4APFQVDGI%FsmgZ1
zQ%Lsv4nx?)^&ITBZ~{L~7N~g3J4})#t@>f%p6Sl7^XP(`G$89T6y!0<E~YOEVqf`~
zGM^5zm&S9QBnlk5wp+tjzuw8F(i+le)iN^tGSl4UaU-IeDqUsZTl|Ogk_I8o^-rc$
zroN<-eV%N`)7_dPLi*X<)6bcpd30uHsj<|v_lz;vz~`o!IxNk#2?YlhP4Zy{q}Y2@
ziOF#=Ypu5?-+mt(Y2rs9vskyV1j&oc(iK|oTxyY-eMF@hz`-n+#LgPA)nDho&t%`Z
z+CQbcwA!FpLCX{V=yTP|aL=pN3N2G*I~PM#1Wj;JZn26X%2*xK#6peY^}-l3hS0V$
zyb}Wnbe9UNqPW|EzE``qEf38$P87($_hGGW#~ysxrude6-KSVSHz>=cju&>E=&sBN
zIT-o68P_xtS^wQTDnEDpK8zXM;<vof&R$X*J7>#k$w}n{TwmDpzR&I2_UyuEpEln^
z3CE&5jkd=t)TA`DFXq1NxqIQBAEv!lBA^dpK0JHzduD4SpIzvbS_mPIp0Oh_eX%?5
zBE-Dv!XlBvHGbls>NEV@26!P6F~{E&Rd{Hh**q-e<mW%}Ig0}Jx=s?*2M_ZatC2&+
zvY3-fV@US8+i;M;Nj0^s$y#qBk6{s)wndLI%fRnflQrMke(HqD2&acloYX5LQb&A>
zPr>=X&zqx;JLNHPDOC610PSo<_S$73(mE8Eur9(J+P}p{VOQU(&f4;Mnx*REf*Aqf
z+eP>TLt~s6Ue%6!=GSfRFqL%qz~0VoGt)~M8cX@4V}<5luAD!$;HwwjXULpnnHR1X
zFu?&SK=KM|sC?*{)<+CQ1W2bkdMwITpLXw0=$n!|#^cdw%<`toc9^3FZi$|=PX6s$
z&B&JrF?_7rii!_5cT9@Qs&22o8>N!AfJVW#G>KnqH|b=#$<gayW>3N2Q&}~gvxg5W
zoF9e1``5dU+?WZuLk7q-g)YY-SUW3T<WisW0oTIL{#-;{UBCDtg}usT@Os`oDxBZ@
z2C{2`7UlsBa^W)JlgV(jV55^GuI0y8r+-c7i)Q*@@DZ=+mwqbiaT7nWfxTq9fT?$f
zy7AJ0hgGIsuhBd)(6GM8Wv17f7MIuZRK<&^WN72%8w^*!)ES?CYwSsT&bPM$Rm!Kd
zTJQ!=OfKHl4nQx}-@CIapDQNT;5AN0D43^zoUY`;d^W7K3dFDr+84&v%7<E#21R`2
z^iF4N&xq)B1+EF<Z#awTlHJqQr}U<CwL)%xo#~eCj=cs`-k<`wG?mjVM|v<ls5=so
zH4mCE*@<0YIQYFBQKKQvFzDA4$+4GLqR58Xh(c6C>{&Z@RNIfyaX9iu{zQfQp@EG=
zgUnrKImf8OUFkWBRc)!P<ca0Da|n%8k6z(YT98DVQ{l6dYq%C}w&FL5Uk^Oax@6_-
z2Pc%?15SM9i8jF<?*BkaYasWWec)`$tKu(1;2w=N#kKI7pR0m975H(j(AS(y-Y`L$
zY9#B2x%PXx)#B&?$(nNdq*}VpM|a&Q5z&Grv&ZPM!vT<TIfjhb`-6O1;c?6mwUYZ#
z(9nTJ-A}zEzFgmhYUt_q>N4aU6e_f#*#7Hvp|MS-YdIp9v_H?&i29NmPuq@M+zJ|=
zr?19Yw!9VLhd~~!2LqAwwGp%07`pUDAFbhQ58S3{H?(wf4!9>e)1Pq_yiUse`1A|T
zg#h1vH2=(m?yzF2F|7M_x)AP)FIgL1fFp?cNB$pbA#IQO&8Bynv5|^A)SDquFz`=c
z-|e}-g0{K&rTsON#?1qeOuiM#_eJfA^PX}vx+m4Xe3$(GvZ%(Ovp2fHACn~Yr|$v?
zCbXEd2-{E9=)^mzLN6BP<a(|o>CatlWLu?@)_42hc%<aIiM%+UeknHf?O>yODV=q4
z&x}-1*ZF1A4u>7|`GDt{wm%4PBNCIN70Jq54EXj42K#<svlxPz4d}5g0li~ow)QuQ
z^)s4!m9pPmwHEun`x>Nguso9C5m1cxE18<d9Ovrlf8&jCC0g_9A_Y$Du4?*lppo9t
zg7oRkJA8Mnw*P}EcmBZunJxWj$OuC0v@P?dlb%KUXUN|<Kf5g}O^XpX116Tk8`?QL
z-~JkUvSFdR5S@K7w|@SKRz-%(8*gHipcG=7rClLp-CI~7P;lgtl_`c${>e()VC4n?
zC?ufkztVm1dMTe`jC)kwUHUE2O?l5bb*C)Yo(y;k2*vHOF=>;SP3a6p;h@5jE7lPZ
zaZb`g!$$sd-na}rGR)D5MSY8y*77R#jVz_VON@VbUgurl0;F)}bjg2=*GRJyFJW{o
z<?70R#BTS{6U(84>Fx(670}CDY`wafk~w|HJAXN}GXeF!nA63Hhr=)wV*&ogXLr?a
zGeee&M=wZio3oEL{|Nrz@v!#*DcG#DulcD?GX|ot2rW_L?+=$CZ?uKH(pK+LkA3YM
z)&j}*c7(YkoclHlJEypSG%yaE+~ZXI+<~5QWYvpeQ>4~{n%K3+4oxGYl&$TKUnrsY
z;1Pp+qvUn{cj-Zz&^UrzD55Mur`FC^ebOLuWgJjBaro(ACty_==;^WTQI25PiCPKx
zsAu*16>J0kzQ^{d-z(XAAEf*kq9M(Ni_bhxa}U_A!@TQ(LoBc#ksGvawY7OwIr|_z
z?T;{arD8K$IYdnKa-<!Je1&)H!KdBlthLQ~f$)%)T=q{|EEWKc(@KE+f4^hM2r%2(
z>%c|J$CAdxb1!YO;qxU?P$(F_t@S_zbf(B|wgCmy%4O7~JFdTfoB-+HI35A6Gw}-P
z&88etN0z5Rr(Jhb*;nVUC0N;qskoEct#E*Bg6aDpSh?-wNef;`5KglH?a-jkfKc0J
z)k7F3pSUc`TY4e{qOkeUFO8&rxMfocuioZJ#UtXP(Q~Vx%~20LbOAzLvuW@q!q)lM
zekq^NcnHVYJc0M+wtXP!c8Z(2e;JYPFSF%hsQ&yX5Xw9JCV!JDlpQr)9v@&v4Gvy|
zS$Tk8EQi0akY6kxlEExOz&XxSHd!nhPGXoi*-ZGjmrtfWeHF>#ec47`2<PIpF%Yv(
zh=FUA(A#DDfFH&DtPn)p=TdUc|3)W!@xsnmMsz9(M}g!GEMk}T)7yPDnrbmVkC+TI
z4t(5iHP5;@d;})8iG9$zEq*T~0Mo!Q2?S8}26G4RKD)(l*#$2feg-vtd#@v-$UIY~
zVgs)a2ttN<kNda+qmIsrdV(dsls3UH!u6$a?XicA&kBR7yWZ9h4U<KGb1beBtnfJ6
zmO*X1HXs5EAj(t*JGN0Q`ZgUu!}YhR7EWvTiZF0uB82cqTei?CnFu_<imLM4r2wQX
z$TX>V)OJ+GH)YKLpal<VENNGhWWUTKt^BTHmY;QsOg_0m@Y@*(QNd{lF$KbGuC3R%
zA{nAITlos&%Ect<+K7NHl#oKTQN=3hl|wnRtju`(<uS7DsU3O^LYyOt2bXgpiD^AT
z8Ao?-cvmiweUrYSnu93aw<T09`)W>OgZ8$ddAvjLOrmscr1lv*s~S(^ALb`GRgUEN
zKv~4bML)sY#tYtWijb%_Q8tezliH)K2LnPSi4k9YY~~VI^-CbkC*48C>(2x0vA)Z#
zQ7EB(wS3E)>(<FwSRRcg92Bp=V&D|gMwNeXFtV<69jU!Jw|n3K4Go0vpNUWZNwh+w
z^ADAL*j&x?#QKgc^SY$cSPIBN8p(nhQ;bTfN$l=c>THt0ug2R=qX{$;&uOOA1HM7+
zN&5~Hvh(g<FygPeMDOjxyV?v?pC#<)Us-$4zCmn%UL$|^+-<r>44)aDZ;Q?=?w6>g
zZ7siCgz^09toA*m@eGH-ImwImv8E0a?><}Ms06^_BehD2KW&6-7RnV{>4b0e&y`ty
z+RSokG1QCM_|`hkTUS_q!sPnHzuylaeZh;MT)4gno(^gmm37ILS;jZ*u}3ShksuWx
z?eCSJy;Yz|Je~IA_v-N4a6Vg`smO9far%S;izLU6`(E7QKitIxul|0cA*YZM8C|wr
zR^Dd&jWats9Uqq>vOj-OWZqW&<)y-PE@|G!i|6by>)ut0*Ii~`%eo6cd=fGiAF0N&
zBWu~z^1v_G)9ZKIc)jsNN8#HF@7Z~&1UIo8gMe+D7#VRWf8b({JuMU%4{98rt4owB
zI5ihhO~VW&)FV%P{pDL4n=X+*o17O#$INxl^@SD4bt<Ped_)gnS%>{LjL;;}GwBN)
zI|D^KFA~9)>T*Y(_RGZQka$=_!yRq5%w2re<~fe^D=aNv$5v*mkJW@>o8!61gnGm3
z50K>wIIn-umHEA*iGhppf}wwy^8LeqycH8O@#nlBq(<{eU`6@N_PC{cs?FB^x_`^=
zO!(g`pJo2^YX$co?H%}IvFxkq%=(OoyX%}sTw)vLuLV%FGv6uKn(c5PPTgB&);YoR
z2G;GG$y9yywmv>^d4%VUHsR7)<@1^XMDF#>3>Pu$YCOUty-!!R;QH;spn$<U^G^8p
zj@nP899&wpTVqj=Mr8})M{7TIBHyd73Z#D;e~S+`UP!;<Fy6m7+PJAwWH)A|0XU!h
z*iBWNSsnatD&k&c<jG|7K{RKVd-2n5^}2c`BWmP9rQL;0!*E|*;ncLVH3S~$>uS_<
zJlElf>8lIM58|Vu=wGo+?y05bLalz;I@?xuWiL>lh8OyD;l(*V?%lkd<q{_y-u17A
zQq5b|g^$_yIOpRc!RR@wK-<f$%MxSZu8}v51WGrfjhxbKe+<wu4*t4_wvYdKs%7DL
z_;M>PuI*YU*U_1v9>Z7N3jZvkd7JU<$Ouq2afZiGkC_WgO7)uKD+ON3DXWXnsbs|A
zWp<lbM^SEz;+eCAiv=eli#SdX#-AWZtUPU-Gh9kih#@SDwTio$eU|U`z4hXxkthAJ
zMZKjhsh6Lk4}QZbJm6Ax>2UEY)+zE!QX~GNa%MfwPzD((FRUEjt3bz83~uZD9{8Wt
zR>!AXHQbAzcCKT&gLIfIg&9&BJ!kG=$!PuSPaetfMdvSn@js3zNmaxB$Vh%TUCE;i
zO^F`7(K-${oe|p>uRX1e4?<6wATMe)huYn=+?hanaJ3`(`<02xebCEwV*N^az-QFf
zl_`ZJEkwZ{f(s;qzO!u=aGEJik$$9M08z=5ss89*1g&Xze*y7u$4^r;3<TP4d>)0(
zc%Fx*7&=|EU4B10e>CE5`gVeA{I&(o(+%pso_SH|W66L`b?7?|i<-1ktetA{IErCi
zm^wf0<}<H<RYtT{2w6CJtE_Hpg-ygjD^jy-C`}uF4p9cX3lMS3varvy><cTFNdn6|
zJBUC$Ra<qFWqr5~0QSVEfLDRCM@O;90CR=PtBF#aPP^H#UWI0HIYCd2pV!^)?Na;l
zc=#CK9uC`dLmt;NtC3vh{@?x3b4Ao=i*j5q{f0=(yTqjIF8U1CN91tDf1}%Qbe7s5
z3XnX0|Aq`KG2~GT%kDH2O&GuP+ZJmn=5&WmbFzsE_$uNu(XeE*4>JxL_(y`BckSJm
zeD7bA^^^l6GKu{ih1jc*ei3k+|7=n|_@<XY_U7>0b-egN)raJYN6n;l0_hQ%G5-De
z4jd%rQS8Q*b(Fr0U3b%uoeBuFe?F8tkqjh~js%YG-MJkzDEzqe7u!+GFm&F(UY&z5
zP;NJH77yE7>%(p2iLFc}^f+A?PNc&;9Q)Q8>;277<?B^r?_1fN{dGNkBB8VLzwW~L
z^=sw5>UcPMLTm($gSS%vhrEzYvYMl-1D%%z>#T8iy_yh02Bez)7?*WM(EFc^^gihh
z*Uk&BZAn(AA;Wd4((X?86&CJ-L<+dSd-A+zhxp~zc$2-KoPw^C8gYchmTQ~;_2Kl=
zEn^#jLFOD<@_HM@efTLvv5y8)nIcgiRDy8{9n4oBRy4odpaUM&bq&sXY7ybP(cew?
z2*(0!m!I1w?TjF|mwJrYKhodoAhY#A>fWdTbO^a9t`e*t-(Ta>h6jnW4KFC30TEQ#
zxYE9SCrbB=Cb6@U3;?r?5^&qe#wNn>F)ynEHm5NXt`m~8iTZ#|7y;N!Bmol#7RxM4
zCIZ>ROh68V0zP#l5K3S)Iq!dETEu3tMXT@tB(sSLQp^VrOdhZS=N*6LJCOnq$TC@k
zU1M1^8nT<>K@VVKRpS9HCcs1=(W4&<b^#;;&m{X72_(uun0Wh7KEQ|72VwvLh)BN3
z|AsSzDbjr6KSk{7#3Hf*9}kebAqlt`$b}-f>WIJ}Frlz)Ct4#Jk*YMK{RhVW-n|1?
z&=o>~U{8Qm@)%FXFJAMDm9dBHwFafAEFi~eXIrqx$QR{I`&bO5b20BRb4$%W-s?38
zC(s>dArIIg{eAple(BAxjeod!>jccYZw`OtwNP*-qo4iBtz&s$$E`{GJP|uB+-R<i
zU8e50Q5bl_Yh|mjbxtN;$>{oKPZ&Q#tLhpsGso065+>k=Bt!45<uo|iqUFfN{}sZz
zzo5VImn?RT$JJcYs_&5b1OGoUNp}68&}gj6`dcqa)6*M^R%C?F0(I!ghh+>A**Uh}
z_Qs)~4t5w3E;qQvhQL*HJS!QTyVyJM#9)#{P1}7sh>qJh@TYD{nIQN#YiA)H@aBjP
zu~~%0ux+K@weVz51KYL@&<-e}wLsln%)%4rW!AqbdI@T0pS^6d9W&f(E<?9u=(%Ty
z%pZ%`@h&(v44v&B7J*~5&gdJXz9(w=AeG6{`V~N+9uR>XDJT(5j}xi`dW>IFS{VAr
zRX-^Mz0(;oWr<`kXfSf_(g;g|gYxMB35*%|MKLmiH=c5EjjcTEDnLrVW9a9ePbGgK
zFk9?G7tlKY&Mio08IpGy^gVXjt4Al1LFh<Ds(?;~Zs`K<$f_&u-L=9!&5%{-Sy3lk
zChO{9f7l)8Z^qGq7R!0fMo7h;K8u~QSyG5l`=b|yG;(DVSS#aeoM#SgesKsfZz2~m
z!Z8sMjxEuN?{Y84QHiwIQ{T57083Bb;7zrm!f^J|HKR(u7>Gq;KL%epcyy!KbLy_L
z)yU#Je9CYssjROV`cu!)9~Q}L$$v_)<i+J*vlV}y{*>s@g>=|q1-Rvl-;iK5OPuba
zaP0M15?MhqHNtG~En+9&c)Dko)ajf-FZzsrG%6mGyu<0n$Kq5P4x5=HD6yimuk3GQ
z_^E9I7d=FhyhDLJVEbgk`j8lXCNq~4#y~Ex{f`2reqy#zARd*%7${jMoK2W_Nw9~U
z;yTsrH3>xSB0MUj6+2xpbl#@062Sc~Cr)QdKWv-BITI#T;qvF){nPlaG@IPRxL79K
z*uoTgLbF3;t2>9|s3UrGm#_bh%LMon+&A~pn3v1c3*<&dl~+ZT$F$S7LLsjZV%acN
z{aF`38!OMkA852u-T(Qx{nhjS@4NH<NVNbUE-Qh^|GSI)pLYGx(Xg|V5%!${Oe}zT
z*Z;IXkkoc3=>JP4{(mOOa9otJtXM8BF2U*@c}5dfe$&*C%z}x+8zUMIS~WN^ki2rO
zi=)dM;ZyLn^)Pl9Yuohv7Le2_>#6rq6G{1ee!YWfm$sESkzYek>u0L9mWSbOw&u1-
zl)T`n)QsFyvVe)nghNhe%0ga8w8!+htu=cZN1T3944aPwBrKLr=xhSn>eCd_xEG=G
z{hrGJn3Mqy5vGAo=e)zIBdbU6rd#4a+F$r*9RIIro!ZGbVSn!sWheg+`!SJ8aue)`
zSmuL{UxBwSG$O1I?*VaPO3$RcAVXfYK-BAUHHJP)2DpVP9GxWKp{)L>)H1piA_H*G
z-$3f+Rl08|ij(F}CzZk}Sj&02%RV(3LsvnF{N%+r;919L7a@HSuHnT}s$ZdR!XL(L
zbk-Iegj!d@z|3Q~T%C6iylK9@g~?h<#dA4~k>EIvPC?LT>)`x1f}A%hpXNzlf$6d+
zg)vfW?K)Os(tWZ0r}HVVhP5)XU1-@AER*5Q%kq1$qE_1?_V>%$WcHWs=>0Ifg}}M@
zN0^Z1r1aJ<t+x|m%dBuWzGf`c1}Uj~`1AGT<ip6gNSEg#@uI8^aynN&ZMksS)?iVK
zadCP<nAAAUQ=>h?jgAZQQ&R0N-iU&Zcc+L5Lxc9343(n}l04&yrH_-ly&^G&sMC};
zG{hUp{n6nke|q{70X+M{MOB=E3|@A4V!RfnLshK&3Jcu<&JOEgMZKyBwDC(?l1NMS
zlU3b5%pIprI`@3z%D&HfQb+&;VHlBJ=f3yOb!XEdI#C~Kp?;DM`-v!6Ya3Eav*#AR
zT9R_<u$rYwl=hE^FF6&?S{AU#tU=%HK^;mc<buMpm)nfrJ;##;kL^AogZc5efIrOS
zZ18&AgHwF)^68p5;%r{F*Nu6511YT=qxiZ**VLS0F!!S~O$x8z)Ak2Wt$V^k*C@=N
z{k_m~8+@4del{zPXQDR5^>%!Cyo#Kf6Ir+*=8;8g#8|ofb;@ijt)^T4#pR4gG3kCs
z$hY=Fuc#l!K&C=%B$zR_qq}y1<InC7pQJZ1bZBZUCIn)-&IuusHXkpNvfxd;#aM0B
zHUOBs<PhHy6`41pBOaM%BVO;Ug{`=|=Ga{&5mB>|iRZ8PcI}_tfIcrD?kv)I&(!II
z=BPKUiiRPR@<C4l>WOpdvr0(zY1hVWrKRiO5w91I?&*=RXP2X5QF|=xLIzV8u!w-P
zvo~JfgBw{<kj|*vZh85jaLr5mSapP!H;N~-f&NY!CD~D}H7OSV^<`o)%j5K_Ei6Fs
ziP&E&n#IxSsEbbs_l6jTLDpkXele67*o@UQ{&E_CCCFb-&L59}A6R*7iC7#_#efr%
z6EvM%SahBtt!sGK!l2$GCvU{XA%_=q>TCMRIKfcqXo&NKeNBiY_z=>*F(GvHfh)fx
z`rc5tVp;Jz9x>r~?kq=2?`KGG6^KuL_I$N#(7*|{-K2GoZK-3sy(5$)$Ni#+eIUjK
z=<3cEsPnUZ2we*q=VJEvXHrzjI&^w_5ZMRITepwRLX}x^^G8wlPQt{lIqo%^6EjVO
zH9R6x<RY!_V_ww8V$~?|6#t&alcdsGGJa9;hv4!S<u(G#$^2X|O)2FE#52c#z1fx9
zxs1W0(r&18A8D?d9sKco8uSnm;ce8N@ujrj=4|(pH(${5EYyQ=6KXvGo0!!QNRU}P
z$Y*p35#HVU)8Ka5v)s?b6}3mT{3HrwjMHX06}zQ8rPaj4%4R6`-X_aiws@8yYBhSb
zG3DBbTG<SwoikxxC9Ia>=xDl+p;wRmQ1kKiAH;r)CI)1Ao#icHVIR@8S<$WwGLUX9
z>G-fcZuwg&htrCP!N<JBZRteGGmngQhR!ORxGAc+c4xVbyI6J23ORE4zXw9g@7W@q
z4qZU?IlA*ZID`^=n5DeG*1jRj-aYYxlnCjAIS-)4<^qBRYq;@QcjYCWi%)A;(21BO
z4twJWV??ItM=2NHg0m-?^z;gi?WVIfw&<re=q-*dz*TzMviijIk99J_JL=Z9hc`-Z
zQUM1_btdn0fKO3BPsnoN7GG%UyUN;W2*2U^_XX9y-*ID+|BkcQD(u*3K@>JWhEXEJ
z{y;GJQ!QbG3Rinv`DakH2Qb?_5^3+%_F_qrKYGA{j+-5RWM-l=G`l3Nq1eEB^L0hJ
z_*P_eS>luKV}VzrSVUX58)5cgb1%NBNy?btn)uZ*uwAIGbmbG`lrJI86BYOPbU@zq
z;n|DHE@$={N5R^hk=HeMo+-SCM>yRgC?OjJ*WT-x7z)#sW1@Z+eg*R$)cR4Awv@lI
z+&#Ta$=bbKv_-kYT6U{`_?NU7EJgV;eAx}g=s{*WI5N9(Md?KtPg-VAr7e!Yf}A>2
zJnR8CB?;3y6j_R1h|%WJCwOwtm%Wb~AtWLs8cS&E$GmY|CDC*Y|BsUMURmrCfB*cA
z$Trrp{>$kN>YIZ9j~68P3_N+Kp1<SXjjUF^jcKwe*v9-k$9KQa1`f|07wqqv>l*8G
zoXmVV0&z5&G1jrj0rKzBZjX<$3PNF=6~4X+!-hF-A|B)Stfk6%M9^h9sy$HgOmW-X
zdv8lU{FZ1rX@n;#ie}@Hcs}I{Hc$67Md;2-M7EcSB<V$t-G3``s&1o;&Yr;vn1Hti
zGZ~2&^TKGz@OlxMvAf#nZpPBdkXEC7&V$jdPiX?@BeR5$Au4{)c2ZRUDz88LNtHC<
z?8!hsOP0Kbj>(M6a^!omb<PET%sl;~ou8J=DYdc75r)V6ybfV!Yg}I`05_fs^xC<V
zEpndRSla~OJUbCojfKbQSJcC2K0c+L4d68_;<|uzI&-i42=eAQaXupi19LJ`WW4D=
zYGXF&FtLYF84<_EQeSGRJD=+#FE1W$@^o`Q%ARyraQ$Ql&pGiY(zTIMTL<t$gh&yL
z3>irq8)<-WmY(@8Rp*`kSzn_p^58KKx7R<_lHHik?2T3}aA9o$$UOzxMx5`BacT`0
zXlF$1clbMsP`AXg1wS7msL<lvkN@l$AT$VT$@kvZ=7EPhN}D;KHIl=5jv6N!=&2fT
zWFMJRE@=5IoMT?O>!n~wxn$MrD&Z(<yX>o`7v8C_KTx^aTXS9d-hAMq<kYSo`_U_W
zppw2}U+lE!TiR@A@^cF!=aFE^U_(s;FuQd=E7JTXUOuD@#u6Q0KMVQPKvDS-4c=_d
zkFSL?+@a%gz)j!G#4DAYBG)8f#Cz#`B$DOa2ju2}L~k9xt~cgs7B{?3<To0`j7N2E
zOk`;GVoM_>HfkwZOD251<C&Go++MhcxGw2Pzihlj8>Rwo?3J~Cz`J&b&iwm-RMg}^
z<nISyJAUW^Ci^IlkIy#}y}4MLU!kkFD)7ujGeZilKjtGf{&yD*v>_hEd8^<bP@@M3
zD$#8Jhp;yfhw}U5htDi#v5qB#>}x1wPmFy@mb6G^&mJn3Y%}&HLaB)Cp_QW5HkMEb
z5!%dH5|xa7Fy?-S`h32h=X!qE^PB7P$GB#WbKdXwc`fgA-?t$0L}Wuj5II3#hC0Y6
z2n4fX8-akBlfjXxBp(cRGTj*od&&if$A<zxL~_X23Xj1rd<rq{FkVMUFI2wb7?wM;
z=R@ck&^vhXeRxcR4Xvw^+(2%yp{tHTKOV;eev2RVXNUlg5QyZq$_oF<+?PHduffz%
z(!G~vFK~IHlMFtl(O6kJEmYTz`c3i}zR2Bhmls<rTwNn{3C6nmKQua}vu_6@fZQO}
z;K*Fx5g2T&n1xut+UR=A5U^8F7H{pl1A6(MM^}_HTAsaL`)wxdYuH>y=X=mf<ZfqF
zK)2W7M85NF?qa(XXfB2FBCi4ZdLg&v^t(}Sx+@R^oG@|r{pc34@%|<(K*ov|)*afH
z5;aR8@?2>PpxARg@;NC>M+J)*kE+CwxG&vdG7KudwfoJBYo066EdIu8rTe-wF0l}i
zqas;aDPe<A{)q{qyM;EEH<s7gie=K^o@^kl!i^Q^@CYE)-t3(r8T`uL8+jOFAOa$?
zE#JG91#QSu1@7`i5S|E}eraW62uIvMvk1a3<QIrlHP=+l(9+)#8zWZRlc=?)(~Y`g
zf;+4&fVd@JXL3o-M>t9lgr->SEWUO;z5$Oo#ut~Ac8vgyokOycu1eV5)qiwQ7;>Q?
zNaD#kqel;*$SXf8PdHyBM;!0)={2Bv6c0p1NK;{slIb-L$>EiSrtnJ+*U~+C4v9Vy
z-p0L3HB$N^L!xNl)d$Su`|B5Xea?QKOk(5bQ)T}xKN_t2Z4b-t<$>QhPZiQ{?}OaZ
z52w?mT|$AbYT)H(1Tn&Ji*eM#$@O8e7NLS6y9Z7*;2gqQV<{xVK$PolLHlywO&GMm
z!0_yvvZ!~PU27!4`m#C((ptz%v92mv4GCrBi(e`}tpAKLA9g*eTS=F$1Io8yN0L<~
zU1p=7_zVm!K+xQz{f#P!PUq*<|K(HfLio}m7<qJH)NyMbWiDcbLFPQBSIX;|d19%~
z5RkUS3PJE|W@U{A5OkD}&h(aMFhJeh9c>8)kjPG{zgn;3cMcKbVRhq|xO64ZT9C5X
zvD<?_H_s2Snc3GlPq|&%KNb8^BpPQYF4;6(IH)%amn@ZD^B1j(0vO3_yC92WyNCTE
zd@3No>0@&2TAKw#j)$#|Myq9DlZ&R`f0ly`3h}Tp|MAgB7iAzQPkxQv*q{$Mzfr-*
zyL%(N_Pxl1+;~>P-SxIn5yLqgI}|9er)>%E%=bBSiHnvjJ*H6*tZxpGqnl^6#+%vk
zH`rs;Z&*K%NZr=K610dDN8i6496W<(VX6ErLN8JNBDSoFCWj55l%)hWH+RT81A!E&
z!fR(O^jSObeCr<?sov}x<H|60uru^-YT1l4=eJ_1m8SCxY|p+<>dQnKpO1cF`hsh3
zc72`xQFGf}K`lX4Kl{)#{80iC5;2KQ`V=P0@WO!8PH{&pwS{t@Wp{D}&Wpq}@63$`
zLbrY`XiIKjbN#;?N=1n=ZdewJ?HcsYi^2S99>Ea)eY+6(X4Fh)_&4Bv+ZBnu-3z$p
zu&-C!6=odLZy+>knz(*KHCMlQ9G*&8ufsoNAif-O<#ZJ2!Gk1e>twsk_Z>ddqRk#P
zMjUVDx_<32d_G*;#voenJ{s~v<_=-r?O4{LEL)IB_^nH@`=Sr|$Hz~?o72=@5oShj
zapZrwg(N_Yv6Ay=vW<?PgS_Mtg1Zv(XQSEr)p&1@^co0V?byfL^-&P;i4E`9)8o-N
zd+(PNW5n5k0+L#I%kKKlEFO&o5cCMi#ZZKxjjdHhrA^(5mrnGe0|^jNbur1xAktNO
zcS?vI_Cl~QThMX<OihDzdFRDXB^Tl5xz*6`gGPNkr+oml@vwiNa=3Nu`9$*DW7gUM
z$HHIeZBOnCF|n_Q2+>Mhvl45rM|(Cbe@QmWizl)___i%q$?Zn=Vm!}fJC)FJ>nEQK
z5{=uYo2IXvs<jt--qg8pSYtNO5XEumv%#9PX2FW=%jLMp#*dAV(oQ+%<}k83xV(q&
zAz;JY`(fudMe!T^yqtk~czIC!NwF4MEBv=hD;0QkSiW^`bH847T7~cKyQ;J=Kv6J7
z88`N6`~q>XA7+)u;I1VC7?}O}F~5E2Gl7t}nkSFz?-y9$dHIs>^uZHHU+}4bv(j7_
za!;P<BtYa4;YZwTp1Zx=5&;_pUZTK#v(Ey0Ucg{d1L88%_9dC1><N?e;mdOe1zj(J
zmre^&gyfgs!oc9Tq{gQWVW_h$6jbeQf2Q_@$7F8pCy@<K5BE@RlC~9lL`28XYfqjg
zXpxvR+PwJ!)=dzj>yhAXMn@Z~gyWvH&vZeGwM$7nSD1K#VKYv?sWnz$Wt0F!eK?$s
z?U#p}7n~q90Q9%C_aFB_D;d%%mnzI<wTcIzDTGMqjqR-gML&2)8~kKZJBDt@;?BTh
zJ@8f{-)|ZuEyy6IZR1)2%QcqTb>>PP8fW3IN(LpeyUwjKAb^fbc!N7tS&t;F7~?+_
zTx9=9CQ}Qvpjl|s_01FF&@6FmR1ng2zp5il24Vno)0m8OT_jC$zh0}+qaF3JIC4!X
zcd{kd`h)A8-PHzb{e+aRDe7JDJ8l-0vl{NI1@F3d>ZPj`IanQ8jUu0G7C)o4F-o-W
zHvT-HjY^L8>a8HaE}-2oS74_4FLTDvt<wA67aWi<28bg59jfDs6{!%q&~?G?inX(8
z5i|mC+gk74sip+L8Djdu=py;9Ed=pGyEon3)~nhGgL)G0_{*%n_euWa9X&Iz)4If}
zTP3NTO)x)M>w9NKqJk0J5-fKX&o|Lez|yUg+Mx;~ii%$jf5s0i_t&Fk+^bc1McVlf
zc5opidF4TNh!NYp)3sBg0j#fYa|%=3!A22ZL-F}^i>h0vt`7}Clmy4LE1dHwC$klH
z^!e|3X{DaNX#40}LJ{G@9aC;-y*E%>HuJ>DOz+q0{2MB11skF6aEFA0Zye|=Y0EUB
zM>=^3)BrFoICyMAFN&bm4<)`Cb>-)L8q)SIkkC8H8Yy3ZEu_GrU>A48BNy}b5=P*+
z@K&u~Tb`XaU~qNi%NhOL_B7+=Rh`5QMtkG}Vd*c7(G!UKf40<*b4|<%^x$07)<UB$
zGKfV3&Hd>XuQw>z8DW8>sR{hH7?%ga-#^^j11;tIuJgs6_a2@QlzcX5>Q=DuIr-?>
zTfzm#8)v8*u-Oe7&%WCRjS}x1n6Bzz!L&7R5<82A{7NRPQ|<fN-<gy%SqCoX+pdtn
zEb?U0VVg%kA-Vz9vGbz9q15+|f|Z>4a#|@4)6EI&VDDxzOEcDxB`B$4iL9(g`fJFE
zIb8wM(}Y<@5N8%0hdWo3yLrJe#sc<zaj)#VeV;=MnCK1bWm=?7{0`dNWYX4RaUBpw
z3E~%2wHS(2!zK~Tq1GRdg(FZE;kV7Me?Jb<n_#>XbCiyA+%Y&J34{cn&ZB(lmN6#K
z1zlmiHo}VbyLFEULTen!c86XhTy6O<O9#hY`I>pieu823TVedRMG47NA7T><$<A&E
z%bZs=|FC9EyYVh_##?@UCdTC`p<y=|$djtStRaT@aS2PVA*|9nUg`)O9zSxML*il*
zyBNaxOSGiJ7uYIluZBQ2SBs-x>9U28R7rxLsYy<ov2d;Cxh}1E<Fmdqb(4v8T~L0x
z0LYp6u76HB3O${xj@=+h?fX^V3@%Ja%efNK6b}aCRO5ypflU6oHr<VH*4Nsc=9(PI
zhGh88HKPkZuhh2^cTa!*>-Xu|-yY+~Ihss-f9#{4dsLka{e%jgCHgzXt7ajTR8K}C
z6&*6$=L=mszKB?OL&cprV~^0&)_7Y8t*?nIKqqb*OYUgR^0Mvc8o@FQmgBzPO5lj1
zy}p2^88pkKCyyQ2ytIj3WZsn>z{SPGn{+5hGcg_YGq>sspY#R-!<@pei&TNZP;tEl
zO1qs00=auEy*pOW`?c6LltBfPswFqgP8|LeX4C8h0>XHN79=n_%MBsLpvn`O>jv<;
z&8GxzIu_=qKr^J$rOH*n())jRCRA8O3)7jrj+T>KHTsnnjj_g|<C;{&QEuEM3~qRg
zC&55(TMUhQhi5o^Z6S7OPhomHne6j6ZG*;UJ9@#aOFA^uaEw*O@d7yLQ6}C{LP36f
zWLewEx_9p9%fSN3d7JW8&6DH}y7=O(dnLDdBWd8~8e;5&7!h$I#Zg1mPz?IiRfbPV
zC7C=p+;S;Iz*3u)3q=`dc11eoU3oY;z|MZz?k!pDXo;bU9-3s1AnNkCYIiCP9W59s
zeWvGQ^*bLC$f~+OnPvZ{jQ5gW?X!8Pt2Z=mjK)tp89v%3_`E)KK>*;hhjGS=gO!yh
z0+<mgVtSbp4q^ctYx9_e4{)rxP*_^t>GU1?K81l@m^i@EZ`m#og<fQs0FIo@qUXjX
zx?wrnC7wGdY6FY_I*EsE<4CiGXn$m%Hpe(W;AfG4adY~?mrSvI>q_Fn2r6}YxKSwS
zX(J<g&(tW@2L8i<!s;&d_3LfB+Y*U@zbRgF+hA+I?aC5?h$h<k-K{iR5G0fq-Z_Q%
zj%#NSV&HV{%@$Gt1l8?M83l6K7<_N0dm*c8nYn1f)3sNw6`1LiAc@4ww~n(3*}M7a
zo1ANKY53CHPWxih#CmrLu(~<=I0u6t>r@bBl2Fpn8I!^wE1j97+tgA0*iGKD+KqOR
z4dYlN7W0)T7GXEcp1rsoxyg5ur>;(<CI_wCg#BKDp!AxQeDpel&c<@P|H#Jo^-!1D
zNqHW86%Ho-4s37#yx<ie7{Dr6eOmVUFIQOf584by?9`coD9SeTktS<s{X>U>cl3MD
z-1WA$h1q<!@@dXpW757hT*HMb8GH}lv+V!zN^n<ts0k{=enukY-lO4~oVXjeEB6N-
z_icpggfrLSB#{m|61>yv=b@*|UpKIOf7eGEZ{L6uunabh{mM_gA!r1dX@5TVrh0uN
zi6vFpyLIv5k9o`lt*ZSKSyYUKqM|Qy+&)#n@ZrQCw14;`pQm8Tqx0$IQ8g#GAX%;k
zbH<WN=8bD&OA%DSJ-E*R#s_WqzYEt4SPJF)4!b@y*Yg>LS`bM}9;=1&k21?WrqD-d
zdkbFSEFaK^$>$uay`H(T5<{O?4HAGL(o6N9Oi0{_`{vDtM~p=&b+ua1A(~v2s}d+g
z0at7Wc6-WX<dR1QlZyfRjkV8B)BBAS7)4gpn`@<RKcm5bR1hk9_>3JB#w9mx5p!#{
zC2?3wJ6_?9d=9=)`}$x_`}LB##bgDgD_l75si`N*?n_P8LpRdJWm)xhm7Y1*#I7Qp
z4QN{ZUuMOIDyi`IGa|iLUKNH;QV03(7|{9Io@Jp>!Yt7qNu)!3L(0+Rg(<w%ul62T
zpRKs=8fL53_lCT&8{u4gic!Ap@a~nC1mtk@5ihzG8ctJta^CFSBOvy6xmU9CS>cQq
ztM$0(*-vxMew|;a6w28S&$s7$O5+u4@A0gXlAL-hwIk2FxMakAXFxFihFCHG$QO21
zu=o341`1w>R$0XjG%>~Gm37wrW+FN!M-LIfE&zvRzqNA}#Uku?2h6Oou0A^XqwU_q
zm3r3dueU?C2?PhiYjPC}pF$k+3el5H_+sC*JSxLjss=@(kolf<)9Y-$7ghPcVjsdp
zVthL+>aWjX)H8iRBLq>O$B03U#?4=K^Ms-qJbVE6<8z<vj9)sU#t;=|yb*k$OUKdX
zvUP=q-i4bvK(2$&S$97J&cO#i9Dt>NYM?H>?rU^k7H^Iz1l<`qrUw=>1`GWK?Hq6F
zj5ZmItpTTP*R8lY!W$ih9V>7$+TzO7aP6~&UW0cM?|-b~xWajOfrC(KIqQCkHC@I*
z<Bry)HT+8n7jOPAX3^V9$A<g$;AYe9jbD{G#_sCI*|<IUb~x{>^rLqO>3wEpkA?1k
zE`2?nUNJU1t<P%OrH{j07e~FZ?jU!8y|4$KmNtyQj8i3jf~%{cnB}RJXb1X-%nFO`
z7erpAKU3<KZrk|!4(~q)lQjS8Lx8rw(KF-iYvbj+9F5;|@6Pk3fIT*p?vt}IYoDBp
zp-ZkcNX`$f%422m(bX#O1Bm9uWWvm^wuEC+a%9LW(c7!1cV+3)0f>At-h={woZOS(
zrs!6SCu&~j4q1Uhz;-n?)XYG1+*ff`h3rYi>w^$lYwnC9O_l<>HxJw;_ZImN8^4xN
zwwe~J1vxoF!Xdk)o+oO~UWS@a!0osLdXF5d!)(CZc9vf4S$VhS3bQDCXBT+UDIg+3
z&wxY$b^r;-tHN9XIfa?e&GS$*XuNG31-ve7<!LCn$<F#aTTmZC1VkpX!vN1-Wi3Wy
z44TNnKfZczXFjzgOk79{Di$(|(R8Ji0k$XO!XfX%>O*uKPYwM@KN@{j-9t!e{$``a
z*gZpP^X#iSEqGZ{j1Tm%JH0uuTf6mJ$tzd5QN_-nGh8>LYs;i>-TkpbI$`k2VX$<E
z0p$1R88D5F6iuV`+aLM3z90KFht=A3?xtLFN#9PcRWL!*#s5&EWQ8}KR8<tkO`Pj`
zP=4E`(F}K0>3U?tWxMOsyY{qVC%nIBw>;p;rr#IPvD)zG-HE;<!J@xn`3;?6C(oCJ
zEa78ox!R?hbGjDl4Ofn<%QGRgv-suE14kmw?-lIrrYST?+4s!02riZ_1@u0VJ1zbA
z$>3T~9c~Boi(TAxq5V5Gj|8sysuyTpThtZnr69&RvZS!;vHP6om{5gy#WaAao-C_O
z16XB>3cwcv>g~e45xFu#Ki|-`1V;5;QA&qA_N^}+1A>_XX)7B9+O;QCb%__c`j;!s
zC)ssbtpK*H|A6{?e+r;oZ}nrlQ02rb$Hkb^^Rl+WV|;UMI?0uEe?0r8%VwPgl@Ogb
zS-J!7`tp;QzCqlsyAAn<x7TVmpdje6!J=e@dD23Z7%hUtOeqSSGrDFFgXnQKUZu-v
zjX>dT5W^NCmk_>uC8^v4NSTSf*+kQ;y0GhIw~pbq^Gu?##rKal#mQ8;V6NW0I8~!m
zT@+W!;vD#;meA6}Yj;_-5Yc+?hOAEfc?K0`=MYmfYIk@kuSHwz{I2mw<k^9OS@&N4
zwEYLOsCq5C9A>{^HN~?_GVD3`AHmPDl7PYB#&%Y*#vb2^PfOA7oYHQ6h_l({1@t_h
zT(o#M`@8Uqd2JewoQ=ykWLcTsXs~<$eAcWX%y(j~)sKPu&kv*w5!-LP{fM(IZ2ob;
zMCwN!EIrbnjy_|Rn)#d&bxrEp-NyAv52pL*Hpu<c+Sm{zKrP=DwR-yMi3Zd{idOVj
zI`W%uWl$b`Y-!HCJ+&|V(Avltb<Z)u$$5_!x?}mhmilFwe94uE6Uy^Tc0W<F^`839
z*IM?VTPPF3s@veNbf0$GJYNz_&B-&+ckAW;7}5!U^jjdQtWoC&)xys7blK=~m|(WM
z>CuFI6puH%rF$ggLyzBKf8u>;;TlrKCc2`T20QXr$Z<$3wtGAwd~Z#;HowlncPr1l
zTB7cptsUutWBL@GBI#lfQPN$0#22GWOdNv6IVM$F&~(yZ&AN^-USku*^Sr$Uw=&Gq
zHwv5XT1+Hpix|#^A)d?-yS<Dy5(=kv^93>C469ql&)r^su`OfmRT#=+`&95_y0Wq9
zpZhu~csuId?mjNj1yL=7ToQqc>l(8tv^(lvKNP+0ZY&HzLrmOQ3>qIDm2?HPY;zvt
ze4fXdS{_M$d1wFwDnK5cy8l2WH2R&$Wk@x)e1vzBtZ3*^4>BpB8?X{v6!qs9K42~_
z9`+s~Q+$N>$)_DyyV|}{W_Hv|O^kXK)!(Uheio*PFB)v~CanD$Mt3_FPt1PM<_tt!
zjt&1=HR1a6k-eoc^olz!^|RPX3Y)aTyAu;02ETSx>9b|VjPUyx`#|d_N_8FS<zkA_
zXHVL$_}APN+`Zd%)#dlKW_uLxkvcXBo8-#l43<IVZHK>BhYfP~@D?Of=je1>5&$gg
zOux9vgF!oAci8}^Yio0JkA`o}cU5hpqh?7KsP?(WaqRx?T4HZuj*IsuFY-x-k~bN1
z&J8XIbduU_R5j$33ZO;25Wj<1W=o$w1Whbhd!*RMz+-w|N;q9xmRdiiD%Q;aP6b_u
z(GfJD<AljOx=MLpq;Sxw(1@?t4RqZ3I7^yy7`jovzDly|Gr1EttSHIJX=`)>&&>i8
z^d@p8_UWfQr~{*M<cnuSyWYO(^C7?FOy7=CSV-t?GIXqHkm(VBa0%<_oG|Ytx$!oZ
z3_Uw&_~!m~uljicj}oRCPu!z&+ClRog%^3^id0V>l~8O{y7HaOGPbni!=y_+wSar)
z{KL@bGt=ghJ3l;IB8}hf=S~V;Cec}<=$DG6sB@SyATm;A8F$>sBK-1MeNKRb4N!ss
z9tF2^0d@l3NIi=Dm$kA7?=!HcpMiMYK|0!|wew!dIs-qMDB*Y|_NT)@pI1WzXG;0i
zX4!OV%@MiFT=gWRIQG+g$>SBra7J22W1~@Et$zMmSk1xHE1%JsFH^_v?b8}p<n4?C
z%4P=gR|Gyh{iRDR)$zSaAw(+E0P3gs&4*`d2aTsSSmv<!jpmOgrXSlh90`ojT*0>H
zAWW1oYxz{EOEmpc;@w;J@DWV<*-M-<D^$=*5*wu8Gy|2oPbFd=NkB93p|x`+wJ+4t
z9<4B-50M%{JtVt~L#r0iqKSo~wPxyt=iGk8ymlV?os-9Fy7#eY(qu5w^=M{98wFUg
z=A6lgUE$$B#C6Ib-0ya|zi+md`#U=q!O{Xo#=s~99DBqltZz^>88Tk9!1sePdck{5
zZd7fi;pcCt+B{h_Bvx#tyBKY9wkPK~<lq_*XHq%DdqM%40mwHWQ3_o(myapi@_9*q
zba=CjYSvD}igI&xzEcl+hH(F4vv2&xC#m#M4*rrevm%q3dEu>_b-I8~Tsnax!Kuh`
zvwDeVHl!pU8p~6B?-Q$I1PW`)q?7us<~;D=2YUkl%E3^6Tt)zoc0ap{tL#4)yk;pT
z!55CdM`UooVg`P(^2sv_v3D%|_R8p>A|90QRI+&%aXB)2OnyXh(1qRxB!~7R#F;L9
z#;5FJWU*%Sfkf@EI}B!5(<~1jbt+X9mQ7?py%Wo9y*jZ)5@&u3ycXEkL?e%Av1CS6
zzvu^|`KaW>H^rdXx2(-cx%o?ab>h)Me%?Cuqa~$PVyOsX;D)$ZvOarnG=eg90rdv3
zR2JPl)dDf*3p+TE?zkjxlz&jCV|bo(7h`pAjO2%Wi28KkVY+P0abDc>7rCyIL}GjH
z=u<c>75`q1z4&e{Cim%GbRD?i5$AqySFc8DbMf5@!&*ai>(o6LHeMhFH9J~j6dGbL
zJQHX5HA%p0T~2Y;{*F3WpKp@3J{u9RII-iXw$sj&X&b^)Cap%sr(Hvn<6Zb@R5)LG
z4ZXackGsEtk&X!5q5KnmOn9nHc2Nwv66PQfRJ2-StG$yrHWfD+>3!LQp9WWZ+TF<L
z;EXJ~r{oa%VBp(eA3410`NbdRk;W}wG5U9DBFN<HA8t;_qZK~oMCk@T=us!Jf3}(!
zksD1;SR=u9^D^RQ*LSxMIqEB1Q)#nT#<Fi%Wv!il1PxxbOs_OFSbDE)n=JF01axX_
zZyVBHP+#hL#~t_*s;2pV&x$r`w@i>_shYV-YDDB2BCeb#n=R_+2WZW;6|kI+=H_aM
zZCXElV(1M8cwBv)uT|AGU$j@CUbB1sW^+I&|L<%)(M%Q4Cv$7SO4qqFcHjpTBM8-+
zoR+_;i5yyv@b9KqZnLU3*x2CotkO86iam|@)`%T%y(pFI0DI-ES1RGqI4y|07xU}O
zz#!E~<F?y9KJrp%q$`5uDPQdUCdPr&#_M$%usiNTyy$xXv#%y@hl}}dTa$v>#?Eo%
z>nYo~G<t)cejwntdHhy$o~>@EEap5HZNE9)tVBxSWkloL#tjI_>fsu<nU?xlxU-Yz
zzUK>4lWAT6V8u6EOKn@{=vSy@x=Ui6IUPq}*rHIh>QC=ssUm=ryEo*0HBNDN(vuC6
zkVK18jHN_>whN<*a(EZq{Z7Wm*(>VCItwg(Z&h>?r+}WimS2-o>pT{kNg^R;D7d8F
zYhRzm5ue_@d(-p%3SBHyFs0+%&eZF2E!oqHg%Pq*f*-Bx1y1jVD2u|q9QWR4w7JC+
zqNpesyXOV*Q!J~^t^8<8AYa58`SqM)?vSc;gpCr`P#`IcJ9G(|tX^)v?J&h!$L!0o
z<4X3bi+F%L3=_Qd;MFNySr@=&ASZ&0ZryJTdDK*ithj()GvS%{ap&h_O&e&>Kyl<V
zD&a}G(~C9{Q4ig|J<)VdY+r}$WzF_j=Io9V2W&(Yo*XV<$*C4}#)T0-7E6&Ya=MeF
zUfVlE7t-=J+OL^a2b}S@;SWlZ^-4ZW@d#sv&b_dDIdLag2o1Msn#8d^VI>m<kIt*T
z!qs<~1Bt9NrXs-isYZ10p(nXRhuc>1_7&1UXD6(lKM*7$=H*YZY|EB#`a1g3ly)yl
zb)OebkX0I;7a76kv~n32#hcM{QS8u_ev4eX0!^G>44syl0*GywEybc%8-uE?__zTY
zbq|*&|4<_#T2js#aHXpA%7pJ5fuPQ2d(45!r*{`sVA;Ty)mHMmqrFS|?gVXhxo;o0
zD+EDb5cuS0DhgWUZpT(GwdnF9)(AN&?0j-4=fo}523x~96?S#&a~%^kRW1-i5%eV!
zH<F{J2^(z(l6zk%`WuV^Fbpv42pkHiNFh@n=te6naGVjE(M2H5l6?Tr9`5Zn=fyjm
z`o>(Fk2I2}GW<A{o5s_>hLv;EhM>^)w4)EaG}u|;4Jf@=fx=`S>nwbj9zyW8$?TEh
zFuIT{Lgi)iz?A{QT6711Q-HXLJ3A350XXcNI1t;sjVDBW$|(bA#-49J`+@Ca?sg)}
zXS}<6eEv*kgVK$f7ac&`+_2xO3;&=&vU3HNdo7mh(Uaxg`?WDDiuRsnZ!KH7p&2Qd
zVqO#5i(sX6IuUMIc=d9LvuTva@|vrwRSVVvs<8svkHkDYjm6052`gR+9+T7J=UDW!
z=(52S`PZ3z<?`{q3Nk$qn#93Xoe1Oh(#iN%&_olC7Zb74pPY(2t|UT++W4rzu*&#&
z!2}O$J2%ow9~+bXl_4>^A6p&*XG?9?7TSJ1;3vOJ|KY5?K38971AUNs!7f0Fy5MTh
zm<5F#2Y0ye;6sa;ipyhf@tKSoc@cpH;^?chtQN0M>IN~2>PIhMysI<1cYEOYkIYZU
zVAIz+eAX0$ps4&(R}7|wxAy1X2x1INF7WaBXux&@E|MJQoyn{-lqcOQ_>80uXPAoI
zb0-rY*wz#3?~2p}uCg-Bjv5KPO!jpBXrxrqp$Doz{6cbQ=036xilPC1)p0+UW49sb
zMqC;4b{yeTD)$C;d9kyFh;MzPWK1F*SC!I^M3b!_7OYIAs_x)sFJ1GPErVF2Ff55M
zdsh%3^+LES%Iq~n7a>=NJ4zVhV6K{qz_oafq;+;^EkGRM(~<aa3(`iRerKI%J*4nj
zTS%Ll=E5GfASX7v=k-b7Y;&u;9ybxC)4qdj#@RtlT~DpG%bSDMu|D&e+>whsPapyy
zLA@zCm*e%yc52I>RIY?ZE{W)NvXAK>S_*bF($RV-Pi|&oaP^vDw>wIj^-YRQ$ngM-
zWLBJn)xnH71xttyE@gAyV>?k)>>cTRYev`cRx%qO*ez}oeZ;;s-~I;`Zew@*{=^*%
zY|3YZ377h<t|@Z;3VY~>uxg<g1ZZ5}4}1LXC;JO)D2N*TGiwUVvECvo$Tp#Vk%M@k
zrc(z(d#J>R82jqSLdPLgIZIxg)bv5e%HM*YaxU$hG(67u3rZZqV{d#;q^JQb4)xl#
zT#;uYA?cbM(R@#w0h?~{^Ywbtc=o+8yNPo2UdU$<%iR>5Kzag^@vvdJyRXwF4=1On
zH70x$7`ywTbvcXjbGGs0=SkKG1)4Pka{vfZWdPlM_BceL3nMjNG7Q;_vCC+ZDAs3?
zU;5#bubEJ6E;QrgKtd;zc2N`RIy3{;CW(dek~(Wh$2A=pLwy==+zyeqqQAZ3oD|fj
z6S6Gby8u7;V-=437IOv@x?fNUdo?tc9#*GZaw7)ru<A=zs=o92H>HF9j&VbMrjR$4
z-1h(!Ye%GJDiI<C5!YI$PP#v<Vre<I@@QMCt#l)U{ZF^BsY5-mIVM*F1OYT=O4s*T
z(zcte$D(K_PD{G9$<I{{<x&S)itisOJ^P`NBlAfwf!xs1^d#<>c}6I#{Qehym9H!J
z#c#K1(f)@|z2ZQC>FmC#^Tzgs-jTTAa)F}irt4;R$7%(F`lNvrc5lm}0zRmcnF#=h
zmn^s&y_TsZM7Sr&yCTB<Hq#_IKN=50HF?8ApTCqhBy1FBi0#uj`zy}|dSRmSx~=?W
zSMPv9U9yp<Y^HF4IKb?PRT1etG!L_lV<0PbW4oRr`)o}3xJbn;r+H1j53PN+H3_JD
zzOs%12v<04Is=(;kT*QlDUxF{0-mztmv8_6uc)9Y8)<+;@?FJ<U$vBu!AM^<fTBqN
zuMUt1fckRlm*svZVzN7tWdhr~^R4!^xBHwCc#7q)UNh{1;c+S}d$btqy9B7YBM&6l
zzvc^u$qta%6<4>P#5hliUtnoE_%`U|QQ>cN4nsK?g5*%W>j2m2OPd9^Im;OpBFSD{
zZ~Q04X{gRImU=sN<;;@BjMC+>Orp3Hd)&`?t=CuieXrAiw3nn>-Vei!r-eX7!~S+D
z_nnHWV^zi@Ca}lCU}sg(!-sqSKUEt~x(bma)K#V*evn#aTM89Xol0eLY-GUg><BnY
z*3wJNmsuQZivCbk1H`z%=~@nr?nwl}d*TN^nU<D@S3VO%;9J6-<Z>lTE&VC20LEg+
zol1uG8s&pauq%eZ?*38OvkKPMAEs~f0FuMc6=0y*Xl=v(uA<+Q6{gL-0El#M9;`7n
zQb{l^Ho}5QB<h%44|s(sec*&;L|1~jz3>++p*x!o7Gb9a1B)(`Q`=s};06ncKoh_b
ze8ktjDyRY~61i*tMcF?6f-eA<WyE{wp^xcY({dYt6~X|8wd{=GPo+IctM*DG{J1Lz
z+G>g+%<ku$qQr%%l32;x6bbJYyx``@jja-Q&4U-BIA#JA05Y}J%>H<V1c#rV3@&cO
z->JYD2x`06<a}X}FqjiJ%m8)^BsnE6T}xld8GBUIC3VMS5B^x4VN-_9yus{m&Y;mX
z=|ekOh;TD^Dfx%J=%Oo&teZ=LsR7W-B=kHYi0JS<&;26CZctns2m>6Kb<Uw|pcnji
zzSOF?vw<3S1ZZOs%`_k(GS2rcKkTi@)t`4XUsI%LnRvt-{PTFhW|E%t+T^?x_c0bX
zLyUI<;Ds4_&7o0-+Ro;ybWTpNOGVSJTgB=?MOZzwM<R2;Y#wWTh}gj_dLXWf(W#-C
zQ*)`-s#c9F`z()>kSD~5>btJ+v8O!lN>E~Obp#r7w-YMv?EA%p20Z{r7UKX{T8jIN
zo^Sl+FCC)9d{6&3H9!ehlj6m4xuoon(SDi=#DSF2c-0yt(eQ@t&~L(4?0%yQ2xQvo
zE8kL;5rFYiP<YVxST6ynvxe?7EYauccq6(3kpPIRY!klRsDC^!ONq?jYV~+f^-k)W
z?UBSLH_XIHO)(>7H_c#c^ftMS&y-1qn7`2#fYB6uI<%g@JuO0QO|1-YvaomUih1C@
z8kQJN(t^o#4h-*q*(F-m*}rDGo5NH_BYO~eTtsw7><SqQ4-f&kUL%L&5Bx5109U>_
zFJ4u{5RRT5{)B0;^<W%pLm<6`N~IY{mHHPz2ND<QveIZSx~pLM`uQRy4ZesRmC2cn
z25A!@B7{8fIQozz!*7>#9jefB{<P-4+7T{10I~WaTaaiPSQw{K!PR1jJrMX<xFe|c
z<pxn);)(xD&EzpYS~gg~%lLY!7jj|sU)FWC9kq9|Gt!wRB1wXygO1+Z^X2!Oo4Mb-
z7|e1RMaH%yjuyt1J$LMx(6S%vl68-n63EwVgZiU5=Ko)%jM+-L3R0Z9wM?^l;or=Z
z;BYUMzet?lI}0^ZVdB-Hv9aQLyQS6`oI$<&a4MyMN0NIx(hKZkKS#9FhvSvzG^qP7
zkL)(2hQ*pih-F^Y=z(6eoVobD^W4?=T&Vd*gfw5=$hbg5!pfyMDllPh=6Rj%WAWVa
zht;Q`u|c{85f~X-9Qdu8yr>Q<bm&Mj@#M~q!L<PpokRrU7uZRzls~&cJBI{ov6Eia
zn%|c@!evNxLbTBf9zRi?WwIn!ngO;7X|1!r@w@gOU7D)`ni`<$U%8@M;jm<w1mKuL
zGjTx4X35{pYq;B6RR*m!Lx1)HNP9{?NqXOm>#@!NY)ECvoM`u{>Fc<w46c}7QLTxM
zw9Iq@UF=U%EGM)+P`4Q2cqB&xYxQg+W0`s`q*ptV0w@_feIKwD2~-=Nk)gcbjKlTK
zI1m90MM%}+XG9F?$RA@0u2TigTWh_$sD%?th~c^Q)jhW(ph~Bap&8Gtwyi1a?Gd7#
zT4_@GwhPJ|ykpyD0$@lxDI5q6gxlV{TXl0Go2RT3vNDz0gbiXaOaETxOdwYhOieYj
z_lO_XSSbC^HYm^NMRB0Ecuy6ev7owjh%~r6^yS}eHO<^s{e*Y}Y%+{S5JV|3zWN;J
zFcp)v)@l5hJ0~fQK`O)%k7)or+fQi#s{%MdRVG{kabac>IZ#<AMJ<o5w*F1RJTnO|
z{sLgwwSs>D(8lwNUI@(w4G?%Bt_BnUSk378A$0~>^Z>vRDw}sM;`i+t6)%-t5xl*q
zm6LlY2S|%X@&$W3q)kY8FOsXHh7U4DpB#Qh#ppB>uSP54imROl&N_llVu`tE=Kaxh
zXHSof$<X@`d9$aDxBVIF>6)+=SGxGew^*XH_UCX2tu-Zfg^$P*%injJR1|WkBgvA0
zLNXUO=1&P1sJ#g_9u@~V|I7?80yu~mblIP}<!wk<&}(M8V3Zryy-QvC_=EE@r!`0R
zMoHs=#MWPHT@wPm@&I70X!9I-h1sa_wCYA`FfiKkfkguC=+DOD%pn1>sY9O)A4<Nq
ztZ$|RQO~(8mXB&tvd`WmybJa^PbD1@e4h=pg#^r5Sxg-#jfMzlk}S;oa%=DLk6o6A
z-Rq|VmJ2~<cG6qL^GJz@Ca=$W#}(spyZs%eToI_~^@3qITtKFlNJXTHgql?*;_BW&
zglO@kjwp~V{Q0Sr#%7fEV5aTa+4abYWw|7nlqz@DktsxPdl(Bd!-W91U1ux90z|GH
z_AA9&I4hx6G$%ljkcfU2*m&YGw><N=$@bSR3*zIXuAO-(-`LJ0LjFu^z5?`Y5M&Xl
z&KMcnM?S3o0oh4Sg_LmvKBs&m0F!vhZoY$2oV8LxWLhmaG9xCS-XQhhf0+u6CbFe+
zWbLu$x#lNY8EPScsUOr3y+KriNP27Xl#X&?l2PUCRtzGM68BArK%Ghaa^mxsIe|`I
zOV(0eSc>S?pVA^^N;l2=5a4C{Rg*xlPvj!e?msa5CmpZFRh_J1<#ZT~?dn(3f1|db
zcX%)-E~FyiKue#(oC+|uw>;pbkvyTo1gNfmIGPDi$zZF3)l4lj2tZW({Eh9c5fwK=
zHw})^`^)q*5>s6IDcWiZBXE8~2-9qZ9z+mfRWPuSOvF}{mQ@RpE_=kbRKd-z=t&)I
z5v_aEzTP!=)X9tceew1}r4eyThg>M;>qZk%XR|oNlZ_8Ibu+}qD8XBL2f#C2(J1BO
z&(TIxcQdyMtgLQNN-chFXCyR$!UG`ygJn1Y*uo~mk711+Q&s*)%f(*L=jd`kyRSXY
zk9LNwt6+t(XWRKQw;ekrvN>3CTSWwKPY}|f4i)rf0R5PS5YHS^m^oyUVYlFhc-F|D
zKX46aytSakj{og!yw{;?+F-6_i=R!Ni2bit{?%AAM^_@q+{-~x0Q>Kh!PXitA&V;T
zo`2w`ROIzpPjIHF<@<^Kc@srm#C`@K#=i-qM0uyY>Q}jP9Y>m6GaheF-3NMWwe8e)
zP9m6Lh9yj>id<Y{b@+4_fKY(MnusR?1O-Nv*`w7=4piNLh{&m~9WkAJjwvL1{}&!&
z*F9@GJkHYq1hCC~iq2pCcMDjPq0w<7_tgy|47gRFKaH46Jn+t$+jP4p#zLpYww#(1
z`zHu*+|>S6Ydim^){J}qKw2GAi7|!PS}-k6L;ltvgN&shW4gyU*<*t1;`|s?p=h}`
zjgMzWsA2zMX;|aGn(5tl`ep<k7zJ5uaI2JGR>?_WD+~<%%yh7S^O50-%rERKKu?6E
zor8X>d^x$gaDo{+XeIM+KB{AwI-%azl!0?uB!8Y@!t4K1z_I6#Zb+NZ`uGJR{t*Ix
zw^yK%5g^SUgbViMjh~P@O4V!Pkbt<7Y0)inyr$}-dn}(ybSJ(yxU3apm}0cNZ&EZ*
zzLze{?(}n`%ZYCTA7$<7F2W`XUm4pS!qmD{fZ<6pqyme7gyfG~)}q67IrW!&8rGwh
zhe3w4Tq+-HOjTDxAVXO;6h)C<4a;RC=tRq_*sA-MWwiMHvsgU#FO>;>hsdc~0#RE$
z+ejDd_@j!7k8%BPxzs2jjFtcSR9lHB#L4B|pN>=iw;xLI16ch78|i^7VbDqpW9x%S
zBgT>M1sq;NfT_cdzYvWKVv5u{)wP3s1XK(EE9h)~y#7}lKyu?#@vtTpHa%zA80UBH
zR#ab7-<#+Q*Nd$anfyAPRwD3!&<|zkagNvI0*!Z8{6P?!ISOY}HW87)RE9wl{#tb+
zWyu7tmS)pq(9q1UkGY(lc$x<_`wEwxPfxUZyyQ9=I+HLq+jHZ)44W1d-H2t8(0b7Z
z6}=>HmC9?ajE|mpfZL05_xb#pF2~eAXxA?MU-6`oJHm+v8R|mzA(v#lzw<Wva0$;x
zwRf~PGXChmgO@l)1igZUB6;H_nIJd3hp9a>*z^uWaJa8r&WI5GTVLV-tuJb)J`bx=
z(3v#I_!4h8A!F2n$(XTLyV9i}(8ofRVdGIIgWE3m5H|i)SnIrS9hPRHfUR#+Zb<0g
z)SAOv6L!_9GZLfHvbh%scMSNY{-~w<i(1-hVc9V8E%?X_lKR5nB5uwolFM)9a&H9S
zQR6;l;_HU-F0(jLMf<#IUpAGXhOfi4;oReGDZz4}KJ+rQxl6<V3~q?g$Et|#Q`<FP
zXNiMoI(O-A%XP?2IWQG|w9dIOI~Z91&x!q&1BAGkjNC8o7kfv7J$IICB|RJ2ET9h4
zQ`~prB=U2_|G;A`E`pyp*C_WZA~hVMtZ{5|O2WQN*BB76+)UEz^4?EJ|4~PFZj;ph
z>E?9JQl{+TU@M77NIp0x;on#XcjXVQJHS$(*Ls~Z==of#cVU1XwbBXB>QzQ)Byn#^
zL&&PYiW6Y}bzX+_w%4jBys02-3F6NHXcE9@7-1XR>3Re~-N2o{+C(IM)vMelF?4mB
zHQx3APw%Ml-ThaFG5zr3m#A)<EjYJ{l;3$09)tgh5JRx_@CgZ6$^=R1uXXstDxq7f
z0{v|lCVBSu)7n`>&;_O<+xcc;YzDQYe@*r#-fxNz)&Iyt{3gYTi{_}^RST+)tW(%k
zhDR7sw%j5R@fmN{h*16ce_}0)lm|4=4%_S%2*vRv+=X@NtJA2fqs(ZC03;w{tx0IZ
z<^=)dF|&_wyKIF;h~NFS0UO3#cHGIHa79`l_Px&>WvV>_KTJSRcuA_IkPR{ZcK`Kg
z*$-u{+c%30j?c(fvD?WuX|zHJcIDhsI$2Kncm7tHg<<q|mns-6{n}f+PLWue`X{35
zU*U51uYt5-PU=6N|L>ZKTz^}oR;hPoqyA}9h*+Ep{p`>58vjv%zAAq^AF=<+7z+B|
zJ_G}T8**p-_^bZf-2e6@P@=B=PZhZR@f08~3EI(R+?Fa}!b7U4t8@peBZCX$7nr;F
z%(7!$!cs*L-iMO%I(GKTamXNc&P&#ttMI^L=XNMq9r<AWM!;<S@>Z-Jb^w4^o^ndy
z0x%F9JStEUEv_6iP%Fo?^2rN=xUfJ<W*xvmi`S1&=rQc$RKr&atUn4T83lL?JCcQ}
zGJiK)=nX$}ffb^3amM8?|HIR#<dR)Q-CYgbT`k3+OPTDCV)m$KRV7gTP&J1wN=J=?
zTw>vPDUi8yYJM(R1X}a={+LTGApH?dY$UUE%Ho!v3*zmzaAyEJCftQ?!ks`76Yjn<
zx97R_-#~*s{mafZ+xS#y<L@bhI@yBIGDbn<q!jNnS$zNTv)!c7u^N-ds*cS7yZ{(9
z9OsHa8kQ)s7Y>|1RU-&oK=pI<+LVejRON+xlyurCl8ep&w**55e_W@>GvESn{H69G
z($mV&rw$VV^+B`C;e}s=^PU<ldy_aYn2*yrtdqiC{HRzBR&Fcn6xsEvck9p^gs`(5
zB6mEU4b?!U9ne!p`cxv_lBUWImA{92Hg3Xw&^c8GN1KXQHW)l2o+D#78S%?#lD+ZM
z{X2ax7JXgsVD2rQf!MQ0t{{ok>6Ov`&U5Y*xKYeAU1`M^r+o?imJOP8S%>|Wo8<l(
zaQYPPP0l~W(sXyDu!AX<fVd^bK+@IJleJveWzMae!pF!c;Udbh1mY}IV`XYDu7<+m
zeBU<@xe6Uue&9rtWA)H_ar33J)Xll%ORUWkZ6&g@%Tw=t1DaZZK!zOtzWkW2{8D&y
zh5FCg38$4hq1erCarKc$6Zh!*<o~Rt<l+XY?==%RjF09%W{@NT1}x8aX|Wj0G>ISI
z+3`L^&&-;Su%61q6TxOH!BoKzPZPzEQqxC3XYcmkTjwwQOHu%DwjDe4TkR4D+k+!R
z&?*2Y01^?6(T@qfG>a?U)%p7?Q95zE){8q(Q7Dmw*4=rX<-y_Ej+5VXrP$3()b8lN
zSmVN{C#Mp%`5Ar-LsTV@HA+j}NebJ=cwTG=dmVf-Et8!PxyK4NN(*&FV2w3IWLUCp
z)yB1OX_YTBtJxe-Zw@Bj(7bsh7m8*7Ye2-aG?D;ouht1Qp^iW@^os*Om~xjduj1zr
zg=DuqPuk#J#EyxqZ5tX7XFQll`;XS5NO@DEuqNEX%|hMZJ1QvKNtmO%93nc%vm1X%
zd$6P3fI&sK{#@Jk+e2+#YqJrc-b>mNXH9|!ol4jpOpA+?T5=QuvovLgA8a1g`5|Rh
z!iQ#o>HYXPo*j-yRz(V##z39NKE%JHrz<KMkKWdFLDN)cV=1n1B~H*O+0y*}h>5$R
zMAsv=Lp4*|Q+RXdx%{RJKa7BD8Me2cZ$@4SXo^e7cVfz_!#0S$)s8WVQkS;(L-Xif
z71@xbE)$7314`fB1L_HBq2SovrtcCv7K>jKB7x;FbAX@RgT7+V?+U`<Djge95O=;z
z+&MP+aCJQ-GWWoDSq-rUr02iAbeM6%OoxKxOvrS>IuX^7#`E@-?>%p*%su@%&AJZO
z#=c*K+vojb&4RBhpI4sOZBgRbWrty6BuA@s$}Kqwe{V9C-fn3{H&ID;v*8RvGP2_J
zL3Qkn?@4)$$CHn*{M+B0nzB(q9<txAcsvRs2?p1s$L+`7;CWO3(Cp?%L;};u1*72m
zWdTc?Vfj|4{!`-yL-<AGHrqD2nr6g*wrH35`sI!%?1{<GePFuCTAQ=t2j)h4rN%tO
zIawNS)!$$5ns2K~b(7(=bL)#%@P{AlZruDw+1XD^-ap!qM|2H~-KWgeG8QDapJWdh
zzhmXhP6f3A>@?C%#%G$4c2$}!>)C}U12Tzn`G$(r@$RMf!LFF6!BsKF_pxNDtWXVY
zy$K01tE+7UG-*KS{BjO|_fOeffV;=z7@Vu0uHj3h9g_OJ^V}=OEi^<6bxGZ!wJpqn
zlUx0koytO(!xS;2kO+$wls@G)fVIu`kEUwyS)W#RpPx8<j;6mUNn_`qnAbzgH$dox
zvJ2NV3)WG9SaE;Awa&Y@ILO97s*4=QfEoJV<y1Ny`0yeG{&c_xa0ySrB5$;JoqKO>
zP;D@#$|gHR_3GDT3et;>bKy2TFr~CHHXDIVr0dH9Y%=1ho>b>UnR7ZVITBv{R%{54
zl%{NO@>yX|3jfkNiPxC(*4Kju881mBn0T+HX<wyeqsna_BBx@^uYe@~^)UddnD|X>
z6)`DN)65jMh3IGwhm3=!@2C3>s9_pJK693iH$3etq$-3ldOqYHY-;b?FicwVgG|NY
z%HdN>;<hL^){cY$xdEt$k!E{9B4jV^pU}1vBDOAOtgPRe&UFVYXrh16)B~Z$%`Wv7
zw^JNuiA^3H<gh2$PiF`tW=4t%oP6HZX9I#gQ3s3ORC=0T-=KK36p!BS_q6oSdA$65
zbWgOnv{si0(lD=s!1bFQ`{%scaW>HZ<_cAsq#WiM`7Jw38KOo>$Vv!Wr%ar}p9{mt
zz0W8HVm!-=JCx4K#Q_)<;G{RN6VO9S*ne!Uh;;Ft4Mmca=0b0=h3h0MPFk=(isoA}
zW_bCZ?t5_XqY7w%c?WVW^}2qAQ2%lm<k}^1689-?O>7lvVpGn1vZ!xBcJ<j~SHxG^
zQ5;ko3M+yM@7p7Bq9vdudg~esCc+EG?wzI2jP_+Bd}Hi$o;L})>q=Z#SZrLN@#6Km
zqt_ZZ1R8%|-uh4J2UmI<dVut%sMAyE?508J1hd!Q2LKXDf%QO8JFz%1?8c$@v&LF0
zhJTO0Y6YOG)X+~i2Tcjkx6PVfnO6=U<ZuFxqeCa%a{8x@*OuIL-7Z;O|7G2$jfS|`
z=3>jn9=&yok-cV#67}(Ay63`lLuN_4CJUQqpNpPi-)~xN)WOs3@_K_}`GaHo_X*Fm
zbL$iVrb%m5-ZE+6rJhav{%uboh=hH&``pSelWL898jZsZyrc}HinzTLwhKRszmeec
z@DR>^r0l1}`y)b0R*D)Aj>_E1#p0jGv)U$aczl?ZRNa<w#5v;z&sSg$bKgdHeyqaB
zK+j`0uW}^;96Jycyunoh&O@Vgm<%p`Nh4t1LZ{R?yAwd8vvDPA!wRxKkoB3hgdIXJ
zA(|zcwE8YewZVnYh<k%8MnbSV=h+~c!LF;7oyZWQdMf5DJpa@Kjfi)+efY+onDoOp
zLgiytBa~Puzxp<8>wDWa+60ezV2&RtzMT}yaaNVd{(=AwBO(wyO^ZPf3`U`5dko}o
zq(?gTmWfUt^Scdtg3rpf-G9ugeKk7KY#SMBwoozPA(FF#J+T*~AdHD>jax?PVQ+}q
zQgSJYFbbiJUKZ?)d;o2Xu_x?sw)Y85FT2^ok+UD7g~8MFzLyApn=?7v_(GC9^<(bo
zAc)dpmM;S}yZrr{3nRhNPt0tsg&{`3nn-PM9M`+b?u(l|3o%4#RQFHWM;^7xk6EI2
zT%7yQ+`kHU8ADu;#AA*-S`FXGGB2J(8FN<3*XWr$>>o|&Du?L%C=uWH;mFD?xOhUa
ziPZLL%}<}9ri3&-b11HgujA;R??F!spdwnVMB>pbCsC=2JH5eEBoT-fnK-V(e%z<^
z<9&u|dpV~!#`u3RVN<_qn23yGEBwFS76Y?}-DPoAB;9RnWISaA?1>SZCo~Q{x>?Ek
zN=Q;#k6Q#QB=)T)6OBK0hkg*HxgRHTe!4P(E$l7fMa8k|{lZ7p3FGOwS`&9p`(3g9
zNC~k5uutxiSAO>}V$HvK{`%^$Pf(}3!NV}{)A(aArSs$~ucO)4Aa?z?!P4{5OTv7F
zGbdp8%1Hz|Rr9noBxMURM&O<vCyY4HZXk{%I=`5GNLX51dcQP!;S<XNL<x)ylUs;u
zQnMGdftEpTtu33f2-tJF!QmXeuv25)UGx*;Hz7dAe1;)#;0aqi5}PVg2m7h2{w*W}
zTA{)ERYdIb)))`i_dilFQu~fNLR@kEc22bQ*7axY&^<ndt0$JA9~Fv64#*t6v~8W*
z>@dyM><vU3@oop{UzaHRJq&u|B^AsVp}fPar$mcOs|^~cyi$9NJRR=uNj!0g8Epg%
zHdeZgSc!S`OoiVNJcf%SUVJ=u{U!tYK0o*~>w(*cV=u-b^Ct;hD+^5<(~E-Bi;2yC
z@&Kde3cvOVmUwK>rwybuSXkR}&7JE)FN;doko$ebtIEOFbk&v(g_ww+Wx=3GLhb+I
z>^;Dmine{<nF55KP(zU}MM0_*rT5+iEI=qCh%`k-1rmA}#D<E}1W~Gjf{lbK3Id7(
zijsf`C?Y{xfF$b$_uglpci+AD?C<5{OR@?pvyJ~8zd6?$(-ITDIE$yA`L9za(0w<~
z|2Y3gKdS)#`!InzclT1Y{Ljw`7kJInbEbL~q{0Y|i{0H0X=E3US6(YiU5P(w`#t^3
z&;CAFl5S{{UQk97>eTkluC2G7yd678LPY!er;opuv4&DZAO-_J+Au$w_D;eK>q){L
zIajK<YQNU6>d95`Olj-qTMS9@dGl!v#FtHzLX*+z<v%$aWa?8f$vwZgK60!X1OPSt
z+1aj0X+AHPD~HTe@~=cu+ayX)+QBcKdSQNC)w|xu-CVOz%^_0wfnL4kfZtL{y0LUm
zL1__u%qHxqW9Iater#_vP=vu$ieO^Xp(kTU@a;S$iw>g>qv<B1`PAzKc(9r9P`jN_
zm7C%Sm1Ta9CkRMw87?lKhgCu*&55E>LOK?~z^9?a&Tti4Z1#_gj2hgeiV2BaWGsdz
zTL(Lg?k2{colH$NHc1@<k-HfJGnLNdb%L>l-L5BZO484HXi(rNHSJ{9Inb*~eT1)8
zuuiOz9|TYeAC4AX6%N@yEK5ScTnVgZ0ON!K>b7BZ*B52wrC$nM+2tpeB#*j@M5%CI
zCU6CP83^!Pm1@9&LW}^D^nGG8n<tX_Y;`i$@?PA5RBDze5Zl3&8S2ArG)=y;4_@x%
zBXrp9yN#zji@ecVGVafPscL6w>nBdh{Q>a=uKxD3mT8zp$Wbvd<^=TetU{vQvG(rl
zoo%ZH93yrqh8jE7=A>FJ=6z$atNx`#G34U`sbe<G(nzy4S>;ol(qt;^kp^9p&#Nuz
z#jXKoZVmx&$^~kUk3KI}va!7_D*?gI%Pu$*R`RwjhZ~ie+FojW!N*j%J!ejHSE2C+
z;{E5_Q(9Jqr}X}8J)xfe>4G52n9)|dDM`_)B$oK>-hOV+%!i9Ai@S$O@;$#gUpddx
z7>CgYUv<Bi=ULW0KkD#zSA!qxbpGwf`dFv0v??7zj{FBAhIl1AEemUAb9T$X7Ngm<
z`1qmk1(+)`@@C6#O)V%%=$&wgLH$KeRM*Vx)wuB^_vb<LC8q8kX<nI*bBAzAf3AZ2
z4NXvYK^z}{sH1HKyZ@4(#PtcYsHkSKnJbLa{1n_v+J^>co_-|wq=pgfR|c$vAEF%|
zkkb{Pl+DW*V&|>2e0c5()Q4LAUUA$rd>Vo#4c=&864K2Da2(sY`R=1xgKAhC9*$jd
z+%$7TS63km(|~e|T52e}F5u*cs8`v|dSKo#e%u3isv(l2?_#d(pZqma#vk6}yh}qL
zXq8qxWwTD-*f`6jrTNTCe8l-QR;&`wG)q0<XS(K2d@@uG8osXq#oy64o%2oQ$fW{R
z^&11nw;n?T`;lkRoWn)C$A|k3qt2Mgb{TBGXVb*r>+v5n?KRq!tkWKQ@Nxc%T&UzN
zTe919Ks=9Z>&1^g>m#BFjs70eSA>**)+E_~;Rd_U#SJ<Qo5vv%^&yo(Z1ey-l4cIF
z+03q>ee3t5!h%&6Zvb(tN@=}yaOA+0CT3CgTcYY0BfLJ0WBm(${wS==WNSu@Q~$)L
zhcqg6lSBbHmV-s&GJ88JoFOGZ1!u7mggka%>EMr6#5EogtRuY^s74j){|-@us=7||
z*UCK&D~JYY-fcGpRu>H$>)*X6?uzE#1haI2BBURaRLD?Hm2j9Yd&{i(+4z8p^{nW*
zuk6sbC*Ss5nb4#|K#{MoN@FJ<;G5wk_3;tUoxE%SHM6efx;o77fq^VderLy{tz?8Q
zeN3?OGW}ZT%n2!{E5I$pu*Qll`T+Bg1E#fyxKTlRLrp2#59v7u%lIqt?Q;T%si)@P
zwj5!%#Uo(|I@^ii4PAUW0Fb?H#J7@a!q*Owbg20!3*H~9EQRgwLTa;9$}D+Mm!odh
zLgb}P9@*DaAxbI|MR=xcLj&h$Yixp<P$J;VB}jCkI}RSbn@<As;cw2hS0t9V!Y#_U
z<j1#UIJIzQLXQh0LnD7vM5;c(5V}GMKMdV0c{w>b2^%O=kW}IL;dede`Bql`Yvc<>
z&x6u0e6jm@<`^=%Y3MgeP~W-bni&8HSb#?K>?Cmdc#3uvzA41*%l*b!YHVBCbLaS5
zdlQHqnl`Lj!Wht1WPnVF=D;azkHJ8YbSFdutsod~MDFm73rZN~dZ>D!l2#Z8Jmd6l
zFtvMdr*QHlScvJUUFAgA(+f<Fj(%5qU)T<aIZ6YE)RLw?zG!ZtA$^>SJT={4=I|J>
zEFFoLg?%eXWq)S^v6KN~F57Cp#y1h9P-X>hy#t7kM~&&y%aEfmX9(IB6mn`!?W)5w
zTNWwl9D8=PrmV01EHXW**iy2%0QJl1LDVbb?qm`Nt>f-`=7DUJ1ss#uCAqmYK~^F1
z(~V8_0T#eu8VGcvoDyb+ku#Qq4F!oHlB*{Yt5OE)+9=>W(8p94=Q$lRp(7~pZ-}GF
zfbtJv9v^>i&!J!1do^&m1mYm$8Bj{11XQ$oM~QO?C|-_GxD{psQNS-b$pfXy=;6<1
zf(LU`0weVu3xw=UpZ=&R)QZ6~0lUr)&9F-o5f>IA;u?W;sW9JhVnh~dUlK^|b&}I1
zL!C;u7Lz#Eq2=A!)8Q0RGSnvl5TR)ZA+U7(ei(6bSwD<-7oviZ$<3FeAYd59Afej5
zoy;4zFkMvmSV7Si_kv7%w3^0o7gy=y&trj@%7qxs=S*x~e(TeVt+V)kfwhego#@Vy
z<;B<(;@g%4J<=FPVdSxs3vI7eLv~8aghDfC3RVOe8i+TTH*}7A{4%St>=^=XWpAW?
z!6ySU#a>Y~SIGQq3Qp}res<Db+t~+E<2BpM@Cw1fbwr5W&xTjV6MwzP^o)W(lvT!o
zrj32c##$XW#d3F%Zk=0l>F4sat`**0nw!(@jLwk#7IqP_+atOJqSf-+a~<Kb(YndR
zzrFZOY-a!w>gq|~ogAWy8htA%)iNZ2SkipRVSSA+mkSJ==4O{x)Y~BtVjRS7i;KNh
zH2%r!K;+fj#zrX*N7Le*Ea~YT_>!yh#;r{rmpRBL@<9WCOG}FNMTVd*`?y^N%~DHQ
z)(|LRP?V|-)6~pM(LlOcq<%dDqEj%O3TKPkhR=s;9?X0cc4C4X$K77#;gYsU0c$GX
z>Ny7wm7LGjuFa61RAY6%{Ps<;ChHR)^E4CYUTr<aoj%L^^-Iwp<uLN?6P2)m4CryG
z@@Qa=l!GnTA`}p&3BA0$eqrQNm6E<?RLOISM_2vAJqXtx$iFA9c;umZ&k&y=25@M(
z{xzeACd|#o+Zxp#J1+<TQByviW@rEIbw(1Yn4_c2Kj!l7>(oGqITWGqN`xS}Qz;yl
zJl*YjiRKrT{t*SIcj@{8iVND}*zO-b)d^*MZd~lIh3~d3(pLce{S$<w;Z7=u)eAaa
zxpgTY`VGPa;l&|3vTfI3+IBl;@g<AX0A??8`L4`B3KvT^3=3IrC<MjlSzy5F^j~IE
zH~^DI##FTod!{@5`MI1M<Gc~jQ8N8iTR0=A$sd2@bR*B7DNZU5yv1A=EY{NNs>Eao
zpqH)F6YitlT=b^|@}FxPS<_Ya0NkaB6g4rCqGtSgcqNeZF5QxryU7w9Wy%k(;Ip^<
ze{3y6^P2+jk*fNGm+i>ZV^GH6%;Sq*4+FBI!MBtu6_#Bwn8*}_wY|})=f3&O?K`E$
zG$^nW$!=$a-If`UpJkaAM#1_$OlI5ij{M%Xyi6L)*9egX)NOyl#qTAaUakY<bx~Xz
zHU!~(iw7R?L;P$Wp)WV`uUC5UVnBdkqI4sVGD}H>Se-}#pBV-535dAfy-Psv+MG!;
zAh~^T%r5a?C&9OOR|yn~nEj+Cb`jvRnyKDs8;u#X1%gleq3he<cxY-`RL(Ef?Lk~#
z?%Mk_!#i58P?v4?Ih)S%FP^vAnwVOyNrdRzk3mLMk8xU!5Gjo!EDpF7BnT9{wiLYj
zP0y$JsbZi{g;kh3n^hq@S7EL()z+`mOW?BV>+rLqsOnIq?>Q=;*9qd%Hb{eWi=js^
ze085JsAp2~gukl>K681O3d<xpVk^1ZtWro(7InWoRql+pk2saB#zHUkv`;aKcO|ps
z4KVxfPz8(}$dHRN>F8&^h{TV{!T6_B7-+GYQ-wlsE-!wl)#BgPDV8shxg>=*Dd~za
zfmkT!bO=0%{#HhxypF_A&GHLzXn1O6rA$tvU1+V7VJ|R2GNzbE@|k!|y8?UaVul&5
zBOu4^m(>@aCHwRy{vk0_tM-d17ytLSyk5{H>=O^!4h??DlcLclENxUCUW7;pO;#?N
zVNx&np{-URcR=wN$ae;)k9N-~@*^n)u=@*@<fKmj1!|nJuVr?z>$h5HYZhUMePR5n
zN8PL+y%(KPqG{+w#IM@B0u*dP24G=wC5)7fOrq%fu{Iux@MYz7HoaexQ*}>F80Xei
zfpd^E->!Xmm6oU0cBE8XuhsT1zjCVG;4n{zfwRZpqEy@$CM)}cv)_M>{ozrcaxqSf
zqWO17i7hd=-C7q}aL52<8iAr_(4*3!H;y{VPjjg2yO93+-w{(LloV(cqG@1^<p-zs
z3C=FlE~c(*7iO%|;4G_HG4JTCi<`$Y<yo6Mqz7lWedPDDAa47Tvc~dVaru}jLmO5N
z{KsE!{xg`r3_F0c0}!PC|Kl30uYYq*k<;Ez?cm>3{`13zE_rNugAVbW+MqKN^J&V1
zv&$=qgYULXZ01<o+n?V}Y<@AMi|ML~^31``d*Ap!{LgWXreXJOaO$M{>rfw&=~Anf
zEX{n*+*(|N(hVguy7XOf;1f0xl~yTAdfX{|l2kbh&BFB0P|44eN?R~nUo=v0?p17_
zy7>NBT%Vzaj5L%{BtE2t6|>3vEj1XWTKWcBU+h?T%v2}A9%<_+zBwJ@3OnM^HG}RD
zI{$KVepGO4-eq-bmIu#tLhc4wGhiq;qJIaQ7!B{WlD7Myx?cg~<`V>^w|f8k<|uSs
zJxp8Ue(y=lnV0nZ(k_$l)Ei8Bb|t?+rryW5w0`u<gEiB~9(bsg61L~!HjfOkN&y3d
zO;zq75cg>NJIc!tV8w#_ny*pujp-_ZK74=;=xgvQ#{CT`3j>lVU`LT=Vv|Uj(38}w
z9MhKOmYSDRzwb^#im~8&Wb2R+3AUv2ryEtdem9>v)(Z}<vc(Tod~N2m2Qi*TJ+C`V
z+6Ygt?Y(O*{xB~+T(RXIdGfSNM{>U@d}#Xqy$aeCJSoHgP8z5r!wiZED2YO9?rp*K
zpMq?r%KNXkJ}6B$nUGHN+5OCQJIo&fF@#`qV$5C}HUZKa`*VZ!;pxUtQ%!i{Qy?x4
z;F#G{9VDOg(>r5IBk=T$nn7E=ZK5_(-Rt;<*w5y4>tTZ?d|e{6zM+Gq;i--;_;u>5
zPdT4`x;f-+&wR<Rr+}vyecf#=$PnQLkQI5PnKgR1QR3`n?cESW=98uQRuMT!wgQO=
z0*uvXD&7F+NyjtURJsaOSI@&Y@=OF`IHyOUrJMNr&CyYa$b(mx=C1`u<Y3<tfvs18
z?J1xJyDlXB{ootv$CW$>IgCCpb=3(4o*zAmU&hN;sYv$i5<U&(1Ri+VBY%*tSv8UW
zeYgmMq&L-q1M)^IpHkh;6T^BWKVC9+hgcM(ACE>MNQE>@V1dd@s2LfLAZ}oB9E1Y)
zg5t?3S(>rQlm;!R6Y5B%fKOsK1&{7)Qt#>se!j2U%i`}MPi2@x*ScWk^4pF7+xAcc
ztNHhs1kLDzWbw?ad)Ys<@8P$#{Qjbpl1$a<k(VqCP|LkFfr-Ycn6f>AIm$XaFlK8=
z@W$)>zh!4ySL3$FThTBFlp`aC2(4k4eDEFC1a50=@vz7pk&2QBvQMJ2+eM2NI6M!H
zxD}bzOh^ihk=YtXh*FHL^+j@<(mDf5NH^JxPV)p}&31X4m>t7~Cx;C(JU%SbNSK`9
zM#MMFfS`-=pG>__5|H~9hMUZ%u|=fea?^v-I<pN6^FEI-!NjmFKU6{qu59cLDC7G6
zjjT<%x=g8Hb7f^yYkLsEZH#*fYq2AJsYsC~11a)I6B9QR8CySASjiY>C4`t@lE_&3
zyK8HGJ4!0=_E-YzzgB2U@$8oW^Kj@p+3zZ_W;Pe-->>cPKphhbHa!0dh{}LwptX>W
z<W`{2#r0((HuLySvr{rQ{t@U*er0oBUSj4k3SuGY6SDe<G?U)0A$V`L2^kK3x!FiJ
z;VcE#{DJz4NAID5M6{ZMCMIX6f@|LL=>m1D7x(196wxB^nNAfbuJ<C8eYG0rwtsWU
z|6fV*UkOLV+~t@64&BC1(3<NW9IUqod1g$?;tvHOqU29a$Nx!fO%tXOiTB`NTKSk8
z8j|YvCv?n`O1O}U&W0P9s71243>5@Y`uPr3%5h0M-X-VSs`)a38c#~0-1H&EVe180
zJ*wQ0$rV}?W%8MH9Eb-6;G|`B#qlZpGMcYtxP*?gNtEQtV61h6KNxX&kENTv#<;5q
z26UdO4OH&RDr3)jH2K`UOY?Ksu^lNnr#IMVo^Vy&w;<D}<WF(UH_#R203R2U%=u{D
zx+SC<nu{06w&ENw__e5T9in4#fKoa>sp~g4^6R5CLpR`O+dWa5)}=1S;+yK*5apM(
zoQOqJFMf*wGlgZSD61aXm8!|_5*I*%X#iJ^na~D-D^<)A%D^$fb>gn_C@6=eJxwg8
zymI$nObN|1lbZk>u(OMdJ2n6P(;a2mLdTDkV4G>nX_3<z(6o%wn1mgZZkqYRh9oDW
zcq$N|N{KNiz)3RQ-<CL|MJIL5qJBve*a(O-{3@1*e*fIu`tKWyBsdB7oa0Kl+S$_y
z9EN67%PaD4smy8D`>jCHQu`UI|KRSR?eNAtzmv5^?8myPoL!@v#$IxlhZ9P*u9M#x
zhT)kUzgWL#oD_TAO?HNjf7A~JlVj_!>p<jiN!Pz1L&WVsz4)!9V6hxc9L!y5zuCxC
zW#x0xxqgI3y?N@f{yw526mKl7q)U}ZQ}p-%zs8gJC)M%0G3>{J0uW2UMH(F?2`$N)
z-_>JE95Dpvar<+XR7DQ1_A4))abZ){O2)_#<RXC-=#*fOOq4vA2C=f$C3bIuyXwlj
zZ@ac=KouZ?E9$iJ({C0&ma9+-zor2OK$CO8$Gqjnu-1_)Zuqz2Vw5qP0gJ=TtyD{M
zyXL}isJ-OB4C&p=8>L_RgLr`G{WCkdauT4W0&VlRSI@zes1nUEorXWpOqc-=UoCKY
zT!lhG8*=F<r%KZ@(-E*E-n@}~&|@J{A80UyUrSnbwd70TN(z7VlB!)~RMet-ZARwR
zp%5u9pPzx7xp*c89Kn6Je=p3BXTm8U8>4A&6f0uafX4>Czt+9?$l55$i!JVXZ3IL+
z8A~-R1?COsmu&JX@aKdwlQqWvU1y@Tu!23qm23vF(!^4jHJ4EO$%j^6@qiCiIqX|^
zK?!2Y$q886?W}=5BUBO?f<4zEO2CYYMLz935P_XAjO;2u-cZ_^`EPkyO#&q(SbrB!
z%&d@)VZjfBBIUbODtc%w<q~o<XT%k`^#Q~k{tO<r`?P?vvX7~<c_YuiU+-Cn$=kT7
z<BheW*v$!kdfc;2hwfz=`U#c-C&kZpy6^GZt7%*6*O(z??=>eYZeVPm@&uHEq@{Yv
zk`tFs1`7Zw#F*{Z%&`ZF`0ZG{#Xu5yjGOLvsQ8|O-w<2l!{>s-7$Xk<1n4$#*+EKr
z@*6d^Kcx3oxHpu-=R%W7H9b;P3=Dw|Jbw3~&`jkT2=bh;WWD@$MuWzS@s63UJ7kg4
z3<BbhqKWRcSKDi5yzx)?+*7EYbfs-GE6`3E2a<%Ig+FcxF1EBi6ru10TE_^8+_F=H
z=weKk7PDMg>b4qha~Q;B3sBC#`hWlKA6S6sU|+yhfu$d<K`vLd-ZWk<y!SYcqk!6@
zR(tCBEk=jFf#$zm3Y$3%Zj;^7H3r9Z&oE1iG}CNEa9@BVP)&OKQKS_emY2h#$^xvj
zM>e<1QU6bwX^lsdv<ck6)K)EU&00Jr<uEm1yPh`w%6~;d(aRebHHP+<hP=yJsD?Da
z>KSS473c*n_?Q7HdZTe~${7mSWaBp!4$Rya{|X|ILE$0)eK&pwG)|rm4!;WF9b`Js
z^e<UJH&XfuELZbIql>Kh&Y25$hTfzgu{Dk<oKm{lf1{V~y@!FYWyP-G$)4!yikRnf
zXo37U66|YU)71`8b4WKywOj*<{C;#jsgw$m53%Y{*kKHy;m3FW*=-Ix8S<L|6TUmF
zx8Dr@<O{&$Wy{4U$D}u2*Dm5hiQX8zgHjxD_h)_+Yh3UUx4$&V2t>~byy3+lF%owg
zPL>8A6?S%>-`_soy-{SNkuKGM&pqKLI4$^QZ|c)KvO*ToA3u?7cz2BlWa#OHMMK0k
zM90Wv!PNaO4Xoo*(`9H9FOujDrO^X6WMy<Lj5QeMrlAZ|R@W=O%{=!1VjlXje}<qS
zLVu&0@@(S^>nP}elIQ;C?wSpDKkI*S{E1r-KJ9bp5s8#VnQHdOBzzm-Ce?4GE99d;
z9p19^`Q_^*Hb^duE!-0*VwOtc37HSWLv@bHndkd9t4!9_$;XI8G6>Wjf&Hbl%O=93
zJZg{Y7NGBt;%-LxJpCC@z~p9a00s0r?>We&;JsBIVL^dSxlP{{7ba4E$d8HH+5qdf
z<&GqHGsg;iFo1&&$tH=V>5Gi(@)rP6|1wE1v9^Nz8esY%uHg>yiB!`yg?1+flzt1<
z!eOR7xhw;wrB2;n_2+2cwCw(~23KTHeY)?edb8yL4}K=`P3-EAy|a|V&tH5yq^7?0
zlFo9zeEvSb37e|g`IihVVEcM;K!$Q5HY@wMYRdY82HWT52kPtiv2#Wi>`(ZGM{n|>
z?;^9zzpAY>m^zvp!T!0fz?!|$=dqKiCt3!M15-z9s2e3WYf}h_TPpW9K1`p{qk>fM
zK)<+n%Vs@5A<NE_3_+P&(8A<=h9-aM%P~%zAxKA%tf-(lw4ao7>*4D~h`^nz<C?AT
zo=0Id4yf+b^e*$e^w|VY-i{xvpx7H6VtU3<vpyks<PS5WG@F77-iR95cLVrD-E=i+
zp7w9K74$6uc%fG+=q`qR$->fG?<C+ywHk)|3~51huMEdsgq{N1lN7s?i;0Ld**l+x
z(pfr>Q?*6B#wOmHWT^;pA^i7c{3cxi=EC9qIrDHV_kS&{Bt(ysGOb7=akHzkG^{7M
z<!Aj3-Csb;dE@cpPq(4Xl(f$dR0G&k66!ou!7@hBed6tv1K%`_^+?J!_@N_Rvo(g;
zlGO$XQcPY@;LJ+7qmnK`;Fu~o>UC!sq6%sYOkHk#kvgq^B&*a*vP_0*%$J(l!xdj}
z?O<Kz0+F)HdGFNa{fvW+8{SML=G51d^V-*P_}df|EJs$~xKrcqg#Ok5XjNB$#$1@7
z{3v$!tlgPrXR>&Aw>NFP;SBpj+%o5Rd(HXt^Fd^vyX<KDfOsHf=&OHg?&AssrH#90
zx=N<QEbR&K(DeDt;Ftt^8V*hhGR*nh@#PQ8myq;oYkRy34F#3nY{*Z|0tmJT83)Z3
zZYfI<ZcK-s?{=c>1g`OUiZVa+hV;#*6pw^1FeoYqwTkR5@IOTzxDg}b7$6zJb@ugW
z+j~NA^u+<a6CA@Ialnfb@6<+&AHpaq$nG5f5t04o4D-esxpjANmOXPlD^W%g0fP}P
zr?a3?c89dk!P8K+Svv^^*yWX~a`rSmMHv+wYX`n}lQLD<b_zJk(Lf_QUvaImoKt~u
zngsvGQYA0<N-`6uvTOIgtX0jplK70rD7m0(dvyt$Z4_b&LQm|TpnxvD$r9sDMT|7h
z61xKM;jvUdUUgMB7Vuk#UZ1hlgBTovFvK2KI#9>l!})a!OWaf0^&n=al(PxV4WRe&
zT{Yi1FL2PY+J>Z8V9pDDOko0%;Mh`IbG9cG%bX8;E@7_pTcx!RnYKUK<*CkqHHjQl
zdg=y!+eCx9vQKaClnhe$1Z{ao6YrBZFJf}AyuatkVF+qwv5hkFC-jG|&3rx^dxp9W
zL5<Hs3(OT1j>4mHNc|SDBeeDnv^7d{tqXj&Por#RMdv;#KgM%7;Y>@BnRdicO$J#G
zSk>PyOR`luBN`SF$CU-E%2jhV3x?K^qNzFA35+lBkJ7P%yjyJ^`gQvUCwK^i@9D@^
z!L`n%+tcm^q4>3lPOZMn<?AiA%60<hpv1iFkt|}u>9}Z_f8v(#Hf{y_{J(JP?@Bp5
z+eF1WK*jq12O+0n6|ys$|68C^wc-9ZP|dmJilcG~un_p3cFWfl*8T*ra+!TkqxIDT
zvLuU>ft9;4v2JGhTLkN{X6ce>9i*&i*rkX8eZvdDGwf?b#H&+uX3tJh%@4Th;HI;S
zXu(PEbED-qxtW{CMC)kv*dhZB_FA-tA6}292YB|s<5`-9Gk@|w^v0nJ{1O3MIgc~1
zbR4{OpQ&zUr=HbqG)G9N;%OO+)|^F-t#@n@yE=AIBzMIPx9!Gkif$)a_`lpY$eQ5h
z^MjX<+La<u<rHwK#JJ%{jd`qZQ)@p|Z0a@Vs&+IKpkRjH2XPD7<R51im-D}!vC#0j
zHdR*g{eHj|?U_4#wbJm6x=fMf6Im{wJ6%q-%jF$etSTxShN-m>9N_}m<6*yxB`V+C
zePSjpO%#FIIhdbxvKarZ%Px1O#mD6#JClDOc%z+K@#;E$y$wa!QGxwnG2%h6vPPUb
zpKE(|5osR${*#NncN1HgeP3_JDVpj%RW%>QawQ6xZbNTm^&f*QL@Mg~Z-{gsO=9=B
z=d5)LC2MWKH*3tQv&L`UcTBttW}}k|v}i|Nv+Lb_ptu-87N1hdbX>k!L9Zr<tmYAb
z!S-Iai9K+l73d?_xj#j`_8)tkTUxS32<SbR?;!m(K@VCYLU>lSGokflaD(M}!ZC8E
zKB!1)e!RFyfVI1B=-xBaQ+w1l<P5*qrCb=5U%e}Q>j&|R-%>}-0i3jTS@$Gzi=wmu
z{70jKy%PDP3Qv&0PS*rMnmEkqD!ZI`Qro`gcUUlq7>0cbFu*+;tPi-CGdQzp!<5!w
zHDUsg8;Z33t}XN~3fgGiWHT1@2gpW%Gy8Gx<8GC~C_`xiJ5tf7Xu*LmjA)h)_;^%P
z58Zh*+Facs%~bzq&2K>!(IKrT*K9!u`A^#s*$mW(V?qAGivuQIC(3?b>d?*NifLcG
z-1EWL%&<=L3EHvYhOJ2CSCdmeo9qhsB^8CMWt-QOUmcE3J9U08O<qttf&k{uAi0H3
zIlkaICFIrReDgvEVh6HY6=@-Oiz*}3qaK+}DuF)#7t^35U@`iSx!UgSX7XrgiJkcF
z+%M@=V!lj*CA;Ss|Ln*}bbGhALZYSU@MX<p`RyUs<L47}vV|#clj?q6ewSc*30l#h
zfXN(rHD|ZopWQvkO#a?@xl1!I%75LpWXA$|gg)N4_IQpB-RjT3?RQg$k{LcZxrS1x
zbFyugb-`Ih?<_CVR+<H}lD$7p6!@55=zQKGd-Sfsl42vbg9zQ8%ENB)x!2C}O4XO4
zz&fFWHAc{A*N(dpr}?Pn?vO{)&Z#PD!v^``E|py#i!gC{MJ4^<s4QEKP7C9ag52s^
zCXd_HGAsFboKUnF<qNJU8my&yODtns4>RxtxZ^vuwgv)8-HcPbR)q2)*oZj^AL~5b
zUFSut+H_w!`;C*Lh13~)+LS2SVFJ+uJS;A!xhcBI2`|fO)@xqsUfKOCn80@GVx(P9
zy~H4J8c`WKRJ)3)zt^<%pe8?sY99B3iPwV?dW3ZW=MA0#RL@ivr)GyiEMVX3{OQ$4
z1`x%j1>98gy5jk@6jLsiYVqSy?<cX>#GL0};s*X3<<ra;s`DcQ8K^)KM$Fg3SW#&G
zzG9r#ix}$7`oqWrp!50I!tSdRG?TZ_$@$dlLsdTf_vi~e;S4IboS<E1?&T<mq7TG@
z5OT*gpwM4ow4~G8tr({<6Y~n{92^u2M>}lDc5Ak$d|~PGDHc9$YwurtDzeKWrFoca
ztVs)DauneyF<cS5t__7-sEWuE2whfc51C^W<h2VtKmXQnc01>FU<$|B6xem$@^FG$
zzfx;R*Ep@i0|PYeUGP+PEzCj3SmoEpuYo<9lI_iZx)g3aH{}%bPCel$+i<K^(!fxQ
z13gwGr8$_-{|juSk|b<q&&+-2KTCsgcwZX6^{~qVM*=!P24$eeY*!|nL}LKkxx*X&
zF-Z*|O{O|DOh=jvABxm2=<>8uTU3I~=GYr8TOO?!d?L?lV{^5wRNp&DJcb1I1OI_#
z=l1U?i@qR6g2&c&{yO2_2&6HR3Aw$=`~tJk({Egn2h8NwVyeScd0MViCf$Il*ef3t
z<OS?!o=N)gGwH#>s%LyFz`W~?&x^a-O1MMi&XDo&Nx+eJE(wTdwmfUUoY5kdcsR>s
zWGs$7<C2EV0gkuYSq|9`*z~&RIOypTQ4B9$+vwR}(m#vsbXOP<aZ=;<;)%XE_JNd{
zhaS5V#~iVH54Z&gTx!}hm)+7mb42O)VDe?Ra&~vkpX;fE5`X&?hC~JWSozJd-cdY^
zn9r8xdd@o{Kf2F!cl3c@hV{EsCIIY$IqDeNMl~T`t9kw+c}An;lQ&ma(Glk8GLZYC
z-``)d5TSMUQq~~(Np>;FsQH5mg6`knYJBd1N8<SX0{)1v2oG6<TI{1?{*L1BFn?Lo
z-w8#y*8MW)uVxk(*T+ei;<gT_vUyp%{K5u!XkvDEtDMJ)9KN&z|J){jB)#!AajSOB
zOCr$n-o5pVJGx@jqz$?(getk!Ath*{m%sWizRUf;@?GwK%6H&9?0(-i->tH`BnEz+
z+4uy7--H$!Of0P+E}V-Cp!5Ljfgb@5o)xnbNE8qckemR1FcR$XDWvjK9#y^loUTz<
zR-c3=@Gj`o;>itc+(DY@X_|bA8YzsO%%q@)=;yUjj8`-v;&k_RGU+#Y0z~<LVsZgW
zPN=@pl)!QL_a;?f&y@8d!~}d+-bdN5$OQgQ?KPUC5yTH$>#cY&InBU<p3JoyFVe;%
z!y2#+)e|4vN`8FM+wxW-u5F$C!~Ky%kZx<7hSMeN{a7K~_dS>FG~M)xPQmdp<-c#Q
z!WG5hw|i=T`OO@r^9TiSh$l`__jH7xu$Px?@r>{OO-@RW*n@G0Bv?khJg?Yto%#yu
zYP0~z>><J)$FGC}FV_=X*is<dl5WB<M3;iQ?A%xOU{{2b{V1LPnsZ4rewyBvMwmpn
z<ikkp`KmzO#h23h0AUgZH<x=>z?~q;6SzeU<@L6P-_buM%JOcY#W~H%)@bS$fn7o7
z?1$H88BANi=e5JqqB26qOVIU3Dac95Q}M<Rrj19Sg6CqAs_!c^IHX}ycbqC1Ye3_1
z;`-LkBQ<5OnAiD#RP(pdq-K?jVJ(h@q*p`!w!E+c8LJY2bj031m*tPIG1Le9feE4R
z@ceRGK>pAaumsfz5)VuYh$7Fh3mcNJM>_rnA}lQ1?LK`uReC;>UFzxS)zyXuX37qc
zGXBY(K(qi|#pH5(?AewiAa*+8SJN+#J!VsZDs10PjNxz*y*Fc$?ByKRb~Z_IHf?F+
z;m!`Bog@+7;oz41O={$;D6YJl>h21IA9+rWd8~gU++iyyA`nopqZC+3@`nQzDn@@8
z014|aa(U)!{P8E;=d1sCxV9cMB`rl2okBn-H41`Q$wuTrL&{5LGEiEux>?i<eI;QG
z9fEc15LS7io`bJZ*P)gkod>RGW)uVDet2GhewmCqP)+HY(1sy;dx$v5lhrS+?k2(B
z3LxyZHn`bszuv=Air(H#gSO^;(U~Y2GwzG}xspkg_ULOsU|9$5^7V}%1bDGY@7o-;
z`SJAhKc;ZzwQ|oyV(G2|_p&n1dDnn$&8@J0lYZ$w63a6W+lD2Ub@fEQg1)6W{UZ{`
ztUFIyofrY6@E<zdNGPPjkF*Z0Nqguo0?SKH*dpMU85M&W3E!e<$q)QFlI8zl&pWgV
zDj6K6*op|SV5(?)_Aa6A0W}yL927b%e|nDH1@`;m6&)8^YOm9yu=N9c0z#slgfbF;
zvC%G92zr^6eJdhlmwPIa4t!Z6$m7p)G`qAJXtrO&0G(cNgLDNK`bI3H%~9CsS1pl(
zsPAx>%us9qTwS5M`dNX4-pK&XeL3))7yq-@VCZ00plTgxe5sd@(uCt&tR)<R2R~uq
zb0jZ_fMcuqR+WlB4vbIj<U}yr8!vyX`@&d}f}k}~yH+WUf+dSI3dq3rTQrJ8$kgNH
zIAs1E2mHFK0`&a)F^VM>CaI=|b$|Q0mOI??C2h8Cc6!hF*&<rW;QP})61+z@Zty|H
zvRWH=5*O>`mW<C%eID;eN($i~{0pZ}j{P5Sign;W#Hk0evj+cLocdpv>wDi54ZP)i
z-qZ%Gi~%ufrtAGXn%#xJjYL48W8X!I9O$#$!OmU85W(L|F#i$oTo?;12=XtZvEo%W
z&HF^UdP5gn!mwwCGI$@0_Bpdpw_l##7sHYXS9R|*-kddfdXZOv5ohxFK>p95JJAB3
zoA0gWj8xoDa0wjkz5unP2lJ%8#K>sknN0S#;i_lRHIevVUDUv0PXVJSg7(psfQQ`B
z0<3<oKwwU%tMwoS=u3IIk0kQL%}?fRxy~}SSDc4v4gbny!=^4*c4DCgkpc$TPPg|-
zc6scf3Lsm*RkRD%wCk&q7mBgPSxpY7Dj!=M#C=`z9)w=X$=Ka^a&riv5fdLA{~Z3z
z_hon<pZMVDl|Ok7-HVhJJx$vmVpo)2krZBi8OvD2HP1rs7f_AaDA`UmgP4Qq?MZh&
zJD8<c*|T%+^PK1lXU4sIAbFCm(HCO-q$(1k=|0hEI;wXI!?ElBjT;R8)q%&O?>ufD
zjNHQild9k*EUGG={%=%uXP1Qxj$>zdi0JH+o;t!7`Ecmnb<sq+H{IY{{J*AjHcUEs
zRAmlP!1SuBxS#t(_bdfibHs?>JRm*H?smOje#fbgzpyDv0rv9O9+j*g6!r+|A0+FL
zr|L6o(p*)ll~j4p&bGB7DFWDf-2p}A5IR;Ma$n0{>VN<Pio<%Il>8w*IEn>7wO}D1
zey(sA@qOcbjVwqwg)}7ov$z+Tc_=wa?wTESRYR(75%vxxvjvqZ)`B%hzgwn`n%bE=
zp8g~{bS#minz?%~N-gB}8bLJD?GhGRg;j(RH1;~BHa0qbxaa*ViGPNaq`0y+;tHlr
zPebQlr<C!C+R1yir4$kDyFAJ|<9STkpCk*d2DDj_DsZls)m8T|KrrFPR1d4FPP<P@
zp)nUCY{ReBhUF|;n|ys66dg;Ca7a@tfy{av<sGT331?GOc9c8_Es)h4m_w*^8w@QU
znD1GcAbfQ_t12m}3oN>}_%3uv`TyHsEVmbcJF>DeE~!NB;o`4N6xy?2cAX+vCzdn4
zTc{u2D7ZpZdgEJ*fi^R4j`z!olCLFXnkA`3FfRGv6T1b7erz|Tum6agE!rE0Z}T%;
zI!{uU(Xb6o^sPnwA;GX8Do+c~Am!U`%1Ebnpz9bO2j)W&i1uXd!IHsGg-PG;bp#qB
z(3d|+cQijsXt(KHO0MdtaR|8Q79_@F2#mf32N7g6lZRZ$r7SRKIZV`TlmF|*$0-+$
zSuKPj{ki<loDJWv&Pz~Go4jy+i_k;TpglM&#=o(hzi!+s%)jscS;lwLY(2Lh?7{&w
z9LRvvT9T~(iv&z*=Mm(~{{XsD=g+ZLj{$$QH+STqRpo{m(G(<29i5RFFvJq=&l+C2
zD4WnikxHnRe{8&_!2KR(7b%5HZ;Tc-527iK+`GBRAV+QZK@j^+r=Tp8R)~)1ig=dU
zN;;dAcGFSzst|v4Vs_mlK+2}9c2$3AbF5O1zRaoDR*xfH{ooU;dUmrt(6|o5(ATy|
zYy9po&Jgjqsz&jGv$#g{)9FN$2^v7)9(9N`k#3h-Mz@@=6uQ7j(w)0Py_b&PB=1Y&
z^8JDeSQ#0TIdn}lb~#N{z-3fG^V*IR11Z{6{LD&h%us;fxqOJf7)Z%@-raxci<Q4=
zQpOD%H)v7;sNDiwfovG%eaGkfTPVo;cffH@BMG_N5PfgJjDI!M;RpnKV~SQ~-pWSs
z7_-W#z=Zpnwso)##GzZkI_v=WLrC!FXyt6PwZtze1h&6dc=t$!y#CdoHC}^{b7DKZ
zO@Dcdr@8n?b`}oi4kR~u+82G~%*?n&M}SFBfU<FRyH@)FKlLHvK8_0Of1SPW>a&Y}
zb!=6H4Pqw`To{Mw3Dj1u`-skXY?iSdW$nh0*YPY5@iI*@B8#qteSqu^1M5RgZcvWf
zlgbx-fE{qL@4W@_zt)4IlG#Y`NB)gKhDSH@ev-*{m6yj$wg=B}^0>xnb!GXjKSPcS
zUEcUj#8+K?8%@(+y5GvB{r$caP44*bV;E>2qNrozTU*Nmac{m9uQ)H}`idu7zJ>~O
zHt(D>$;!?YbBT|?8fzyD>5av)2_Fcw$-xZ{yfyLh_E&f%EmnK*&b$4yBvSY=nHalH
zfT)w5is{@?=M)Z{!vg0bnYq0$x0pjz77uEmjMPGKw>$MG?eri1T>my`Xp?FvmxxEj
z+0vONAO3|G1OHdN82FE;j|5>4c>lL}AsQTtGPg$J2!@KB$?||R_kcsc;NARzQfpJ^
zq_75UTO&r?gZ&}*mxlztlJLYu>LZ0Zqal-yUwK8gOL8flmy$bW`97M8V_a|pYW31d
zl6voFzAn~sNzz5p6_4@E7u@!{9_=4_0zq?x_g3lyKd~uv9)WO%>89TS8rU0nqFBB4
zQZBSMLwW3lV!FehNl>?Eptk+->7gKgC{&gu6r9JB98fWrbY3x&lsTj=B`}g<QDv@<
zd?~<+4`E8s6u?Pp&8J>H@I+!oW<t$ERo~>iT){ERS6&ZHwa{6f<y&*$=uVM+5nnXg
z-mfH$b~fGNrQ7teiY1l>Bh`EV!icS$YB~XtSu|z3diLt_&BG9VKL^6!vHM76NKox_
zx^xfSAa(Wf;XaxvX9uo8N8z9h>ZZ7glo5xngKpgggg(G<oUjq75`Izpp@nVmP)2e<
zyQadWw#A>JLG(za6T6DdXrL@h$4c)ta51I>p^lLK$?eZ{oeiM&clqzjN>Wd*lb&+~
zVI<kGn=@S7z7B&Sf&ix6wVENHogyy~*dtorM4H3!PtD$##N@iHKM;_YUSInKxWe0D
z-tzahmTx*NFTS{{lW|;T>bGjq_m2wk7a*z-TP@7twNN2!{09#1(@n>8SUorH>gIE6
zdp>ih`%AFX%j<{!gdD{~Taz7P|G<mnA2e;a0Y5;Hq)6|-tq|7R%(`H{er*E->Eh&|
zsE*(+ZKZdxRgGh0H*2N3Gv3UWK>+h?eBsM846WAd<lSh}{z%!Mhr`xv{UJZ$;rzyT
zyq~Oszhktu-Y&7eSjZ~(A1sf2yFvEE!0xB!U`T01hM~j>FX4-?<N2E=H4ngsc?3Mw
zQ*K=6<;pY`e-KZ9btsYm;mN7~MKWS2c1Nlt-~!PBVv$(r%Y}{_u!F$!nJH@+CDIiK
zBLLJP6|P7>3u)RqRwj`j@Qa~`i{_?|A833<zd)@8f^wP<u)R~8S7)nyOn}I1z%?uR
z`4W3QU6X0_D$T1)3W(gLNOLzu2b3%lsjnDI)EWY!H}kH7<z<(lc6Brg9I?bi|Ls}=
zGy2RIMp5Sc6p*WqomL;n>s^YIZ38^-cn!FV2i%RS!_ts9Y?>baTrz<eY2zn!x#6#n
z8X8^7T7b9inaJ$=oLrJ*x4}gxlLT6l`*qllpS#A=A!dy$yWiY6xu)CxzBDmjALo?2
zGbF03tX#&W0Q+FUW!JUqfPd;vi0qxV@lcZh6q}%-^2F*R`q!SvN?)jyQocbM=fMl)
z!={JcXA{k=p=eonRLQMq<7a)#aj7?C^S7v0G2GW7Xe?+Us)b7*yinY*D(c9?7n}l#
zCs6Hsp%*EcUKKemhZ}z80K^&rB#9hy&D_Jy#h)TWxqd=?Gl1f|`e&Wd<G$1K8d~nF
z-<-$3_R(p<SU<>xNOjM=t9F@P?1&KVzfG{D{GTRRQvTx!mU-DZv;TnzhC+P=f_0GD
zUmleLpFI!tICv!b=cn*mUO)zWvlek%@-5H611afAZTN-;pqX}u-Xfa%!LZ^JI}IKm
z{Y)t`+Bi28U8nI=Ka3DHO_LQ()~DpLgA4LPKL<=SKrJF)OhEY_<5`AChI=^?kH%d6
zc`eD|{JyT|ABRk}ehJb2wx}oG%4zhGzYro@3AP2d9->lC#^ow?=XNC~^7zf|*I6-s
zQ(3Y(zI?`F#I?SpSF1lKoY)q3C(8BgpT@irwPso_PS44;wQv169%{blY9&&h>5Yfl
zs||+guJ31D==(cp`LFD6=|M}$f)r5jC0+g^<d%Km0}cqnk|(a+f~Y>8V~C+%134|L
z@)J6dL$a9_0*YPYisR`E7X*M>Z*Olco_yb!uV7z}{!X!^-$hCq%~jQNmWQ+B*NA9b
z#_g)7x<3v%nHJNpi6s8ghQ1>dV!c<##ZRjrfVrhV8ojYx%qZJ!yT{VL%<_*5?hh9m
z{1UiwtO54=B)q`tRtr>`A=Hn0p!>Qq3*P)qJxsi6uw_S$8-$10u=Hc^h8Z-~rYX0o
zEAt_WZh{fbyA2#)WS1na_I)GnfV%K3ZHD7mNKuCTFQizY+_V7j8L3Q#6izK(r$N0U
ztvilsJ<dD^sWEt_fQ&kUjVdUG(CF2P7ad>EDkv2+B1b+d+&|E})xtzSzaBaJo&4Lw
zjX8^Fc0t|vPMbR~qHaO!5JZN4k)c?uEE=eTqEZ#Ptb^|(^x5Cw;F>j(h{h*$ZmUmY
zbrwv9*pPx=g-qJf&8YRvc(jc4H-zfL&RY>J>@=1Vd~XIweq)Hq<%R|*_K;oxXJ24@
zsCh~Q7L@wutaX|RgCs_ORTn2vLqpkeXXzI?Z$OVScQkn}L*unOHQt5tm%sHBeuj`z
z|LoT<7mHQO?p{rmXD$MaRKxrtVSxKkAx2gk+LA5rI;c3ygaY{gH950^w3^g!e`4)Z
z_|Vu(q1NSXsAhuB1d!BMJaDb;5t}e$MfQwZ_~e+`R&wl$VOS2wxZ#lOT6KELjpgqN
zZOE{vrtNzu_P%#?KPfIQFAVn!)axUO&|4>Qll2rgTQ}K3PMHf6gkR2Mu+*EiQDb`%
z<xy=|^gPo&!$WlB82O9u3eJ6qOJf55ry}u6G4yrl1fM&Mx2w70<Mceo%V<LDuQvBi
zmpF^Q|1#PNytFib2@pZ27KaYMm8<?d%RvByoNRUnM^QsTrhqQkm+I)A?`u_ff!w3{
z!|9}WngHD?g}@6-?&5sURhzW6S<lCoQYfVAqw0h~K&#Xkjsbc_#^#u)z=xLKqYFDb
zwfcJbKQVt8?nImEg_BavLaWDX$TVqZkwxKAv0cH_NE1p01pqb;7ISQi3X3`7Z5qen
zLRBPqr`S@3?AMqM-9(5cM}@gIzAV4{wN|Vmnrnulx7>k&Ke|21x7p!NT}$((=<?pZ
z{d7B19ouj8u?rUta|ytt+CIbUf!I1O1C@n#Y+`c8oxW)gct2tF{oGaj2~wur8Ns?K
zEgQ)=+4+d34{lM=$q=B9W(w{}#bt~aq_m$~QrqOWBOuo$L3BZv!&NQ@gISKs%GJ}j
zt4{!EQ69rPsZ&WsBxj8;;5<j~G1~)jR4EZo<$;4o$>)wf#6N!H2+e)W<96Cb=R?gS
zIKAy1rDSHPX8SI$y<9kP4IOgNa3Ul6&n&C40>a_12Dc!3Np~KyyxsO~^<l=NYuTO3
z?_Xq@JMJXM$(;@iboX9tL*ZV?`c95rjQeGyv;T*M=7sMJnH_~5EZRa#gm<0BZ|$UF
zH+<@ih+Ee+%-;Erp8J~WG*<y-3;;e<Y@$=og^jC51g*T6O@0GUh-);wZq4e4-6Cx)
zYdJolArOFSvpZtj^+!ec{T4($WmkLi6&<2;?)2l{Yy0ZsE(lLx18;;28;<m2?uHRp
z>1a_3&!my`IZpY<tJG6{C4;le8-MRx+jyC4(`oC9L-6(?!|r}nae8<-7r?<uTNWpb
z@tUxNMFs(Y=`+WzJ$p$UxxES=w{7J_n(;WEYq^EI8R9=Oa$j(h_p1}&qW<8CXK;12
zcF81l78cFsq5hdqxDRSC0<vk9YDIv(qw#(eO_7C{Y`4y``Z8Ss{{CVMtBsSMuG4GC
zbpD(Aj)?+SJX$Pwf1f*4)EiW<xhSpydrci3XbSJFa5KH=9tjyDZpJjI>Ct2eP7A^M
zRqJIofx(mbtBrU<<bHP;?edVJSpee08TegOAOmYC9ad}l25qb=@w)OkM=#F1XMU96
zJNo^#wC^bC3~JE-5Y#?$y6eXE(L<Q{V9Y&6Z?9hOe#7n!Gi|Q<15oNkEQ^aiUegc{
zu%ECSqF>5dnf7)t;<FOFw&x0dkS4J6H2kf*=Bhn$82@0ib~mfQesn%NIDaF#xej(E
zV&U2PnI~-&hyp0uXM9M<-CGKeZN0{pI9tUweVW}ae+CMUGUeWh25Jblzz$)B6G`uF
zYRF3yO5L~Sq0U*pJnZL7?xReI++XI4_fsa>?V=vcwl*&F-l796hyCB$-S0~kvz!>O
zUOW1vjYk7SYkMsb3R3+Q8deO5BQ;c0`lZZgtTr;(S>f2H=m(KEky-vpA@?Pn%^Oyh
zXP5CTUeEytC3p1k__StQa}Ii!qEM8igA4MCUn3N}RBSzwO$4?See~WipW=#JLH^?;
ztRNv@rQ=B4y{k=G?E1@HwBhr$_{n8}0I`!_Rag7l#l68B-L(mu=XDRM0dF5LPIGma
zQUD>O?i)-IT{C@SI@d++lCSED!QDQ^hmZ*bxARW^M>&!yFjK9x;F?iwWSDpq1CL~*
zA@p5rCd_RY65=JvAzKdEsDf6jio5`;gJD^K182kESDEXEKP_rPlO}MRWw=`_Y@Fpb
zKL3&==gOZId7?OH2BMj4ZC%hE=aGqPEs+fHJx*LQM*t*ZZxohOgH=$~@&Bt8B`MUj
zhup_*R{Af}fKRZsGhcp*K34sFxaM^^G|dHOnrA9~&E-UP_lbOnfJO;j)ja(EndoSt
zKa;3Ew%I`az^67IbYg8OPoEI5&81>2F5QRz2bT)P4f4n3vm81Gp7{@#j)kS$2mixa
zuNBw>m;diwjp3td?@)FV7#oZLf2pOA{=S?S-S<jUO0|ZMgQX8WSu1nclK7IV&z}dJ
z>3uU%AX5;W@pKv%cB=esLKyF@FX7(@Iv!nbpzuN|)XHZQ@*5EvDrV20VASF+i{W2q
zLx(n@U4NsjICG_PXylZlv5L0#0n(cUx!>fR6kPbbe?DCY#Q~+y)nmzrk`Cy7O07MM
zPa8gwJZT0G;!p=^MNS6370@D;>pmgII>X5KF^|JtY}qZ@$&q6}8+ZHepl$3`Y0`v#
zcI07H=T@NKjlvD5ZyvA9pECAgxw0lK?!0fb&7Hon8X^`jH@FNUKKHWC%p&pU`02g=
zr?@?vVqP)xk8-LcFerEl>WtusQ`D~2=@>yY?5r9oF4oS98wRbkM74LM=S&R=92=-+
zhkdlTdoL>GH}#PCmayoKQHDR_XL)3=;`)o-%*QO8_It4>^E0ZW3IVUC!?K=Dg=<L2
znLfREjpIA{s_h29#+$HZ{EN=rtAURbIJZn4ZY|P|<X#kw6Vf+$C14L9*8lFOVPX(8
z4PP!5QklIWn@0Vb<e<PNHydYp+|c{Ukw6R0IpeQ&t=`qIkK`1;q@?>MB!tg1U&i^?
z3bSd#<A9<isy<o7XGZJB*=oZvuIttCyT`+;cawfgc86YkFB&CeXn{7>@gBUJbB)MY
z<Nuu~J^GZQYXyIcdiw<<miam=zMetQo9vKg(_l5MbK3~XYCPQyzbtz?m6JEvTrwbN
zb-rUR%b8lkc~ir(w)4J`VhYm5IJxZFnDL2C10%;f=dE4Y1?(%f7FRs>4Q4SOlU$#Q
z2M#13dt}3xWUBf9H1^$LO)X!$lZ28`Lk~p=MXE?uK!JqbyGm2KT>-@sX-Ob-6cA~G
z3Lda4pdczGp$MobC<@ph6e-dIsDzU28$8F~cfaR;_ui8y&;BEMl0AE7t(o_oHSb#X
zUUQ`)#e5z8HoDa1p_J8isF7DCP~{PQcuyL!HVk&oun<$zEdFT+@}d_XHX9)t^6NVr
zDwRCYT5&3697pwMi=G!nTFqFa-5=O5Ts4B$A%OBn2z>pVD<M%8goZ`yUXT(v5tbeP
ze(Oi%i5X>j7@``VxfP&h&wD)2gS2829nz;O?ed9?;6;fJy%$5+hgq$AFd$lXPufSB
ziRnHpKQ|i)*s6tT<hA|OnIEFYb5=d}GlA$z+Frc`Q0z3pLpcL^hbe?eUYGM>LnOYo
z;B_U*OM&=(+`cm*BtO1O78a`_N2L(9h<uFE+seO|v?DQYMICBsO<DZN;NaE{T@3)+
zCK=*R=OS!*7qaWRcO!hg_|iCpyBDGwyFd<%Q)3Y$Zk)+yJ@lD)`U;WQlH5iPOCj;w
zkuZvwl!`IgTIODgtGQUSE(+N4f=;|O%<_zR!^<Tzi@O3qL6-hv#`>84+85Ft$w!(e
zme!ks715-eNZ7F+7<|V?%K(S^KsM0646vShIvy&rwRXq?(v3Y9@80C~oxPdpHpJyr
zMIq?H@T7yHK*+YFWplydEH4~%!Z6j*?_Hz4UbX!`m81j_+D%E3NIE>#M*YWO)rQ<N
z&m!w{(iO;DJTxi%A$~lJ4nG#Eb8o7Rq1rQy4)l7)x#_NlSj>!ZZ2;hv!OcqEQFWLH
zqL^^QtHowvyPq*t_T3Udss%hF{h_qE|F<Al?!OLlxhhUMz%Kn$s=a^X!XYGVNru%Q
zth@~6b|5!#GqM*FIW%2M<fS8r&A_zw^+Og9&N_sz2^&nI6)`vG5Aj(H?zLta3iDo1
z_O%Sl)sTl0{@Nw^@rcc*^WNl?d-^=E;@1~bbJ$Sy<|j7h2pYd_ie$tJYK=&$0-EOE
zr6uIagpv<Qt%t`Y)^xecy>FjhBvV)ODD&(<j#rIP|7qT089fTGX=w}+eiHpB;ixwS
z3prt51V`k6s4o8gZOi%#)z^;!cz>lviHzFZLn{1vmzToL8Itxzo*j=$zPvsE6;CL3
zms1O!Z&bSw!bPDBBgJI1>jG`;Vw-~m{kanNTYe#a7P0dSzE5e+ira1`J)alRTio?K
zrM!xx4=9%4zj@&q+DB{U?Akc(siQoq^wNtYR8<69nY}Tyc5ql@g$j=caeR^3&(hts
zxe$K~2KemSc27WaRBD2**2ts6c=ng4seIp?jt<p9x)&Cp7SB-~k^~n~`-bFc<VNm{
z5$Z6N>Bi~(fOYB`T5^+A3VMjn<$h<@^43R_Bs%v)i;&K<#%~V7XUyFqwLhG3FR%0~
z5+-(}zfw4HW@*m1F?su!(C(q{I<xb&RMz9y5wRj%?;<=l6Pw?Aey}QlZv<(6ZuBSh
zfC7|bfeM0|7#N>iCzUJ2m4f)5+Ozc$&;&?zP;U74D{ZRu`2nRD6^{shFoM$Is<=5I
zyx;f@3_E2t?~!>|(T4d88oZlQvF|N3_~YK;tMBbtUwn2vqjb%zcGLY)#mDAdV~J~f
zxn;UMLO<0BWd->;6Xy@t4_)uG#e9w4H%|`O`rsn8EMUAr(fa>3yP0=9uY`xy0B`28
z<Ga~2&!J^-*ia~V*W1kXDlx;HJ!e<gY&`JHLiMY^N!-XnY=Q;GJhal28`%-Gg~b3+
zK<cU1d3n4n`1$x;yUELyV9VmMcLVpdcIvLJPWZzbo+QL#fPsClSc#HRHx>Z2*uq~z
zM}3Pt+}1HxY(8_2>$Gsl*@k;W7!B?S4MJqkH2Rehhv|2YOHuU}7wmuCkXsp)|Gn*V
zUUP2-TRj_0kYrQ@zxY}Ouac@x+{(C^v0We)I^?>B>2arC#1{BLpl8)MR4m|E^7N4h
zPpq}54g5@SVEbU&_KWeESOFe*P}}U83|O=PDdYKb<=Lyq7ppQqi<a-)?SBGprN2qb
zBEUqBYt(#;v}nj4xdS!B42fUP?JA>&ez+7yp?qCeiolDnFv@5!o<nL~)tc|`yI^%`
z@D|yE-KKXuMR4=<t+vl6`kZtit74WK6T5OjRqHPehr&7eOYqQ=^Umvgp@^%5-;v45
zzlHwok>K^?6&ISwG!23pNT|nIxR#GJuFsNRxT1Sb0>`6=jY{!1V@@4HxZT?J>XJ5Y
z2p_=XqiDD<Bf~uus<F65F?^cQvVA9X<WeaxQ2|^aH;|Q_nxZE)vg$8YR>Jq<`NK`n
zF1gXbYG}GS5%6{$Zg$Oc-GgJN1iy8tmAGGxGNFIDuaCCYv%5Pex=s0Jukm#zFjn`^
zPncC(3uFlx1CzWfxIMOBr`P4loAS(Gp4!f$(qOHcyS|%G9IVqAiDI~hm9cbhY{7$F
zBJGxXdU}|?<|%nzY3qTfmc%ARh~bf=D-gtFh#M$2h8<H_L#+zQ0XfT%BR54H=ZYX+
zQ&%F6$e^a{E;&H0<E_deOVgV<YaWn`3VEh~sptan9mzQ==k~RXq1o*UF6Kxqpu5+Z
z!C9Nt7dKJ@qYo<j50;0R)OVW`adds60P`=e?jPkI4P2Ty)#+^w_nMOB0D9AoUEdYf
zp6bwB0XHd0k?&huTd>NH6dOv+<L$eK=BsGj$yw%Ng#Zl%c;wdR8<x7w*XB(jhyfTN
zs7o;erlow!mRqXf7Lb<a={zZ*T=Z5IAymqlkgPV~vL}B323+=d7W<>nCKd2XXS>yg
zM;6zd>Zfzas3->bP})AYD&>9U*hskTi`S<)MxX$qF3Mcj%GLW~rjFv<<7hK7u@>v>
zs{DF6BuA<(lMV_CZ)yq5`5ukR2a;Snr*?m-a(yMKwRQq-E1iBoDfajfi;mg-GX5mB
z)2hyj!6ozRa^334d2|6pg9UM=ni78t^dg7Sbytaum34sTlb@*K|8eQBS1H@C;jcY!
zCBX&8v|`?8+8ISMk-Oqu`i`FSjl~23($u?~?$Fm4#9$I!*H%3LR;##u%`Ok=CTmY6
z9gIEj0XguFbw|~^(SRR_VtpJ#c5n0VF$G(IJvo%EEwww20880A_rpq})n~BHikE&Z
zhXlvQkPFNAXWVbQt-ENg>Kv+!dTGal;Sh^xh8FD)vEX#$za$pvusb<HS~LrKhE$>6
zvf_e}I0hJJ?iA?I5+*a7^9y;l`>)W>4T^;`R7}bv%-WTG6khpKq$?ZgI>}rJh_Qs&
zD~r(=6l>TPKX|aFYamn<1Fc_1?g6?9U^v|!9WNOliO5dZrdAC5Mop;+5E=b^(0`5<
zA&f|31`=AEiq13~e8p+aFAm(lV?(M$&FpdD0^FJ^jnhLs@~;xt3!9`qb1_OEVG%vw
zK1D0cqs6y$U>VAX&eCk^@o3c;+r3YR*k!u6<Ro6cpThrFo&hXu5+Pi?)-4@K;~m&U
zQ4)t=h>PNWG(8~@i(|&|b_>K6HdbW1=iGv<SLXm<Xu&?E(IJS;07+*GyRKa*^=>G7
z>JKr78zX$J6kc_-exq@>U`+#QqB#4YD6oUa$9-0*3*T^CJ*3lQ<n4l%M^1iD_xhl1
z_D6?rc8k#SnuFEZF5a^bb9sgjr{h=~>i<x&N{1i-uwt!+W7cl<)D`-7j`c5Ypmfei
zv{x_50t-QB&rRoVC+wBW$<1FR>*5=@KXNG*2}AX%5D)6qZ!x|l7Tzn+75Tyq<<R{B
zU2OC`xWB}H)5wR1sV)4j40?XM6o!($qNrjnqGDf)w<7UUaN(})zpSYQ@tNEk=D2#=
zrTt?gS=2Q~eGZp}eUN?|3MmOBMO-qDj{fA3^D7t63TJ&`%BZRAJ8)_NTCL3NbK%*L
z^IPL##ny#GWg=e<zf#I21Z^uZsFYn*h*9htF&FGR<c6AmHzi*P1CjO&>_K+682jla
zI$*z6G7&K@SR9*3o~CEFSW4s#E9o9kKwDtpd#<{~5Q%VDee~+l6Ral2Ewh4s>RB<C
zQ#C1t%CsIG8oVoM_H3l;RYl@w#BPeM>#d2(xHyI@W&y`mU;>7J?z!^HacDRbGF8h6
z1d@E75u#4Qui0P=mz!^Bb2in8&GEID`}zXR<(pUx$A$ntymK(=+H}bqZ92SpZr}Hh
zhgUdr@r%z|=AG00)X7+fzq|r}Ld}zEhxf1AT!ZNRs^?vZ{ZJq^R#Yd*17?x*A`Aw2
zv%>{x58)&OQ4FdSwqPJ?nxQZ>&j#`f+EbUDBdAosUHy_h`L%MHpzNm9H%@$mu=Oyy
zF=BKxaP229ZbSLFX9FIW`|vSr8v=OH($dZ9d-<^URIxzwBus78Q{;+D4C7$i719>f
z+qwFxc@PWma|KJE-qWs;GF{1l1#OWsckgqOAyV(qEWx9M-P8SCUn9+FfAICjKVt}6
zN&kO*?WXwMV*_9R1~tDy_6F?w?*O|P`dG}zM+f=X+56)T9rpI8s#LYLMUbY8#?{NC
z-b}C-G?UyjNnBe(kqYAd(aM4Bu@5Q3OcwwTo_r&#-)j$~+>h9|eRnYbF47eKP&g+-
zF||K7Ho$q^(g8ygxEVs?*OZPg+Sr}kNN_Oyd)MCO=!qNV48$I<T!nRU;UGj#rgTA&
z|M{0BfyG<(FQEzd0`zq%Zhoq?ZYyuZVG>!!J!1H}yB)<~tmSp?qn~T^1|UCND1OPU
z1bti-Ma5(X)USiR`a(+$F~aw%>+we^UVITkJ{j7$PtCWK#Q6AgdQ;>3Q)r=$v|%2s
z$J3Q^_=$`nook)89|aN{=H**w48uPZrW<q*cbUK9nRP-N3B5}*;5t(`X23U~DM=9~
zE+{N+9Hva;0PNe=e*iZ30S>0Xpq;kpw{E<3Unu~-Rs}~XHTKjem~AAqPC*SQd}A>y
znNcl7h`PEwJp}QDI{SdrTvL|iWVFkrTKE|r<^7I|Vdh3Zjn-Njw?PJD+oq)zyr+fE
zpnF<gH|a-T15n=4{G`?!w965gU!jak!X)9sP3`(}Fe`<<%^RVR-(x%UD8}G8s<0gk
zL;u>DCb<TU;$O%gyK65)gd2g&l`kiWqk<Q3ha4|euHjLXg*k)%r8#H7os$3L<Q;v?
zl_<GR;+n<x(n3w7lJIu#p;O~)df~^lyR0^8Toq2t{uL8{us;&)Z7tZ9)3XfG31Bla
z=cV>3(M3PDUY5P%rJ5-3KrkRN^1XU9#Fmq$N0E52-2v#uf1o}Dt>GI)#&838K&GW*
zZiZedrro=ELXE5|g3Wl6aBj@RGZOVU4^(#|FKl{^l~dVKnz?;7SA;QF&`YqBxr;nZ
ze?*?^H|wxt#SIHH)i)A&8FC=<hJ{BMwOj;nWql<B10`jB4mjErB(hmN@RLSzXVHEi
z{VfGJw?WvLsfN>0@n^|U<nl&qendQydZgDb!ykFz?X^B)KOXjd#{B#gM4)xP@g%p5
zS5>_JOhPc+AGMZXLJzzkG6fl;P66GW%en)jKZ>?`vsha(&L2y##3kKvU16woC{sr{
zZPviY(dm?~Sjnz#WO2(iWUv(-%m#6baFDP4V=7y?D|P=Vy&OBo?CjQV(}Ta8anx0L
z)mHtWIPj7(p1gi|L;RibQjB}ic1(R43Vys5{v!yzQ}ZVKxcasdfc*k^e@+4{e^GbE
zAritVjs~zcPYt_-dhqw_0N3vV1dAD70}q1SEtX48H&Za}%g~edLz+DmjhoJY4O8qn
zH)l);9m)MLtG<1|2^Z@_RMSkO0cO96-QA)8RL^@(pm=e&^s2&ZJhuD8c;vpktq5ha
z2pI7?RF@{kG7DKe<yNj}N#j*}2%7x@!&gZ+D&!XxoxGzv*^_<XhWm=Nk`H?ojM;9p
zl2vaik6ke56A)juViZ*Yg6j4|&6j^{wjnYIN<dg@fLrNURR271aMjn*JM3Mtd$`+l
zh(S%;u25kvrYF#=KteR@J+c+(FVob5p8VG@rY5>y4PQeaBDy*ImZCJ;ZN{}Vf81%Z
zGHe4SSJf;h@85&UQUE`L|0zLizI^yIdu5_~V!rT;_fL)!Q#L^9rN2Sx_&RSpnGXZd
zziWh4|9X?$PR^f70SGJ?!pj(DV(Oao*54Q66*E_EJ3CA@Y0742my&4kb?y&L)ggxj
zBNp&Ykh;6=P}k4!SBJ2Oi`DsaTg#-w9ulry>z;%8cDbTwE9seo8c-`Fa^YdCaaNw>
ztWXe?HEbvcM3qH+h4!nz@O&p-ThsM-no0w7RCh77+;ZI*Fgi&BMjB1rre<dyfvG+g
zA^0+a>?XYL9n4KG+61or^ppKvh$-&|Cz-tJAOKYnn^1QLhZA$^j{(A8uTsNSWPL0V
zmIADU#os(vHh6XiA%w(12OMLqB4>e6rnUdm6=~xc;rw&Pj+T8Uy0O2L2UugzKe=7)
zERl>L0a7+V+f+OOlN8HC2`6{lRo7h#Uq(U{Dp_#qE$XHI$dR(grbWoV(AOEoO6GX(
zvh0&wdo#ick9{rOU|aA(>)K<i?^bM{;IA|E#FL4}yZszgo`m;co461CLA96uEvkj_
z!0z<^&q)BHxr67iWj!%s=w$?}6IhE4l^?W2jlIV@;(lBj&u1U!FVESZgT}WI5HTf{
z)s$+4`;UC$j_|eNvmXd2cCtu#M6UUtL;$V)bw^@}=l<C%Hx7k<`n1wug(Z6*irZH%
zTYpNSA=>_WVQ;8KY<_1~rJsEPoG-R6B5@xQp5)GN5&p@xf*b4z)_#0U0SmTLEsbG~
zvy-T2E#zAZ_W$GoXf0l2Tg%VDqJy^h$JuWh@O@MHAy$ERN=#~c09hy_I(BDI(_4|<
z&bU=*^Tg_v@pXRh(<Mi3DxkB})D;fOgynJ&^<9^Z4Rn8OSYo*@P?1kLQ91H0wd9sq
z?H$~QW!_(CH}`}7@aLz;6WcUkO73+|ry=5bW)x~eQS!r#%NtmUeWMzG4}%3a9mTT;
z-qy`4Tw&FLdy2!BC%e)6TR-u#Cez6JMFmsiSL2LpdGpWvn2IRnnZ-7@FY_pz+`0L3
zkj9S5UXPw}l}xj2;!yR4Js*YC$blPDdA;UNl6o??obIqs5lOHp?S#X?jGcYtQ!xv)
zb#^vEhR4zp!Hu60eYLHAX9SZwUCi~H>e<!0l$Ui3Y{u2;;^>2C%MxSVbGAQby$KK&
zd%dY0z`0)nI6NZei-JMPP6_KLx7Aobl8#oUJzEZXW6XQP&cVhkV&ActY2^O?{=O#a
zz~6fJjQ{A}HU8+`gZ|OGPyfI4?w?dTax3F1U^$is#$T%x+;*dJkvP?%z{UX)Rk--x
z!SnmWZbnR9bL)~AOLKtMsK{7x4mf}-Z@_(yiME$T$#P{CL+I|_x7Gz|MA!qbvJ?nn
z@tBqn8P@^!)Fw@egO;f8(R+3@<3*$g6}qRu0FRU_;Ff6ZI=D(e*{Rgb8zH(+b|7U4
zGI@M-S$#Y2zuX{&!m}iy&NER5E3+6|4;&74|34Jx2R9VwOOXd-m-oG6r0y0Lmq_Fh
zN<slHXM@cjTU=Lhh!g#N4YyRU$mrV=#Kb`V(@CGZ-E*Y-wwq*)?pKwtVmYhQ4=ER{
zm8hs(QbO<nlHfVtya_0pDWlUve;G>NKS8bf&J{fuw)2p5d@v%ck>{cj+Z9OLq<v%m
zZ!&ezYb$vZ`w&_k;cwZhxzvQ$4l$opHHw*vO7H8xx}j1}kTz7CO&Q(US%G~I%{C^#
z+Ul4!I9OGt;xNHlk<@%^G@4c^BoZLO57)IuS_aYVbwwkA?$caDCDFchhB?VoN9u?M
z2UN_ud?5&L-s>h7EFOWN>F-fo+u~72E8Tigk&={^Txf!z-6V0f-}x3WH}_cB9+kf5
zs*@CMZ5^mv9kjlEUR9zIT3un_F&m0uhM}PE^0ALYF|*7bUHC;5+*lA!L#zYS_P9aK
zCN{%0X6Dhy7>2`Zwc9^_F4B_-d(SJrf?-h>>T;2n89rx*`aX9Lk%2h>X|L0av{Zl#
zb16{&ylg7qZ0R|#e0G}E#9G?m2OS&ypyv1XIl6(a+}z9ErVF-zG&G#q74kSSp-s&G
zpb@52I`T-Pj7I8;E6$!9NDk{&&|#x{Pc}48-(4ANJ=b5!pOb?UAgA(}N>l8H(O6Uh
zf9{UjDNdK*n84&oFLXou&a=!xN$*9~*H@O5Lr(3~b8QnjJD*@P-7=Y4Xe^!B9Q44{
zy&OooJioHy*2RLp(%;M1yb3yR76bF1zS7IO<!_5ZS{nGO_OGHW6?c6TMK=(K?r{U1
zAufg4=w;gdKZK;_UvK!66{mgwhYkM)LaP5CMluftD{+;HWCQzciWFyd&t4bt9YEG0
z`Da2@z;g=UvAwOHHa}M(I=W)c?gRM=zAb=7$+?guOAS(gd|ITo(;xRJ69wb(^o*K7
zyYcSplL@AYEh+RGH(D?sVDdajt4Q^)14AR&eST*axsSise!h<^FO>n{UdT^|CUltT
z4%%gJsrxz<L|vKEFOh*)^SpBeSZ$vOvDEl(+qDkc_#{pv1GG5a{QKCQM%nf1-ky0~
z(q#`1g#)H<*7T&eDeKxomo5C|%y#*JZ`Z!spGocLcv)x6HiK=;DJzd-@AEB0F3Z8T
z3tJ{Rr%cv3xZ$fSo;qN6%`cB%5h`>#J|@YH($BAC=Nov1RCT1xb@P-~M5~@NjfsWN
z7~rlI?z0nPnv^;R&EhF`yiG!|UV*Dg6&W-$-6KvpWxIz6_PGwnDju-AG&c42Sw8)x
z(t4V4<u();1EoUwoIx1iP?-B+e<+NnB1zz;YsrB+WJvm10|~MDWmbwz{lu?`nGpf9
zSc2N*^$%iM%PDJIxP?H*+X-kG2Mw`ee$GP)pooHp(K6|`{T~wA3T3YXUT(V=wfeFr
zpPv1M!e6gO#mt^BSMvU?=cgO*K5~yY%KiHB?&an}fU75=tQ(^&vnk5fcjRBk3W9r?
zBr8j%o8XNO91jMpkiUc~(!}+Cc5UznXhR*uS~KD~y0Slvq-z$)idVpRV4h0;)zjX5
zZzlRz3`+GRd1<sb;SwvU&0n$_cIfdF1m)e$xwv{~QjNW5RYq1w(byG1hiP#SKBdDX
z_|<4jdE^nH(sSurAsWqQRrCl8y#StZH60r1hGO)tNik^6qBF*fYB2qTOAxkTT(jxc
z<)P*T9v-V06R(Hd=GRQ6=?IkLx#d0L@tM+F-IdQQ!5^#sK9v^uw;4Zjv);yJtXPEQ
zX=tfm2<(SXC;XW4W1od7X&6i^4)YCl%a=%=JIv?fKqmS5)QxzP=waH&-d(O|g&zvv
z)9mCh&u+4+E%vn|grFg>g#Ps6>$r({>x#|0CrIa&on0eShfGQFhQY6o8fa=jiAZ9z
z-Np)Zg~Nz8Tr9$9guAeWXRz7@dNQ5lKoVZ0@wiPOO&Viq&&nUeXqG3kOsmC3KK+Rx
zjLn=$YM%K5)bbvMZFxWf4V0T}_KN$jtj(SyXYF?Hjn#93ekxMW67+Eo+dJYj^PWQH
z--Mh9Dq4X<y}CeDa<it%cU$XQW?uG?dG90`4ZxFhDjEl5Pkf^UJjV2|3=rhET;`Hc
z9xv87u^WG5u#yB_%yy|;WgICT?w~`bJU{n+f+%g%@h|4VT;h1O=Z2PA*FOEat)+GM
zG&*VK<Hxk%Gfa&m#))UFKFlMF2V{@#PY5N!#n7*bvU{>x9fZ3EjXc+Ov&v{N`oPz_
zyhkr4NkKz`LXr<de8xBPZ;AL#x5Cd0{P6M@ITqgkw3MM9{hDd=@sPxmT{GGx-n<O}
zekRo;PH@q@>BIDAs4paZ_g-bQ*DN*<i*&Um;aJ8R;&HvL6*1m#7hU9=mq0S)#TP%b
z_1#c&k4fiNOaIp|g~(of)TE_?V%Rx3iHri{`Z)B-r`zwHo}cGR<Uet$*(3MnFM*Kt
zHtQSNNmFFEG(loLZ?U?T>~|<UIX&09nTea{rMMi8!N-e<y=?$@bX5cJ{lq4co*hc@
z%Sek~6^JKo8KVb2NKAp4I6;9OM^8HrT0)6j!#e>NazZaNs$^X6LKG4DyYjco3+k(N
z(*_me7md$1HzoBVmh`1JITI4g!rh~~aqBu0MxTZb7`yjyHR@tys#-jWlj5K70&=N}
zQ*j`Q@YQM7I}rb$&Xk3kyK&v!!`Jj0(-J@Vv_>9^tj*mLB}yq?R}iFgdz5Z><+PP8
zOychpD?NSbM2M$Zz=$#>drm7jB0#`&X<}l7dRcBzufD&j*Nx$<g0{;5c__Ho|Blae
zXy~z~-}NQ)sg_fuD#$=F=Y7Y(DecUJw(it%#?YlM0rS3f)gYL!Gfe>5yLktTUT}kl
zr%Si?+FFY_2pY2xUcL&(7oO!E_g+phU0I1m%g#pBmRW5)gVWT=r?D~{Xt~uY>0V*J
zN!qu9VNM4d^1SGjnTLjyE{Iw^xu4WX-~qfY^06#pGpbfH<-Ktk1~m9oXghSK%*VsG
zTRTVeWP0O46KsDte{E0D6^M5fYsm_~?O)PJTMyB&JubQDcI3w`F8C#4I=w-Y^iP6i
z_(veRrIHr7NzO`7JrMeZ2?ALnCj`uXh&yDd$_+7jU|jIlrigW*kYtVLF71*lE84np
zP{HUZ8%XZ31uBDvhhv;4;#mn~90afVL!A2lbvWQX?5@QBK%A1zRpez_5=d}C8aPr=
z3P@XT!b)|Gf7g@6gM5Dyf4)isg1P1PqcdfhT8EC_K&67K<M(ioDM8&|8mXcvH!+HY
zJRyAbK<d)H2v+ldDARN3LnsDR>+So%pz+m3+)>&0d@ICe0zZX4!#OQtVf*{*;qiF+
z$Ekq>DeL0!k(a5mXLh>RAAc=E_!bC@e!M!DR}9tX44wTtysz~ybH@HvCaP4Sug307
z^!cWEuee-h*2YSv%%MT|cK@b9XjDZu9tO54ZLVJ_Ehv;pC(algdr(i1<#&1(I2te4
z68+--w{<;eVGEiDQ>wx8=Nbj6NL-SIC#wVG@!>4UjY}P9z!JXkC!28x6+F?U@pcJ~
zN(+H9w+BI$s~oISs5eYaN%;cw6cJ4~90hQTcyO}nyV54D!`G`WQ(gnEy>f>g>)Eke
zKOeGEv!d|I7Of)~!V)vZxvUwuSv&g?UuD^I_5+1pcZE2H*_-`9iwFIxvhsc$v8uy{
zTUY@l4|K4KF6-id9l0F`SJD5z_VM7rjlGF&ZJzuu<72tFwnXGr84FqqWnRpJGqU3N
z>uzLIg6T-yjUt^&)+xaO*65w_jQ0<hqLWSLn#I{xR|4b|8D5-j+RmXR8wSvxjDzGf
z!++OczqunjO#4t5;KD?|`%2*|AW1l7p2wbQ%vx&YtOtqc?jLxmYB6A|{h|bAD=1>A
z-uHqx;MX3%TTNicjAKX0;|*bU&mk{y>#LQ#aNbwj{2~MMu%^)mhPSM9iEr(VH^sK0
z$Y#2q{8gi0<MpCogFz6DKjKPc)-0a)&C4`iR-$j9-ztu{h%83)h{^#GY-azWNZzY2
zx}zLmRa);tvxj4Xd`@o324^w87h3$RDWTp_{jS3`CmW&LRk^DVV!LT+bhvS}UsZW=
zt&ik4(dE^%bEBq~vvudPC{n$&dv~m9H=bS=E@C`iJM#lNA(6I76$n^;<;1i$FcnJ<
ziR`jvW|}tW4YSG;B!RF<oBI*3mh=)#%tY(-^LS<<$8iickoxoA+711MKy%rb4F<0h
zxO+lLL?)pJ*mqIVqwb<!1-jMHocb-Y)~!G`zxy9l{QTc4JHQ9n%szMnmqLP$)VLAs
zYEepPDNN{oqv-JfJeR17U*af$amkcF=FLUd)Wje+*Zyh?9y07xSe{(Bu(|HQrmlb8
zBdcdvM+e`9ZxOC0O9(T-4cp+T>@mgqKx-k->z>h#Ljw+O0*<|-Yk)8R(sViY87tx_
z7OV9howD4wHOz8Qb<^<c;VjW+q@n=Xy5#^L4MC<nE%(JaC0s3a76vms!K(09^ZI>(
z#74ydg8lR=LGX!qXda5!=@Y3lwPUawk4kTC5kq4F+_%Z^cUvNK8~(022OF(E#mBf-
zN3qH70Vj`*lQcAzSlfo6VLJ2m<a(mSk#Vc#Mks}u7PQu}KD5rm+_ej+N)!k!pzP+W
z78Ct3#|}qN7zP0e@I*v=K@u_cW-I!fVljm9A};I<-c94iNF;jxq~ikPflx@8R*H_z
zi)7sAscV&~4F_~$MK81;qk9NH2&%i*zdmeV1yU+kn^ICB64#Sl?;Y94{0}@ju39$}
z1S5ZoJwxI9`ekR<7kGKoX;Eb{=-L4qNPa{+m6`z!Zr3_Eq*V4hn&_PPASZGdB9m+2
z`4`WS?w(^O!)KP0-4E|#<p`Y7c`&<4OxJ;Mi<Q;z_}f{C897fiY3gG#m{&dlHvP-_
zEzlDFB+S9mcT0_+_fHsBl&m7E@6){b0+%fHh)&}-Ok=g!da1Zt17fq^r&0mo)!|!5
zyq>;{ZulKcXL1~Q!&DAaIex6nS!hLC*+`31Jxz;-yN#gf1bHC!P<HRGh^;J$UhuZe
z7)@+(G{D1!^?NIKaHk&gyJFvOEP@;p^2;=ZV~|%XO~*zZE2kmDftEc7)*Z00c>EjN
zIm&ZyAUx9e5H1l{i>NIW|2QFY^76pm_Zj_lDZH?cK_Bx!tWPOAPH0vYyy3ERlX^^l
z_`Px{+foCf($bR=A}s{afb@P^^RliUVgr7frOE7#-3`~Em0`Lj9!cxJXE(3n2>s9-
zjIdqvpKYO#_|mp|4Um7!uhs_)1gUGC#u=RlTkiM&v?IYT133Jn%w^&%)8(`5ht^$F
z*E5)#O1T?f3cWA2h#QI!eph<!209{cDLrp=bdf=(vb!SxqQk44Qk>Gyg_{MC@00e)
zwyyZjSAp1$w7aXRmC$;z%>9+ifjW#Iz^saY{0aM1%<TMm_d(R_8JF6Owg*7qqlg~W
zO8FTadG35ydXZaWV#i9c(W4<~jol(28g*TDVz5Wi_|i6w(7Yec&SJ70vVbZ@^n$Yj
zW2XG*xF~#~q!^?Wu5*T6YKXwd%VS`4d)~6A^;x`h=7PDrQEhr3j;j;6^5qqbRR=<a
zy4$%09$b9WNHquIVN#9>6|yBm?12Hkv8qP*WyoP9WFx`(DrYL%DTS{T`uld^b$0Hh
z#?0qhk?3<z*1zBV2pxXB;>0Kcdr*;6C)~6<?sDh=Sw-*|d~#6XO?O=5!ky1-c~wG|
zu<WPjv!en)N^j%{yW9qP5Ysilnx2KoaN!dxAH0b3K}_(2wyD)b7~ZC^m!?$WDCkI-
zP!FCcF<DtR>k0=X<x2&ob=dEhy8_;=tC97BrWIKWX)Fft!_=A`x>Fb!!PHgdra+y=
z8DFUlQl?7;MS=h+2<r~YlRH{&zw)TJpu>Wx%?hGsD{N$Ei0&8hyN-9l``2C!!?4E2
zg4v$yK-55_$R_+&(zZK9h`doMj-NB5Zah6Kh5k$tAn=Fe{@WG%`-*29@{nnYuD8A3
z9V$$faiEJEdR6WITBVyy(}-RVU1;^Y#vY2OyijXiGwluijEjpqeU~{r5eVIh=pMc4
z6>tg~VZU}@yc=!5MY3X^ELgzex2hl!ZDc?g2oio?YigGvie!E^w7KT(G~s}$u~J+6
zW_fkf7jdj@k~dA0kFVy5m!IjgS#EBTa$u;L6v!1iN(V0R;;?s(!)My<G1<C*UPhWc
zJUm8w^FR>i6@sVH+MCH_a*na?_xaBj^G@53V;{dJ{2cAi3b_1pv^S>iM)8hm+Ue<z
z8^!*<F?<~fO1N_;!R8qes?Iz8!8)_dR_cC<9ZgD~%NSzR`em2gU-4~|EkROeJz$-|
zvq#a}3wKPfUJ<T;WSPFSt$IOTGrii=;mAc4{N8SK&qIeJ51EQgVOl(bp^$Rk1Ees%
z>5Sk>d+pJ@X>hPmMN`N)LdcR-5m{C|Dgol|9_y_G(V6BS9v}WpGNUQ-Z+vz<(l{GR
YO}W)N>wlEoma=Zm`QrZ^r+;z%Ur|t1<NyEw
new file mode 100644
--- /dev/null
+++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-video2.m4s^headers^
@@ -0,0 +1,1 @@
+Cache-Control: no-store
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b1a2d44058f1c093c0ba448a721b558a541ce216
GIT binary patch
literal 1410
zc$}?L&1(}u6rb6otzU<gt`IemRVppWhNO1YW2An>k3vDrK`UjOnQfNtWS5!AwtCY4
zp#B9OrT>6<5j=SCDhM7#QM`Ec>Z!h+Y{(={f`X5oeeXB#&71e$ZxBL7Up|fl5xEE<
z>?O@=Y7<Yi03Y%>rJ!%8`j&`RC<#3KMi5eal}Du0q{QA1WXry}dUe^Zl-=^8bM1P=
z;WVjMTxXNeCHEq|>@ZJA$|2E|#iA$yBV<X7paIGKR0^xFFL*F&7}wB5$-&xT3Ecs0
zGMe3adixRlZOPSsFDtC0ueCdLztP>z>$y$v$J%)vL%cC9xwi%On%q+NrnR6CFG{~h
zboEdD8c$*Sn}QWeqyW7@Lm{<V*Y`mN&MF&o1`MXXF)}oNyuO>N`|lKTS|sE>R}v7a
zhc*C5b+1iAMJg__pzVWUB}^sNubm@ZUy*R?Yo#3P@X*feFG6mFpq~pVh!*oKeU4+s
z0z-fi)WN8ai#Q+!7zsibAnP(-sh!#Xj;wjmdj)Ie75Z4npZa{{)0<x=M)`%Whu=e}
zDWsZiPXLRihAqHPhAx4aX4HrH?Sxlgj3^T0QO!(#^>f)PC~B{uf1;c4%2?)6<6Qb5
z#k`0*Z9VcHVA5wE{m7U%1sh2EH>|(RSbsRg`W+T8c?X&>kl8O4%~L@XF}aiA$sezs
zP}{T3bWItvyVKY}|Ajxa(IGM|=K-U#SJqj5Mle_I#c`-7ae^)p=l5ikCMyw79ajC^
P^%CE`RIa+^YGv^c$=AL=
new file mode 100644
--- /dev/null
+++ b/dom/media/mediasource/test/bipbop/bipbop_480_624kbps-videoinit.mp4^headers^
@@ -0,0 +1,1 @@
+Cache-Control: no-store
--- a/dom/media/mediasource/test/mediasource.js
+++ b/dom/media/mediasource/test/mediasource.js
@@ -110,9 +110,22 @@ function fetchAndLoad(sb, prefix, chunks
 //Register timeout function to dump debugging logs.
 SimpleTest.registerTimeoutFunction(function() {
   for (var v of document.getElementsByTagName("video")) {
     v.mozDumpDebugInfo();
   }
   for (var a of document.getElementsByTagName("audio")) {
     a.mozDumpDebugInfo();
   }
-});
\ No newline at end of file
+});
+
+function waitUntilTime(target, targetTime) {
+  return new Promise(function(resolve, reject) {
+    target.addEventListener("waiting", function onwaiting() {
+      info("Got a waiting event at " + target.currentTime);
+      if (target.currentTime >= targetTime) {
+        ok(true, "Reached target time of: " + targetTime);
+        target.removeEventListener("waiting", onwaiting);
+        resolve();
+      }
+    });
+  });
+}
--- a/dom/media/mediasource/test/mochitest.ini
+++ b/dom/media/mediasource/test/mochitest.ini
@@ -35,16 +35,19 @@ support-files =
   bipbop/bipbop12.m4s^headers^ bipbop/bipbop_video12.m4s^headers^
   bipbop/bipbop13.m4s^headers^ bipbop/bipbop_video13.m4s^headers^
   aac20-48000-64000-init.mp4   aac20-48000-64000-init.mp4^headers^
   aac20-48000-64000-1.m4s aac20-48000-64000-1.m4s^headers^
   aac20-48000-64000-2.m4s aac20-48000-64000-2.m4s^headers^
   aac51-48000-128000-init.mp4 aac51-48000-128000-init.mp4^headers^
   aac51-48000-128000-1.m4s aac51-48000-128000-1.m4s^headers^
   aac51-48000-128000-2.m4s aac51-48000-128000-2.m4s^headers^
+  bipbop/bipbop_480_624kbps-videoinit.mp4 bipbop/bipbop_480_624kbps-videoinit.mp4^headers^
+  bipbop/bipbop_480_624kbps-video1.m4s bipbop/bipbop_480_624kbps-video1.m4s^headers^
+  bipbop/bipbop_480_624kbps-video2.m4s bipbop/bipbop_480_624kbps-video2.m4s^headers^
 
 [test_AudioChange_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_BufferedSeek.html]
 [test_BufferedSeek_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_BufferingWait.html]
 skip-if = toolkit == 'android' #timeout android bug 1199531
@@ -55,16 +58,18 @@ skip-if = ((os == "win" && os_version ==
 [test_EndOfStream.html]
 skip-if = (true || toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet only bug 1101187 and bug 1182946
 [test_EndOfStream_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android' || buildapp == 'mulet')) # Not supported on xp and android 2.3
 [test_DurationUpdated.html]
 [test_DurationUpdated_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_FrameSelection.html]
+[test_FrameSelection_mp4.html]
+skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_HaveMetadataUnbufferedSeek.html]
 [test_HaveMetadataUnbufferedSeek_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_LoadedDataFired_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_LoadedMetadataFired.html]
 [test_LoadedMetadataFired_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
@@ -73,16 +78,18 @@ skip-if = ((os == "win" && os_version ==
 [test_MediaSource_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_MediaSource_disabled.html]
 [test_MultipleInitSegments.html]
 [test_MultipleInitSegments_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_PlayEvents.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
+[test_ResumeAfterClearing_mp4.html]
+skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_SeekableAfterEndOfStream.html]
 [test_SeekableAfterEndOfStream_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_SeekableAfterEndOfStreamSplit.html]
 [test_SeekableAfterEndOfStreamSplit_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
 [test_SeekableBeforeEndOfStream.html]
 [test_SeekableBeforeEndOfStream_mp4.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/mediasource/test/test_FrameSelection_mp4.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">
+  <title>MSE: Don't get stuck buffering for too long when we have frames to show</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="mediasource.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test"><script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+// This test loads partial video, plays and waits until playback stalls.
+// It then loads only 3 frames of a video at higher resolution.
+
+var receivedSourceOpen = false;
+runWithMSE(function(ms, v) {
+  ms.addEventListener("sourceopen", function() {
+    ok(true, "Receive a sourceopen event");
+    ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
+    receivedSourceOpen = true;
+    var sb = ms.addSourceBuffer("video/mp4");
+    ok(sb, "Create a SourceBuffer");
+
+    // Log events for debugging.
+    var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
+                  "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
+                  "waiting", "pause", "durationchange", "seeking", "seeked"];
+    function logEvent(e) {
+      var v = e.target;
+      info("got " + e.type + " event");
+    }
+    events.forEach(function(e) {
+      v.addEventListener(e, logEvent, false);
+    });
+
+    sb.addEventListener('error', (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
+    fetchAndLoad(sb, 'bipbop/bipbop', ['init'], '.mp4')
+    .then(function() {
+      var promises = [];
+      promises.push(fetchAndLoad(sb, 'bipbop/bipbop', range(1,3), '.m4s'));
+      promises.push(once(v, "loadeddata"));
+      return Promise.all(promises);
+    }).then(function() {
+      is(sb.buffered.length, 1, "continuous range");
+      v.play();
+      // We have nothing to play, waiting will be fired.
+      return waitUntilTime(v, 1.5);
+    }).then(function() {
+      return fetchAndLoad(sb, 'bipbop/bipbop_480_624kbps-video', ['init'], '.mp4');
+    }).then(function() {
+      sb.timestampOffset = 1.601666; // End of the video track buffered - time of first video sample (0.095).
+      sb.appendWindowEnd = 1.796677; // Only allow room for three extra video frames (we need 3 as this video has b-frames).
+      return fetchAndLoad(sb, 'bipbop/bipbop_480_624kbps-video', ['1'], '.m4s');
+    }).then(function() {
+      ms.endOfStream();
+      var promises = [];
+      promises.push(once(ms, "sourceended"));
+      promises.push(once(v, "playing"));
+      promises.push(once(v, "ended"));
+      return Promise.all(promises);
+    }).then(function() {
+      if(v.width, 640, "has proper width");
+      if(v.height, 480, "has proper height");
+      SimpleTest.finish();
+    });
+  });
+});
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/mediasource/test/test_ResumeAfterClearing_mp4.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">
+  <title>MSE: Don't get stuck buffering for too long when we have frames to show</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="mediasource.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test"><script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var receivedSourceOpen = false;
+runWithMSE(function(ms, v) {
+  ms.addEventListener("sourceopen", function() {
+    ok(true, "Receive a sourceopen event");
+    ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
+    receivedSourceOpen = true;
+    var sb = ms.addSourceBuffer("video/mp4");
+    ok(sb, "Create a SourceBuffer");
+
+    sb.addEventListener('error', (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
+    fetchAndLoad(sb, 'bipbop/bipbop', ['init'], '.mp4')
+    .then(function() {
+      var promises = [];
+      promises.push(fetchAndLoad(sb, 'bipbop/bipbop', range(1,3), '.m4s'));
+      promises.push(once(v, "loadeddata"));
+      return Promise.all(promises);
+    }).then(function() {
+      // clear the entire sourcebuffer.
+      sb.remove(0, 5);
+      return once(sb, "updateend");
+    }).then(function() {
+      v.play();
+      // We have nothing to play, waiting will be fired.
+      return once(v, "waiting");
+    }).then(function() {
+      var promises = [];
+      promises.push(once(v, "playing"));
+      promises.push(fetchAndLoad(sb, 'bipbop/bipbop', range(1,3), '.m4s'));
+      return Promise.all(promises);
+    }).then(function() {
+      ms.endOfStream();
+      var promises = [];
+      promises.push(once(ms, "sourceended"));
+      promises.push(once(v, "ended"));
+      return Promise.all(promises);
+    }).then(SimpleTest.finish.bind(SimpleTest));
+  });
+});
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -103,16 +103,17 @@ EXPORTS += [
     'DOMMediaStream.h',
     'EncodedBufferCache.h',
     'FileBlockCache.h',
     'FlushableTaskQueue.h',
     'FrameStatistics.h',
     'Intervals.h',
     'Latency.h',
     'MediaCache.h',
+    'MediaCallbackID.h',
     'MediaData.h',
     'MediaDataDemuxer.h',
     'MediaDecoder.h',
     'MediaDecoderOwner.h',
     'MediaDecoderReader.h',
     'MediaDecoderStateMachine.h',
     'MediaEventSource.h',
     'MediaFormatReader.h',
@@ -213,16 +214,17 @@ UNIFIED_SOURCES += [
     'DOMMediaStream.cpp',
     'EncodedBufferCache.cpp',
     'FileBlockCache.cpp',
     'FlushableTaskQueue.cpp',
     'GetUserMediaRequest.cpp',
     'GraphDriver.cpp',
     'Latency.cpp',
     'MediaCache.cpp',
+    'MediaCallbackID.cpp',
     'MediaData.cpp',
     'MediaDecoder.cpp',
     'MediaDecoderReader.cpp',
     'MediaDecoderReaderWrapper.cpp',
     'MediaDecoderStateMachine.cpp',
     'MediaDeviceInfo.cpp',
     'MediaDevices.cpp',
     'MediaFormatReader.cpp',
--- a/dom/media/test/test_decode_error.html
+++ b/dom/media/test/test_decode_error.html
@@ -7,16 +7,23 @@
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 var manager = new MediaTestManager;
 
 function startTest(test, token) {
+  var ok = function (condition, name) {
+    SimpleTest.ok(condition, test.name + ": " + name);
+  }
+  var is = function (a, b, name) {
+    SimpleTest.is(a, b, test.name + ": " + name);
+  }
+
   var v = document.createElement("video");
   manager.started(token);
   v.addEventListener("error", function (event) {
     var el = event.currentTarget;
     is(event.type, "error", "Expected event of type 'error'");
     ok(el.error, "Element 'error' attr expected to have a value");
     ok(el.error instanceof MediaError, "Element 'error' attr expected to be MediaError");
     is(el.error.code, MediaError.MEDIA_ERR_DECODE, "Expected a decode error");
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -41,17 +41,16 @@ DIRS += ['interfaces/' + i for i in inte
 
 DIRS += [
     'animation',
     'apps',
     'base',
     'bluetooth',
     'activities',
     'archivereader',
-    'requestsync',
     'bindings',
     'battery',
     'browser-element',
     'cache',
     'canvas',
     'cellbroadcast',
     'contacts',
     'crypto',
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -284,17 +284,18 @@ public:
 };
 
 class GetPermissionRunnable final : public WorkerMainThreadRunnable
 {
   NotificationPermission mPermission;
 
 public:
   explicit GetPermissionRunnable(WorkerPrivate* aWorker)
-    : WorkerMainThreadRunnable(aWorker)
+    : WorkerMainThreadRunnable(aWorker,
+                               NS_LITERAL_CSTRING("Notification :: Get Permission"))
     , mPermission(NotificationPermission::Denied)
   { }
 
   bool
   MainThreadRun() override
   {
     ErrorResult result;
     mPermission =
@@ -2443,17 +2444,18 @@ NotificationFeature::NotificationFeature
 class CloseNotificationRunnable final
   : public WorkerMainThreadRunnable
 {
   Notification* mNotification;
   bool mHadObserver;
 
   public:
   explicit CloseNotificationRunnable(Notification* aNotification)
-    : WorkerMainThreadRunnable(aNotification->mWorkerPrivate)
+    : WorkerMainThreadRunnable(aNotification->mWorkerPrivate,
+                               NS_LITERAL_CSTRING("Notification :: Close Notification"))
     , mNotification(aNotification)
     , mHadObserver(false)
   {}
 
   bool
   MainThreadRun() override
   {
     if (mNotification->mObserver) {
@@ -2550,17 +2552,18 @@ Notification::UnregisterFeature()
  */
 class CheckLoadRunnable final : public WorkerMainThreadRunnable
 {
   nsresult mRv;
   nsCString mScope;
 
 public:
   explicit CheckLoadRunnable(WorkerPrivate* aWorker, const nsACString& aScope)
-    : WorkerMainThreadRunnable(aWorker)
+    : WorkerMainThreadRunnable(aWorker,
+                               NS_LITERAL_CSTRING("Notification :: Check Load"))
     , mRv(NS_ERROR_DOM_SECURITY_ERR)
     , mScope(aScope)
   { }
 
   bool
   MainThreadRun() override
   {
     nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -332,25 +332,24 @@ nsPluginInstanceOwner::UpdateScrollState
   nsresult rv = mInstance->UpdateScrollState(aIsScrolling);
   return NS_SUCCEEDED(rv);
 #else
   return false;
 #endif
 }
 
 nsPluginInstanceOwner::nsPluginInstanceOwner()
+  : mPluginWindow(nullptr)
 {
   // create nsPluginNativeWindow object, it is derived from NPWindow
   // struct and allows to manipulate native window procedure
   nsCOMPtr<nsIPluginHost> pluginHostCOM = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
   mPluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
   if (mPluginHost)
     mPluginHost->NewPluginNativeWindow(&mPluginWindow);
-  else
-    mPluginWindow = nullptr;
 
   mPluginFrame = nullptr;
   mWidgetCreationComplete = false;
 #ifdef XP_MACOSX
   mSentInitialTopLevelWindowEvent = false;
   mLastWindowIsActive = false;
   mLastContentFocused = false;
   mLastScaleFactor = 1.0;
--- a/dom/push/PushNotifier.cpp
+++ b/dom/push/PushNotifier.cpp
@@ -423,20 +423,17 @@ PushMessage::Json(JSContext* aCx,
                   JS::MutableHandle<JS::Value> aResult)
 {
   nsresult rv = EnsureDecodedText();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   ErrorResult error;
   BodyUtil::ConsumeJson(aCx, aResult, mDecodedText, error);
-  if (error.Failed()) {
-    return error.StealNSResult();
-  }
-  return NS_OK;
+  return error.StealNSResult();
 }
 
 NS_IMETHODIMP
 PushMessage::Binary(uint32_t* aDataLen, uint8_t** aData)
 {
   if (!aDataLen || !aData) {
     return NS_ERROR_INVALID_ARG;
   }
new file mode 100644
--- /dev/null
+++ b/dom/push/test/xpcshell/test_observer_data.js
@@ -0,0 +1,40 @@
+'use strict';
+
+var pushNotifier = Cc['@mozilla.org/push/Notifier;1']
+                     .getService(Ci.nsIPushNotifier);
+var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
+
+function run_test() {
+  run_next_test();
+}
+
+add_task(function* test_notifyWithData() {
+  let textData = '{"hello":"world"}';
+  let data = new TextEncoder('utf-8').encode(textData);
+
+  let notifyPromise =
+    promiseObserverNotification(PushServiceComponent.pushTopic);
+  pushNotifier.notifyPushWithData('chrome://notify-test', systemPrincipal,
+    '' /* messageId */, data.length, data);
+
+  let message = (yield notifyPromise).subject.QueryInterface(Ci.nsIPushMessage);
+  deepEqual(message.json(), {
+    hello: 'world',
+  }, 'Should extract JSON values');
+  deepEqual(message.binary(), Array.from(data),
+    'Should extract raw binary data');
+  equal(message.text(), textData, 'Should extract text data');
+});
+
+add_task(function* test_empty_notifyWithData() {
+  let notifyPromise =
+    promiseObserverNotification(PushServiceComponent.pushTopic);
+  pushNotifier.notifyPushWithData('chrome://notify-test', systemPrincipal,
+    '' /* messageId */, 0, null);
+
+  let message = (yield notifyPromise).subject.QueryInterface(Ci.nsIPushMessage);
+  throws(_ => message.json(),
+    'Should throw an error when parsing an empty string as JSON');
+  strictEqual(message.text(), '', 'Should return an empty string');
+  deepEqual(message.binary(), [], 'Should return an empty array');
+});
--- a/dom/push/test/xpcshell/xpcshell.ini
+++ b/dom/push/test/xpcshell/xpcshell.ini
@@ -11,16 +11,17 @@ skip-if = toolkit == 'android'
 [test_handler_service.js]
 support-files = PushServiceHandler.js PushServiceHandler.manifest
 [test_notification_ack.js]
 [test_notification_data.js]
 [test_notification_duplicate.js]
 [test_notification_error.js]
 [test_notification_incomplete.js]
 [test_notification_version_string.js]
+[test_observer_data.js]
 
 [test_permissions.js]
 run-sequentially = This will delete all existing push subscriptions.
 
 [test_quota_exceeded.js]
 [test_quota_observer.js]
 [test_quota_with_notification.js]
 [test_register_case.js]
deleted file mode 100644
--- a/dom/requestsync/RequestSync.manifest
+++ /dev/null
@@ -1,5 +0,0 @@
-component {8ee5ab74-15c4-478f-9d32-67627b9f0f1a} RequestSyncScheduler.js
-contract @mozilla.org/dom/request-sync-scheduler;1 {8ee5ab74-15c4-478f-9d32-67627b9f0f1a}
-
-component {e6f55080-e549-4e30-9d00-15f240fb763c} RequestSyncManager.js
-contract @mozilla.org/dom/request-sync-manager;1 {e6f55080-e549-4e30-9d00-15f240fb763c}
deleted file mode 100644
--- a/dom/requestsync/RequestSyncApp.jsm
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-this.EXPORTED_SYMBOLS = ['RequestSyncApp'];
-
-function debug(s) {
-  //dump('DEBUG RequestSyncApp: ' + s + '\n');
-}
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-this.RequestSyncApp = function(aData) {
-  debug('created');
-
-  let keys = [ 'origin', 'manifestURL', 'isInBrowserElement' ];
-  for (let i = 0; i < keys.length; ++i) {
-    if (!(keys[i] in aData)) {
-      dump("ERROR - RequestSyncApp must receive a full app object: " + keys[i] + " missing.");
-      throw "ERROR!";
-    }
-
-    this["_" + keys[i]] = aData[keys[i]];
-  }
-}
-
-this.RequestSyncApp.prototype = {
-  classDescription: 'RequestSyncApp XPCOM Component',
-  classID: Components.ID('{5a0b64db-a2be-4f08-a6c5-8bf2e3ae0c57}'),
-  contractID: '@mozilla.org/dom/request-sync-manager;1',
-  QueryInterface: XPCOMUtils.generateQI([]),
-
-  get origin() {
-    return this._origin;
-  },
-
-  get manifestURL() {
-    return this._manifestURL;
-  },
-
-  get isInBrowserElement() {
-    return this._isInBrowserElement;
-  }
-};
deleted file mode 100644
--- a/dom/requestsync/RequestSyncManager.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-function debug(s) {
-  //dump('DEBUG RequestSyncManager: ' + s + '\n');
-}
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/RequestSyncApp.jsm');
-Cu.import('resource://gre/modules/RequestSyncTask.jsm');
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIMessageSender");
-
-function RequestSyncManager() {
-  debug('created');
-}
-
-RequestSyncManager.prototype = {
-  __proto__: DOMRequestIpcHelper.prototype,
-
-  classDescription: 'RequestSyncManager XPCOM Component',
-  classID: Components.ID('{e6f55080-e549-4e30-9d00-15f240fb763c}'),
-  contractID: '@mozilla.org/dom/request-sync-manager;1',
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
-                                         Ci.nsIObserver,
-                                         Ci.nsIDOMGlobalPropertyInitializer]),
-
-  _messages: [ "RequestSyncManager:Registrations:Return",
-               "RequestSyncManager:SetPolicy:Return",
-               "RequestSyncManager:RunTask:Return" ],
-
-  init: function(aWindow) {
-    debug("init");
-
-    // DOMRequestIpcHelper.initHelper sets this._window
-    this.initDOMRequestHelper(aWindow, this._messages);
-  },
-
-  sendMessage: function(aMsg, aObj) {
-    let self = this;
-    return this.createPromiseWithId(function(aResolverId) {
-      aObj.requestID = aResolverId;
-      cpmm.sendAsyncMessage(aMsg, aObj, null,
-                            self._window.document.nodePrincipal);
-    });
-  },
-
-  registrations: function() {
-    debug('registrations');
-    return this.sendMessage("RequestSyncManager:Registrations", {});
-  },
-
-  setPolicy: function(aTask, aOrigin, aManifestURL, aIsInIsolatedMozBrowserElement,
-                      aState, aOverwrittenMinInterval) {
-    debug('setPolicy');
-
-    return this.sendMessage("RequestSyncManager:SetPolicy",
-      { task: aTask,
-        origin: aOrigin,
-        manifestURL: aManifestURL,
-        isInBrowserElement: aIsInIsolatedMozBrowserElement,
-        state: aState,
-        overwrittenMinInterval: aOverwrittenMinInterval });
-  },
-
-  runTask: function(aTask, aOrigin, aManifestURL, aIsInIsolatedMozBrowserElement) {
-    debug('runTask');
-
-    return this.sendMessage("RequestSyncManager:RunTask",
-      { task: aTask,
-        origin: aOrigin,
-        manifestURL: aManifestURL,
-        isInBrowserElement: aIsInIsolatedMozBrowserElement });
-  },
-
-  registrationsResult: function(aData) {
-    debug("registrationsResult");
-
-    let results = new this._window.Array();
-    for (let i = 0; i < aData.length; ++i) {
-      if (!("app" in aData[i])) {
-        dump("ERROR - Serialization error in RequestSyncManager.\n");
-        continue;
-      }
-
-      let app = new RequestSyncApp(aData[i].app);
-      let exposedApp =
-        this._window.RequestSyncApp._create(this._window, app);
-
-      let task = new RequestSyncTask(this, this._window, exposedApp, aData[i]);
-      let exposedTask =
-        this._window.RequestSyncTask._create(this._window, task);
-
-      results.push(exposedTask);
-    }
-    return results;
-  },
-
-  receiveMessage: function(aMessage) {
-    debug('receiveMessage');
-
-    let req = this.getPromiseResolver(aMessage.data.requestID);
-    if (!req) {
-      return;
-    }
-
-    if ('error' in aMessage.data) {
-      req.reject(Cu.cloneInto(aMessage.data.error, this._window));
-      return;
-    }
-
-    if (aMessage.name == 'RequestSyncManager:Registrations:Return') {
-      req.resolve(this.registrationsResult(aMessage.data.results));
-      return;
-    }
-
-    if ('results' in aMessage.data) {
-      req.resolve(Cu.cloneInto(aMessage.data.results, this._window));
-      return;
-    }
-
-    req.resolve();
-  }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RequestSyncManager]);
deleted file mode 100644
--- a/dom/requestsync/RequestSyncScheduler.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-function debug(s) {
-  //dump('DEBUG RequestSyncScheduler: ' + s + '\n');
-}
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import('resource://gre/modules/DOMRequestHelper.jsm');
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-XPCOMUtils.defineLazyServiceGetter(this, 'cpmm',
-                                   '@mozilla.org/childprocessmessagemanager;1',
-                                   'nsIMessageSender');
-
-function RequestSyncScheduler() {
-  debug('created');
-}
-
-RequestSyncScheduler.prototype = {
-  __proto__: DOMRequestIpcHelper.prototype,
-
-  classDescription: 'RequestSyncScheduler XPCOM Component',
-  classID: Components.ID('{8ee5ab74-15c4-478f-9d32-67627b9f0f1a}'),
-  contractID: '@mozilla.org/dom/request-sync-scheduler;1',
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
-                                         Ci.nsIObserver,
-                                         Ci.nsIDOMGlobalPropertyInitializer]),
-
-  _messages: [ 'RequestSync:Register:Return',
-               'RequestSync:Unregister:Return',
-               'RequestSync:Registrations:Return',
-               'RequestSync:Registration:Return' ],
-
-  init: function(aWindow) {
-    debug('init');
-
-    // DOMRequestIpcHelper.initHelper sets this._window
-    this.initDOMRequestHelper(aWindow, this._messages);
-  },
-
-  register: function(aTask, aParams) {
-    debug('register');
-    return this.sendMessage('RequestSync:Register',
-                            { task: aTask, params: aParams });
-  },
-
-  unregister: function(aTask) {
-    debug('unregister');
-    return this.sendMessage('RequestSync:Unregister',
-                            { task: aTask });
-  },
-
-  registrations: function() {
-    debug('registrations');
-    return this.sendMessage('RequestSync:Registrations', {});
-  },
-
-  registration: function(aTask) {
-    debug('registration');
-    return this.sendMessage('RequestSync:Registration',
-                            { task: aTask });
-  },
-
-  sendMessage: function(aMsg, aObj) {
-    let self = this;
-    return this.createPromiseWithId(function(aResolverId) {
-      aObj.requestID = aResolverId;
-      cpmm.sendAsyncMessage(aMsg, aObj, null,
-                            self._window.document.nodePrincipal);
-    });
-  },
-
-  receiveMessage: function(aMessage) {
-    debug('receiveMessage');
-
-    let req = this.getPromiseResolver(aMessage.data.requestID);
-    if (!req) {
-      return;
-    }
-
-    if ('error' in aMessage.data) {
-      req.reject(Cu.cloneInto(aMessage.data.error, this._window));
-      return;
-    }
-
-    if ('results' in aMessage.data) {
-      req.resolve(Cu.cloneInto(aMessage.data.results, this._window));
-      return;
-    }
-
-    req.resolve();
-  }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RequestSyncScheduler]);
deleted file mode 100644
--- a/dom/requestsync/RequestSyncService.jsm
+++ /dev/null
@@ -1,1008 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict'
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-function debug(s) {
-  //dump('DEBUG RequestSyncService: ' + s + '\n');
-}
-
-const RSYNCDB_VERSION = 1;
-const RSYNCDB_NAME = "requestSync";
-const RSYNC_MIN_INTERVAL = 100;
-
-const RSYNC_OPERATION_TIMEOUT = 120000 // 2 minutes
-
-const RSYNC_STATE_ENABLED = "enabled";
-const RSYNC_STATE_DISABLED = "disabled";
-const RSYNC_STATE_WIFIONLY = "wifiOnly";
-
-Cu.import('resource://gre/modules/IndexedDBHelper.jsm');
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.importGlobalProperties(["indexedDB"]);
-
-
-XPCOMUtils.defineLazyServiceGetter(this, "appsService",
-                                   "@mozilla.org/AppsService;1",
-                                   "nsIAppsService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsISyncMessageSender");
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
-                                   "@mozilla.org/parentprocessmessagemanager;1",
-                                   "nsIMessageBroadcaster");
-
-XPCOMUtils.defineLazyServiceGetter(this, "systemMessenger",
-                                   "@mozilla.org/system-message-internal;1",
-                                   "nsISystemMessagesInternal");
-
-XPCOMUtils.defineLazyServiceGetter(this, "secMan",
-                                   "@mozilla.org/scriptsecuritymanager;1",
-                                   "nsIScriptSecurityManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "powerManagerService",
-                                   "@mozilla.org/power/powermanagerservice;1",
-                                   "nsIPowerManagerService");
-
-XPCOMUtils.defineLazyModuleGetter(this, "AlarmService",
-                                  "resource://gre/modules/AlarmService.jsm");
-
-this.RequestSyncService = {
-  __proto__: IndexedDBHelper.prototype,
-
-  children: [],
-
-  _messages: [ "RequestSync:Register",
-               "RequestSync:Unregister",
-               "RequestSync:Registrations",
-               "RequestSync:Registration",
-               "RequestSyncManager:Registrations",
-               "RequestSyncManager:SetPolicy",
-               "RequestSyncManager:RunTask" ],
-
-  _pendingOperation: false,
-  _pendingMessages: [],
-
-  _registrations: {},
-
-  _wifi: false,
-
-  _activeTask: null,
-  _queuedTasks: [],
-
-  _timers: {},
-  _pendingRequests: {},
-
-  // This array contains functions to be executed after the scheduling of the
-  // current task or immediately if there are not scheduling in progress.
-  _afterSchedulingTasks: [],
-
-  // Initialization of the RequestSyncService.
-  init: function() {
-    debug("init");
-
-    if (!Services.prefs.getBoolPref("dom.requestSync.enabled")) {
-      return;
-    }
-
-    this._messages.forEach((function(msgName) {
-      ppmm.addMessageListener(msgName, this);
-    }).bind(this));
-
-    Services.obs.addObserver(this, 'xpcom-shutdown', false);
-    Services.obs.addObserver(this, 'clear-origin-data', false);
-    Services.obs.addObserver(this, 'wifi-state-changed', false);
-
-    this.initDBHelper("requestSync", RSYNCDB_VERSION, [RSYNCDB_NAME]);
-
-    // Loading all the data from the database into the _registrations map.
-    // Any incoming message will be stored and processed when the async
-    // operation is completed.
-
-    this.dbTxn("readonly", function(aStore) {
-      aStore.openCursor().onsuccess = event => {
-        let cursor = event.target.result;
-        if (cursor) {
-          this.addRegistration(cursor.value, function() {
-            cursor.continue();
-          });
-        }
-      }
-    }.bind(this),
-    function() {
-      debug("initialization done");
-    },
-    function() {
-      dump("ERROR!! RequestSyncService - Failed to retrieve data from the database.\n");
-    });
-  },
-
-  // Shutdown the RequestSyncService.
-  shutdown: function() {
-    debug("shutdown");
-
-    this._messages.forEach((function(msgName) {
-      ppmm.removeMessageListener(msgName, this);
-    }).bind(this));
-
-    Services.obs.removeObserver(this, 'xpcom-shutdown');
-    Services.obs.removeObserver(this, 'clear-origin-data');
-    Services.obs.removeObserver(this, 'wifi-state-changed');
-
-    this.close();
-
-    // Removing all the registrations will delete the pending timers.
-    this.forEachRegistration(function(aObj) {
-      let key = this.principalToKey(aObj.principal);
-      this.removeRegistrationInternal(aObj.data.task, key);
-    }.bind(this));
-  },
-
-  observe: function(aSubject, aTopic, aData) {
-    debug("observe");
-
-    switch (aTopic) {
-      case 'xpcom-shutdown':
-        this.executeAfterScheduling(function() {
-          this.shutdown();
-        }.bind(this));
-        break;
-
-      case 'clear-origin-data':
-        this.executeAfterScheduling(function() {
-          this.clearData(aData);
-        }.bind(this));
-        break;
-
-      case 'wifi-state-changed':
-        this.executeAfterScheduling(function() {
-          this.wifiStateChanged(aSubject == 'enabled');
-        }.bind(this));
-        break;
-
-      default:
-        debug("Wrong observer topic: " + aTopic);
-        break;
-    }
-  },
-
-  // When an app is uninstalled, we have to clean all its tasks.
-  clearData: function(aData) {
-    debug('clearData');
-
-    if (!aData) {
-      return;
-    }
-
-    let pattern = JSON.parse(aData);
-    let dbKeys = [];
-
-    for (let key in this._registrations) {
-      let prin = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(key);
-      if (!ChromeUtils.originAttributesMatchPattern(prin.originAttributes, pattern)) {
-        continue;
-      }
-
-      for (let task in this._registrations[key]) {
-        dbKeys = this._registrations[key][task].dbKey;
-        this.removeRegistrationInternal(task, key);
-      }
-    }
-
-    if (dbKeys.length == 0) {
-      return;
-    }
-
-    // Remove the tasks from the database.
-    this.dbTxn('readwrite', function(aStore) {
-      for (let i = 0; i < dbKeys.length; ++i) {
-        aStore.delete(dbKeys[i]);
-      }
-    },
-    function() {
-      debug("ClearData completed");
-    }, function() {
-      debug("ClearData failed");
-    });
-  },
-
-  // Creation of the schema for the database.
-  upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
-    debug('updateSchema');
-    aDb.createObjectStore(RSYNCDB_NAME, { autoIncrement: true });
-  },
-
-  // This method generates the key for the indexedDB object storage.
-  principalToKey: function(aPrincipal) {
-    return aPrincipal.origin;
-  },
-
-  // Add a task to the _registrations map and create the timer if it's needed.
-  addRegistration: function(aObj, aCb) {
-    debug('addRegistration');
-
-    let key = this.principalToKey(aObj.principal);
-    if (!(key in this._registrations)) {
-      this._registrations[key] = {};
-    }
-
-    this.scheduleTimer(aObj, function() {
-      this._registrations[key][aObj.data.task] = aObj;
-      if (aCb) {
-        aCb();
-      }
-    }.bind(this));
-  },
-
-  // Remove a task from the _registrations map and delete the timer if it's
-  // needed. It also checks if the principal is correct before doing the real
-  // operation.
-  removeRegistration: function(aTaskName, aKey, aPrincipal) {
-    debug('removeRegistration');
-
-    if (!(aKey in this._registrations) ||
-        !(aTaskName in this._registrations[aKey])) {
-      return false;
-    }
-
-    // Additional security check.
-    if (!aPrincipal.equals(this._registrations[aKey][aTaskName].principal)) {
-      return false;
-    }
-
-    this.removeRegistrationInternal(aTaskName, aKey);
-    return true;
-  },
-
-  removeRegistrationInternal: function(aTaskName, aKey) {
-    debug('removeRegistrationInternal');
-
-    let obj = this._registrations[aKey][aTaskName];
-
-    this.removeTimer(obj);
-
-    // It can be that this task has been already schedulated.
-    this.removeTaskFromQueue(obj);
-
-    // It can be that this object is already in scheduled, or in the queue of a
-    // iDB transacation. In order to avoid rescheduling it, we must disable it.
-    obj.active = false;
-
-    delete this._registrations[aKey][aTaskName];
-
-    // Lets remove the key in case there are not tasks registered.
-    for (let key in this._registrations[aKey]) {
-      return;
-    }
-    delete this._registrations[aKey];
-  },
-
-  removeTaskFromQueue: function(aObj) {
-    let pos = this._queuedTasks.indexOf(aObj);
-    if (pos != -1) {
-      this._queuedTasks.splice(pos, 1);
-    }
-  },
-
-  // The communication from the exposed objects and the service is done using
-  // messages. This function receives and processes them.