merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 29 Jun 2016 16:13:05 +0200
changeset 345191 b69a5bbb5e40bd426e35222baa600b481e50d265
parent 345034 3cd482f4d7fe1e0a40bb27ce3557fe10068154bd (current diff)
parent 345190 72993ec9d3030d7d479a0da71551a17fc490124f (diff)
child 345201 0c56fe904602ed999c82f46a8dde0bfac2e2ae9b
child 345229 eeb6862f960c1310bde9aed159f3fc5bb2d4b6d7
child 345262 b7188125e7317d13c22c3973478d57b866c1662d
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central a=merge
browser/themes/shared/customizableui/customizeMode.inc.css
dom/base/URL.cpp
dom/base/URL.h
dom/base/URLSearchParams.cpp
dom/base/URLSearchParams.h
dom/base/test/file_url.jsm
dom/base/test/test_unknown_url_origin.html
dom/base/test/test_url.html
dom/base/test/test_url.xul
dom/base/test/test_urlExceptions.html
dom/base/test/test_urlSearchParams.html
dom/base/test/test_urlSearchParams_utf8.html
dom/base/test/test_url_data.html
dom/base/test/test_url_empty_port.html
dom/base/test/test_url_malformedHost.html
dom/base/test/test_urlutils_stringify.html
dom/workers/URL.cpp
dom/workers/URL.h
dom/workers/test/file_url.jsm
dom/workers/test/jsm_url_worker.js
dom/workers/test/test_bug883784.jsm
dom/workers/test/test_bug883784.xul
dom/workers/test/test_url.html
dom/workers/test/test_url.xul
dom/workers/test/test_urlApi.html
dom/workers/test/test_urlSearchParams.html
dom/workers/test/test_url_exceptions.html
dom/workers/test/urlApi_worker.js
dom/workers/test/urlSearchParams_worker.js
dom/workers/test/url_exceptions_worker.js
dom/workers/test/url_worker.js
js/src/vm/Monitor.cpp
modules/libpref/init/all.js
taskcluster/taskgraph/types.py
testing/web-platform/meta/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html.ini
testing/web-platform/meta/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html.ini
testing/web-platform/meta/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html.ini
testing/web-platform/meta/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html.ini
testing/web-platform/meta/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html.ini
testing/web-platform/meta/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html.ini
testing/web-platform/meta/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html.ini
testing/web-platform/meta/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html.ini
testing/web-platform/meta/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html.ini
testing/web-platform/meta/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html.ini
toolkit/components/telemetry/Histograms.json
widget/cocoa/nsChildView.mm
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -27,17 +27,16 @@ builtin(include, build/autoconf/zlib.m4)
 builtin(include, build/autoconf/linux.m4)dnl
 builtin(include, build/autoconf/winsdk.m4)dnl
 builtin(include, build/autoconf/icu.m4)dnl
 builtin(include, build/autoconf/ffi.m4)dnl
 builtin(include, build/autoconf/clang-plugin.m4)dnl
 builtin(include, build/autoconf/alloc.m4)dnl
 builtin(include, build/autoconf/ios.m4)dnl
 builtin(include, build/autoconf/jemalloc.m4)dnl
-builtin(include, build/autoconf/rust.m4)dnl
 
 MOZ_PROG_CHECKMSYS()
 
 # Read the user's .mozconfig script.  We can't do this in
 # configure.in: autoconf puts the argument parsing code above anything
 # expanded from configure.in, and we need to get the configure options
 # from .mozconfig in place before that argument parsing code.
 MOZ_READ_MOZCONFIG(.)
--- a/b2g/app/nsBrowserApp.cpp
+++ b/b2g/app/nsBrowserApp.cpp
@@ -210,27 +210,16 @@ int main(int argc, _CONST char* argv[])
   // If the b2g app is launched from adb shell, then the shell will wind
   // up being the process group controller. This means that we can't send
   // signals to the process group (useful for profiling).
   // We ignore the return value since setsid() fails if we're already the
   // process group controller (the normal situation).
   (void)setsid();
 #endif
 
-  int gotCounters;
-#if defined(XP_UNIX)
-  struct rusage initialRUsage;
-  gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
-#elif defined(XP_WIN)
-  IO_COUNTERS ioCounters;
-  gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
-#else
-  #error "Unknown platform"  // having this here keeps cppcheck happy
-#endif
-
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize();
 #endif
 
   // B2G loader has already initialized Gecko so we can't initialize
   // it again here.
 #ifndef MOZ_B2G_LOADER
   // We do this because of data in bug 771745
@@ -246,42 +235,16 @@ int main(int argc, _CONST char* argv[])
 #endif // MOZ_B2G_LOADER
 
   rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XRE functions.\n");
     return 255;
   }
 
-  if (gotCounters) {
-#if defined(XP_WIN)
-    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
-                            int(ioCounters.ReadOperationCount));
-    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER,
-                            int(ioCounters.ReadTransferCount / 1024));
-    IO_COUNTERS newIoCounters;
-    if (GetProcessIoCounters(GetCurrentProcess(), &newIoCounters)) {
-      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_OPS,
-                              int(newIoCounters.ReadOperationCount - ioCounters.ReadOperationCount));
-      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_TRANSFER,
-                              int((newIoCounters.ReadTransferCount - ioCounters.ReadTransferCount) / 1024));
-    }
-#elif defined(XP_UNIX)
-    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_HARD_FAULTS,
-                            int(initialRUsage.ru_majflt));
-    struct rusage newRUsage;
-    if (!getrusage(RUSAGE_SELF, &newRUsage)) {
-      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_HARD_FAULTS,
-                              int(newRUsage.ru_majflt - initialRUsage.ru_majflt));
-    }
-#else
-  #error "Unknown platform"  // having this here keeps cppcheck happy
-#endif
-  }
-
   int result;
   {
     ScopedLogging log;
     char **_argv;
 
     /*
      * Duplicate argument vector to conform non-const argv of
      * do_main() since XRE_main() is very stupid with non-const argv.
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -357,27 +357,16 @@ int main(int argc, char* argv[], char* e
 #endif
 
   mozilla::TimeStamp start = mozilla::TimeStamp::Now();
 
 #ifdef XP_MACOSX
   TriggerQuirks();
 #endif
 
-  int gotCounters;
-#if defined(XP_UNIX)
-  struct rusage initialRUsage;
-  gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
-#elif defined(XP_WIN)
-  IO_COUNTERS ioCounters;
-  gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
-#else
-  #error "Unknown platform"  // having this here keeps cppcheck happy
-#endif
-
   nsIFile *xreDirectory;
 
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize();
 
 #ifdef DEBUG
   // In order to be effective against AppInit DLLs, the blocklist must be
   // initialized before user32.dll is loaded into the process (bug 932100).
@@ -389,42 +378,16 @@ int main(int argc, char* argv[], char* e
 
   nsresult rv = InitXPCOMGlue(argv[0], &xreDirectory);
   if (NS_FAILED(rv)) {
     return 255;
   }
 
   XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
 
-  if (gotCounters) {
-#if defined(XP_WIN)
-    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
-                            int(ioCounters.ReadOperationCount));
-    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER,
-                            int(ioCounters.ReadTransferCount / 1024));
-    IO_COUNTERS newIoCounters;
-    if (GetProcessIoCounters(GetCurrentProcess(), &newIoCounters)) {
-      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_OPS,
-                              int(newIoCounters.ReadOperationCount - ioCounters.ReadOperationCount));
-      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_TRANSFER,
-                              int((newIoCounters.ReadTransferCount - ioCounters.ReadTransferCount) / 1024));
-    }
-#elif defined(XP_UNIX)
-    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_HARD_FAULTS,
-                            int(initialRUsage.ru_majflt));
-    struct rusage newRUsage;
-    if (!getrusage(RUSAGE_SELF, &newRUsage)) {
-      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_HARD_FAULTS,
-                              int(newRUsage.ru_majflt - initialRUsage.ru_majflt));
-    }
-#else
-  #error "Unknown platform"  // having this here keeps cppcheck happy
-#endif
-  }
-
 #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
   XRE_EnableSameExecutableForContentProc();
 #endif
 
   int result = do_main(argc, argv, envp, xreDirectory);
 
   NS_LogTerm();
 
--- a/browser/base/content/browser-gestureSupport.js
+++ b/browser/base/content/browser-gestureSupport.js
@@ -982,17 +982,16 @@ var gHistorySwipeAnimation = {
    */
   _takeSnapshot: function HSA__takeSnapshot() {
     if (!this._readyToTakeSnapshots()) {
       return;
     }
 
     let canvas = null;
 
-    TelemetryStopwatch.start("FX_GESTURE_TAKE_SNAPSHOT_OF_PAGE");
     try {
       let browser = gBrowser.selectedBrowser;
       let r = browser.getBoundingClientRect();
       canvas = document.createElementNS("http://www.w3.org/1999/xhtml",
                                         "canvas");
       canvas.mozOpaque = true;
       let scale = window.devicePixelRatio;
       canvas.width = r.width * scale;
@@ -1001,17 +1000,16 @@ var gHistorySwipeAnimation = {
       let zoom = browser.markupDocumentViewer.fullZoom * scale;
       ctx.scale(zoom, zoom);
       ctx.drawWindow(browser.contentWindow,
                      0, 0, canvas.width / zoom, canvas.height / zoom, "white",
                      ctx.DRAWWINDOW_DO_NOT_FLUSH | ctx.DRAWWINDOW_DRAW_VIEW |
                      ctx.DRAWWINDOW_ASYNC_DECODE_IMAGES |
                      ctx.DRAWWINDOW_USE_WIDGET_LAYERS);
     } finally {
-      TelemetryStopwatch.finish("FX_GESTURE_TAKE_SNAPSHOT_OF_PAGE");
     }
 
     TelemetryStopwatch.start("FX_GESTURE_INSTALL_SNAPSHOT_OF_PAGE");
     try {
       this._installCurrentPageSnapshot(canvas);
       this._assignSnapshotToCurrentBrowser(canvas);
     } finally {
       TelemetryStopwatch.finish("FX_GESTURE_INSTALL_SNAPSHOT_OF_PAGE");
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -5620,20 +5620,16 @@
       <method name="_handleTabTelemetryEnd">
         <parameter name="aTab"/>
         <body>
         <![CDATA[
           if (!aTab._animStartTime) {
             return;
           }
 
-          Services.telemetry.getHistogramById(aTab.closing ?
-                                              "FX_TAB_ANIM_CLOSE_MS" :
-                                              "FX_TAB_ANIM_OPEN_MS")
-                            .add(Date.now() - aTab._animStartTime);
           aTab._animStartTime = 0;
 
           // Handle tab animation smoothness telemetry/logging of frame intervals and paint times
           if (!("_recordingHandle" in aTab)) {
             return;
           }
 
           let intervals = window.QueryInterface(Ci.nsIInterfaceRequestor)
--- a/browser/components/sessionstore/SessionWorker.js
+++ b/browser/components/sessionstore/SessionWorker.js
@@ -339,35 +339,39 @@ var Agent = {
     // Sanity check
     if (typeof prefix == "undefined" || prefix == "") {
       throw new TypeError();
     }
 
     let exn = null;
 
     let iterator = new File.DirectoryIterator(path);
-    if (!iterator.exists()) {
-      return;
-    }
-    for (let entry in iterator) {
-      if (entry.isDir) {
-        continue;
+    try {
+      if (!iterator.exists()) {
+        return;
       }
-      if (!prefix || entry.name.startsWith(prefix)) {
-        try {
-          File.remove(entry.path);
-        } catch (ex) {
-          // Don't stop immediately
-          exn = exn || ex;
+      for (let entry in iterator) {
+        if (entry.isDir) {
+          continue;
+        }
+        if (!prefix || entry.name.startsWith(prefix)) {
+          try {
+            File.remove(entry.path);
+          } catch (ex) {
+            // Don't stop immediately
+            exn = exn || ex;
+          }
         }
       }
-    }
 
-    if (exn) {
-      throw exn;
+      if (exn) {
+        throw exn;
+      }
+    } finally {
+      iterator.close();
     }
   },
 };
 
 function isNoSuchFileEx(aReason) {
   return aReason instanceof OS.File.Error && aReason.becauseNoSuchFile;
 }
 
--- a/browser/config/mozconfigs/linux64/artifact
+++ b/browser/config/mozconfigs/linux64/artifact
@@ -1,10 +1,9 @@
 MOZ_AUTOMATION_BUILD_SYMBOLS=0
 MOZ_AUTOMATION_L10N_CHECK=0
 
-NO_CACHE=1
-
-. "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
+. "$topsrcdir/browser/config/mozconfigs/linux64/common-opt"
+. "$topsrcdir/build/mozconfig.common.override"
 
 ac_add_options --enable-artifact-builds
 unset CC
 unset CXX
--- a/browser/themes/shared/customizableui/customizeMode.inc.css
+++ b/browser/themes/shared/customizableui/customizeMode.inc.css
@@ -89,17 +89,17 @@
 #customization-container {
   background-color: rgb(247,247,247);
   color: black;
   text-shadow: none;
 }
 
 #customization-palette,
 #customization-empty {
-  padding: 0 25px 25px;
+  padding: 5px 25px 25px;
 }
 
 #customization-header {
   font-size: 1.75em;
   line-height: 1.75em;
   color: #666;
   font-weight: 200;
   margin: 25px 25px 12px;
@@ -276,18 +276,21 @@ toolbarpaletteitem[place="toolbar"]:-moz
 }
 
 toolbarpaletteitem[place="palette"]:not([mousedown="true"]):-moz-focusring,
 toolbarpaletteitem[place="panel"]:not([mousedown="true"]):-moz-focusring,
 toolbarpaletteitem[place="toolbar"]:not([mousedown="true"]):-moz-focusring {
   /* Delay adding the focusring back until after the transform transition completes. */
   transition: outline-width .01s linear var(--drag-drop-transition-duration);
   outline: 1px dotted rgba(0,0,0,.5);
+  -moz-outline-radius: 2.5px;
+}
+
+toolbarpaletteitem[place="toolbar"]:not([mousedown="true"]):-moz-focusring {
   outline-offset: -5px;
-  -moz-outline-radius: 2.5px;
 }
 
 #wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton,
 #wrapper-edit-controls[place="palette"] > #edit-controls > separator,
 #wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton,
 #wrapper-zoom-controls[place="palette"] > #zoom-controls > separator {
   margin-top: 20px;
 }
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -90,17 +90,19 @@ if test "$OS_TARGET" = "Android"; then
 fi
 ])
 
 AC_DEFUN([MOZ_ANDROID_STLPORT],
 [
 
 if test "$OS_TARGET" = "Android"; then
     cpu_arch_dir="$ANDROID_CPU_ARCH"
-    if test "$MOZ_THUMB2" = 1; then
+    # NDK r12 removed the arm/thumb library split and just made everything
+    # thumb by default.  Attempt to compensate.
+    if test "$MOZ_THUMB2" = 1 -a -d "$cpu_arch_dir/thumb"; then
         cpu_arch_dir="$cpu_arch_dir/thumb"
     fi
 
     if test -z "$STLPORT_CPPFLAGS$STLPORT_LIBS"; then
         case "$android_cxx_stl" in
         libstdc++)
             # android-ndk-r8b and later
             ndk_base="$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version"
@@ -124,16 +126,22 @@ if test "$OS_TARGET" = "Android"; then
             cxxabi_base="$ndk_base/llvm-libc++abi"
             cxxabi_include="$cxxabi_base/libcxxabi/include"
 
             if ! test -e "$cxx_libs/libc++_static.a"; then
                 AC_MSG_ERROR([Couldn't find path to llvm-libc++ in the android ndk])
             fi
 
             STLPORT_LIBS="-L$cxx_libs -lc++_static"
+            # NDK r12 split the libc++ runtime libraries into pieces.
+            for lib in c++abi unwind android_support; do
+                if test -e "$cxx_libs/lib${lib}.a"; then
+                     STLPORT_LIBS="$STLPORT_LIBS -l${lib}"
+                fi
+            done
             # Add android/support/include/ for prototyping long double math
             # functions, locale-specific C library functions, multibyte support,
             # etc.
             STLPORT_CPPFLAGS="-I$android_ndk/sources/android/support/include -I$cxx_include -I$cxxabi_include"
             ;;
         mozstlport)
             # We don't need to set STLPORT_LIBS, because the build system will
             # take care of linking in our home-built stlport where it is needed.
--- a/build/autoconf/ffi.m4
+++ b/build/autoconf/ffi.m4
@@ -32,16 +32,22 @@ if test "$MOZ_BUILD_APP" != js -o -n "$J
       ac_configure_args="$ac_configure_args --enable-debug"
     fi
     if test "$DSO_PIC_CFLAGS"; then
       ac_configure_args="$ac_configure_args --with-pic"
     fi
     for var in AS CC CXX CPP LD AR RANLIB STRIP; do
       ac_configure_args="$ac_configure_args $var='`eval echo \\${${var}}`'"
     done
+    old_cflags="$CFLAGS"
+    # The libffi sources (especially the ARM ones) are written expecting gas
+    # syntax, and clang's integrated assembler doesn't handle all of gas syntax.
+    if test -n "$CLANG_CC" -a "$CPU_ARCH" = arm; then
+      CFLAGS="-no-integrated-as $CFLAGS"
+    fi
     if test "$CROSS_COMPILE"; then
       export CPPFLAGS CFLAGS LDFLAGS
     fi
     ac_configure_args="$ac_configure_args --build=$build --host=$target"
     if test "$_MSC_VER"; then
       # Use a wrapper script for cl and ml that looks more like gcc.
       # autotools can't quite handle an MSVC build environment yet.
       LDFLAGS=
@@ -72,13 +78,14 @@ if test "$MOZ_BUILD_APP" != js -o -n "$J
 
     # Use a separate cache file for libffi, since it does things differently
     # from our configure.
     old_config_files=$CONFIG_FILES
     unset CONFIG_FILES
     AC_OUTPUT_SUBDIRS(js/src/ctypes/libffi)
     ac_configure_args="$_SUBDIR_CONFIG_ARGS"
     CONFIG_FILES=$old_config_files
+    CFLAGS="$old_cflags"
   fi
 
 fi
 ])
 
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -223,17 +223,16 @@ def old_configure_options(*options):
     '--enable-pref-extensions',
     '--enable-printing',
     '--enable-pulseaudio',
     '--enable-raw',
     '--enable-readline',
     '--enable-reflow-perf',
     '--enable-release',
     '--enable-require-all-d3dc-versions',
-    '--enable-rust',
     '--enable-safe-browsing',
     '--enable-sandbox',
     '--enable-signmar',
     '--enable-simulator',
     '--enable-skia',
     '--enable-skia-gpu',
     '--enable-small-chunk-size',
     '--enable-startup-notification',
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/rust.configure
@@ -0,0 +1,146 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+option('--enable-rust', help='Include Rust language sources')
+
+@depends('--enable-rust')
+def rust_compiler_names(value):
+    if value:
+        return ['rustc']
+
+rustc = check_prog('RUSTC', rust_compiler_names, allow_missing=True)
+
+@depends_if(rustc)
+@checking('rustc version')
+@imports('subprocess')
+def rustc_version(rustc):
+    try:
+        # TODO: We should run `rustc --version -v` and parse that output instead.
+        version = Version(subprocess.check_output(
+            [rustc, '--version']
+        ).splitlines()[0].split()[1])
+        return version
+    except subprocess.CalledProcessError as e:
+        die('Failed to get rustc version: %s', e.message)
+
+@depends('--enable-rust', rustc, rustc_version)
+@imports(_from='textwrap', _import='dedent')
+def rust_compiler(value, rustc, rustc_version):
+    if value:
+        if not rustc:
+            die(dedent('''\
+            Rust compiler not found.
+            To compile rust language sources, you must have 'rustc' in your path.
+            See http://www.rust-lang.org/ for more information.
+            '''))
+        if rustc_version < '1.5':
+            die(dedent('''\
+            Rust compiler {} is too old.
+            To compile Rust language sources please install at least
+            version 1.5 of the 'rustc' toolchain and make sure it is
+            first in your path.
+            You can verify this by typing 'rustc --version'.
+            '''.format(rustc_version)))
+        return True
+
+set_config('MOZ_RUST', rust_compiler)
+
+@depends(rust_compiler, rustc, target, cross_compiling)
+@imports('os')
+@imports('subprocess')
+@imports(_from='mozbuild.configure.util', _import='LineIO')
+@imports(_from='mozbuild.shellutil', _import='quote')
+@imports(_from='tempfile', _import='mkstemp')
+def rust_target(rust_compiler, rustc, target, cross_compiling):
+    if rust_compiler:
+        # Rust's --target options are similar to, but not exactly the same
+        # as, the autoconf-derived targets we use.  An example would be that
+        # Rust uses distinct target triples for targetting the GNU C++ ABI
+        # and the MSVC C++ ABI on Win32, whereas autoconf has a single
+        # triple and relies on the user to ensure that everything is
+        # compiled for the appropriate ABI.  We need to perform appropriate
+        # munging to get the correct option to rustc.
+        #
+        # The canonical list of targets supported can be derived from:
+        #
+        # https://github.com/rust-lang/rust/tree/master/mk/cfg
+
+        # Avoid having to write out os+kernel for all the platforms where
+        # they don't differ.
+        os_or_kernel = target.kernel if target.kernel == 'Linux' and target.os != 'Android' else target.os
+        rustc_target = {
+            # DragonFly
+            ('x86_64', 'Dragonfly'): 'x86_64-unknown-dragonfly',
+            # FreeBSD, GNU/kFreeBSD
+            ('x86', 'FreeBSD'): 'i686-unknown-freebsd',
+            ('x86_64', 'FreeBSD'): 'x86_64-unknown-freebsd',
+            # NetBSD
+            ('x86_64', 'NetBSD'): 'x86_64-unknown-netbsd',
+            # OpenBSD
+            ('x86_64', 'OpenBSD'): 'x86_64-unknown-openbsd',
+            # Linux
+            ('x86', 'Linux'): 'i686-unknown-linux-gnu',
+            # Linux
+            ('x86_64', 'Linux'): 'x86_64-unknown-linux-gnu',
+            # OS X and iOS
+            ('x86', 'OSX'): 'i686-apple-darwin',
+            ('x86', 'iOS'): 'i386-apple-ios',
+            ('x86_64', 'OSX'): 'x86_64-apple-darwin',
+            # Android
+            ('x86', 'Android'): 'i686-linux-android',
+            ('arm', 'Android'): 'arm-linux-androideabi',
+            # Windows
+            # XXX better detection of CXX needed here, to figure out whether
+            # we need i686-pc-windows-gnu instead, since mingw32 builds work.
+            ('x86', 'WINNT'): 'i686-pc-windows-msvc',
+            ('x86_64', 'WINNT'): 'x86_64-pc-windows-msvc',
+        }.get((target.cpu, os_or_kernel), None)
+
+        if rustc_target is None:
+            if cross_compiling:
+                die("Don't know how to translate {} for rustc".format(target.alias))
+            # Fall back to implicit (native) target when not cross-compiling
+            return None
+
+        # Check to see whether our rustc has a reasonably functional stdlib
+        # for our chosen target.
+        target_arg = '--target=' + rustc_target
+        in_fd, in_path = mkstemp(prefix='conftest', suffix='.rs')
+        out_fd, out_path = mkstemp(prefix='conftest', suffix='.rlib')
+        os.close(out_fd)
+        try:
+            source = 'pub extern fn hello() { println!("Hello world"); }'
+            log.debug('Creating `%s` with content:', in_path)
+            with LineIO(lambda l: log.debug('| %s', l)) as out:
+                out.write(source)
+
+            os.write(in_fd, source)
+            os.close(in_fd)
+
+            cmd = [
+                rustc,
+                '--crate-type', 'staticlib',
+                target_arg,
+                '-o', out_path,
+                in_path,
+            ]
+            def failed():
+                die('Cannot compile for {} with {}'.format(target.alias, rustc))
+            check_cmd_output(*cmd, onerror=failed)
+            if not os.path.exists(out_path) or os.path.getsize(out_path) == 0:
+                failed()
+        finally:
+            os.remove(in_path)
+            os.remove(out_path)
+        # This target is usable.
+        return target_arg
+
+set_config('RUST_TARGET', rust_target)
+
+# Until we remove all the other Rust checks in old-configure.
+add_old_configure_assignment('MOZ_RUST', rust_compiler)
+add_old_configure_assignment('RUSTC', rustc)
+add_old_configure_assignment('RUST_TARGET', rust_target)
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -635,8 +635,10 @@ def debug_flags(env_debug_flags, enable_
     if len(enable_debug_flags):
         return enable_debug_flags[0]
     if env_debug_flags:
         return env_debug_flags[0]
     return default_debug_flags
 
 set_config('MOZ_DEBUG_FLAGS', debug_flags)
 add_old_configure_assignment('MOZ_DEBUG_FLAGS', debug_flags)
+
+include('rust.configure')
--- a/build/moz.configure/util.configure
+++ b/build/moz.configure/util.configure
@@ -65,19 +65,20 @@ def normsep(path):
 # exists.
 # The `paths` parameter may be passed to search the given paths instead of
 # $PATH.
 @imports(_from='which', _import='which')
 @imports(_from='which', _import='WhichError')
 @imports('itertools')
 @imports(_from='os', _import='pathsep')
 def find_program(file, paths=None):
-    if is_absolute_or_relative(file):
-        return os.path.abspath(file) if os.path.isfile(file) else None
     try:
+        if is_absolute_or_relative(file):
+            return normsep(which(os.path.basename(file),
+                                 [os.path.dirname(file)]))
         if paths:
             if not isinstance(paths, (list, tuple)):
                 die("Paths provided to find_program must be a list of strings, "
                     "not %r", paths)
             paths = list(itertools.chain(
                 *(p.split(pathsep) for p in paths if p)))
         return normsep(which(file, path=paths))
     except WhichError:
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -914,21 +914,21 @@ ifdef ASFILES
 	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
 endif
 
 ifdef MOZ_RUST
 # Assume any system libraries rustc links against are already
 # in the target's LIBS.
 $(RSOBJS):
 	$(REPORT_BUILD)
-	$(RUSTC) $(RUSTFLAGS) --crate-type rlib --emit dep-info=$(MDDEPDIR)/$(call mk_libname,$<).pp,link=$(call mk_libname,$<) $(_VPATH_SRCS)
+	$(RUSTC) $(RUST_TARGET) $(RUSTFLAGS) --crate-type rlib --emit dep-info=$(MDDEPDIR)/$(call mk_libname,$<).pp,link=$(call mk_libname,$<) $(_VPATH_SRCS)
 
 $(RS_STATICLIB_CRATE_OBJ):
 	$(REPORT_BUILD)
-	$(RUSTC) $(RUSTFLAGS) --crate-type staticlib $(RLIB_EXTERN_CRATE_OPTIONS) --emit dep-info=$(MDDEPDIR)/$(call mk_global_crate_libname,$(RS_STATICLIB_CRATE_SRC)).pp,link=$@ $(RS_STATICLIB_CRATE_SRC)
+	$(RUSTC) $(RUST_TARGET) $(RUSTFLAGS) --crate-type staticlib $(RLIB_EXTERN_CRATE_OPTIONS) --emit dep-info=$(MDDEPDIR)/$(call mk_global_crate_libname,$(RS_STATICLIB_CRATE_SRC)).pp,link=$@ $(RS_STATICLIB_CRATE_SRC)
 endif
 
 $(SOBJS):
 	$(REPORT_BUILD)
 	$(AS) -o $@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) -c $<
 
 $(CPPOBJS):
 	$(REPORT_BUILD_VERBOSE)
--- a/devtools/client/shared/test/browser_telemetry_toolboxtabs_storage.js
+++ b/devtools/client/shared/test/browser_telemetry_toolboxtabs_storage.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const TEST_URI = "data:text/html;charset=utf-8,<p>browser_telemetry_toolboxtabs_storage.js</p>";
 
 // Because we need to gather stats for the period of time that a tool has been
 // opened we make use of setTimeout() to create tool active times.
-const TOOL_DELAY = 200;
+const TOOL_DELAY = 1000;
 
 add_task(function* () {
   info("Activating the storage inspector");
   Services.prefs.setBoolPref("devtools.storage.enabled", true);
 
   yield addTab(TEST_URI);
   let Telemetry = loadTelemetryAndRecordLogs();
 
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -195,18 +195,16 @@ EXPORTS.mozilla.dom += [
     'ScriptSettings.h',
     'ShadowRoot.h',
     'StructuredCloneHolder.h',
     'StructuredCloneTags.h',
     'StyleSheetList.h',
     'SubtleCrypto.h',
     'Text.h',
     'TreeWalker.h',
-    'URL.h',
-    'URLSearchParams.h',
     'WebKitCSSMatrix.h',
     'WebSocket.h',
     'WindowOrientationObserver.h',
 ]
 
 UNIFIED_SOURCES += [
     'AnonymousContent.cpp',
     'Attr.cpp',
@@ -331,18 +329,16 @@ UNIFIED_SOURCES += [
     'ShadowRoot.cpp',
     'StructuredCloneHolder.cpp',
     'StyleSheetList.cpp',
     'SubtleCrypto.cpp',
     'Text.cpp',
     'TextInputProcessor.cpp',
     'ThirdPartyUtil.cpp',
     'TreeWalker.cpp',
-    'URL.cpp',
-    'URLSearchParams.cpp',
     'WebKitCSSMatrix.cpp',
     'WebSocket.cpp',
     'WindowNamedPropertiesHandler.cpp',
     'WindowOrientationObserver.cpp',
 ]
 
 if CONFIG['MOZ_WEBRTC']:
     UNIFIED_SOURCES += [
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1909,16 +1909,19 @@ nsDOMWindowUtils::SendQueryContentEvent(
       message = eQueryTextRect;
       break;
     case QUERY_EDITOR_RECT:
       message = eQueryEditorRect;
       break;
     case QUERY_CHARACTER_AT_POINT:
       message = eQueryCharacterAtPoint;
       break;
+    case QUERY_TEXT_RECT_ARRAY:
+      message = eQueryTextRectArray;
+      break;
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   SelectionType selectionType = SelectionType::eNormal;
   static const uint32_t kSelectionFlags =
     QUERY_CONTENT_FLAG_SELECTION_SPELLCHECK |
     QUERY_CONTENT_FLAG_SELECTION_IME_RAWINPUT |
@@ -2026,16 +2029,19 @@ nsDOMWindowUtils::SendQueryContentEvent(
       queryEvent.InitForQueryCaretRect(aOffset, options);
       break;
     case eQueryTextRect:
       queryEvent.InitForQueryTextRect(aOffset, aLength, options);
       break;
     case eQuerySelectedText:
       queryEvent.InitForQuerySelectedText(selectionType, options);
       break;
+    case eQueryTextRectArray:
+      queryEvent.InitForQueryTextRectArray(aOffset, aLength, options);
+      break;
     default:
       queryEvent.Init(options);
       break;
   }
 
   nsEventStatus status;
   nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -279,17 +279,16 @@ bool nsGlobalWindow::sIdleObserversAPIFu
 static int32_t              gRefCnt                    = 0;
 static int32_t              gOpenPopupSpamCount        = 0;
 static PopupControlState    gPopupControlState         = openAbused;
 static int32_t              gRunningTimeoutDepth       = 0;
 static bool                 gMouseDown                 = false;
 static bool                 gDragServiceDisabled       = false;
 static FILE                *gDumpFile                  = nullptr;
 static uint32_t             gSerialCounter             = 0;
-static uint32_t             gTimeoutsRecentlySet       = 0;
 static TimeStamp            gLastRecordedRecentTimeouts;
 #define STATISTICS_INTERVAL (30 * PR_MSEC_PER_SEC)
 
 #ifdef DEBUG_jst
 int32_t gTimeoutCnt                                    = 0;
 #endif
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
@@ -9231,18 +9230,16 @@ nsGlobalWindow::ShowModalDialogOuter(con
     mDoc->WarnOnceAbout(nsIDocument::eShowModalDialog);
   }
 
   if (!IsShowModalDialogEnabled()) {
     aError.Throw(NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
 
-  Telemetry::Accumulate(Telemetry::DOM_WINDOW_SHOWMODALDIALOG_USED, true);
-
   RefPtr<DialogValueHolder> argHolder =
     new DialogValueHolder(nsContentUtils::SubjectPrincipal(), aArgument);
 
   // Before bringing up the window/dialog, unsuppress painting and flush
   // pending reflows.
   EnsureReflowFlushAndPaint();
 
   if (!AreDialogsEnabled()) {
@@ -12071,17 +12068,16 @@ nsGlobalWindow::SetTimeoutOrInterval(nsI
   nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
   nsCOMPtr<nsIPrincipal> ourPrincipal = GetPrincipal();
   if (ourPrincipal->Subsumes(subjectPrincipal)) {
     timeout->mPrincipal = subjectPrincipal;
   } else {
     timeout->mPrincipal = ourPrincipal;
   }
 
-  ++gTimeoutsRecentlySet;
   TimeDuration delta = TimeDuration::FromMilliseconds(realInterval);
 
   if (!IsFrozen() && !mTimeoutsSuspendDepth) {
     // If we're not currently frozen, then we set timeout->mWhen to be the
     // actual firing time of the timer (i.e., now + delta). We also actually
     // create a timer and fire it off.
 
     timeout->mWhen = TimeStamp::Now() + delta;
@@ -12454,19 +12450,16 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
   if (!last_expired_timeout) {
     return;
   }
 
   // Record telemetry information about timers set recently.
   TimeDuration recordingInterval = TimeDuration::FromMilliseconds(STATISTICS_INTERVAL);
   if (gLastRecordedRecentTimeouts.IsNull() ||
       now - gLastRecordedRecentTimeouts > recordingInterval) {
-    uint32_t count = gTimeoutsRecentlySet;
-    gTimeoutsRecentlySet = 0;
-    Telemetry::Accumulate(Telemetry::DOM_TIMERS_RECENTLY_SET, count);
     gLastRecordedRecentTimeouts = now;
   }
 
   // Insert a dummy timeout into the list of timeouts between the
   // portion of the list that we are about to process now and those
   // timeouts that will be processed in a future call to
   // win_run_timeout(). This dummy timeout serves as the head of the
   // list for any timeouts inserted as a result of running a timeout.
@@ -12476,18 +12469,16 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
   last_expired_timeout->setNext(dummy_timeout);
   RefPtr<nsTimeout> timeoutExtraRef(dummy_timeout);
 
   last_insertion_point = mTimeoutInsertionPoint;
   // If we ever start setting mTimeoutInsertionPoint to a non-dummy timeout,
   // the logic in ResetTimersForNonBackgroundWindow will need to change.
   mTimeoutInsertionPoint = dummy_timeout;
 
-  Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan;
-
   for (nsTimeout *timeout = mTimeouts.getFirst();
        timeout != dummy_timeout && !IsFrozen();
        timeout = nextTimeout) {
     nextTimeout = timeout->getNext();
 
     if (timeout->mFiringDepth != firingDepth) {
       // We skip the timeout since it's on the list to run at another
       // depth.
@@ -12511,17 +12502,16 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
 
     if (!scx) {
       // No context means this window was closed or never properly
       // initialized for this language.
       continue;
     }
 
     // This timeout is good to run
-    ++timeoutsRan;
     bool timeout_was_cleared = RunTimeoutHandler(timeout, scx);
 
     if (timeout_was_cleared) {
       // The running timeout's window was cleared, this means that
       // ClearAllTimeouts() was called from a *nested* call, possibly
       // through a timeout that fired while a modal (to this window)
       // dialog was open or through other non-obvious paths.
       MOZ_ASSERT(dummy_timeout->HasRefCntOne(), "dummy_timeout may leak");
--- a/dom/base/nsQueryContentEventResult.cpp
+++ b/dom/base/nsQueryContentEventResult.cpp
@@ -1,17 +1,18 @@
 /* -*- 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/. */
 
-#include "nsQueryContentEventResult.h"
 #include "nsIWidget.h"
 #include "nsPoint.h"
+#include "nsQueryContentEventResult.h"
+#include "mozilla/Move.h"
 #include "mozilla/TextEvents.h"
 
 using namespace mozilla;
 
 /******************************************************************************
  * Is*PropertyAvailable() methods which check if the property is available
  * (valid) with the event message.
  ******************************************************************************/
@@ -194,35 +195,62 @@ nsQueryContentEventResult::GetTentativeC
   }
   if (NS_WARN_IF(mEventMessage != eQueryCharacterAtPoint)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   *aNotFound = (mTentativeCaretOffset == WidgetQueryContentEvent::NOT_FOUND);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsQueryContentEventResult::GetCharacterRect(int32_t aOffset,
+                                            int32_t* aLeft, int32_t* aTop,
+                                            int32_t* aWidth, int32_t* aHeight)
+{
+  NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(mEventMessage == eQueryTextRectArray,
+                 NS_ERROR_NOT_AVAILABLE);
+
+  if (NS_WARN_IF(mRectArray.Length() <= static_cast<uint32_t>(aOffset))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  *aLeft = mRectArray[aOffset].x;
+  *aTop = mRectArray[aOffset].y;
+  *aWidth = mRectArray[aOffset].width;
+  *aHeight = mRectArray[aOffset].height;
+
+  return NS_OK;
+}
+
 void
 nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
-                                          const WidgetQueryContentEvent &aEvent)
+                                          WidgetQueryContentEvent &aEvent)
 {
   mEventMessage = aEvent.mMessage;
   mSucceeded = aEvent.mSucceeded;
   mReversed = aEvent.mReply.mReversed;
   mRect = aEvent.mReply.mRect;
   mOffset = aEvent.mReply.mOffset;
   mTentativeCaretOffset = aEvent.mReply.mTentativeCaretOffset;
   mString = aEvent.mReply.mString;
+  mRectArray = mozilla::Move(aEvent.mReply.mRectArray);
+  // Mark as result that is longer used.
+  aEvent.mSucceeded = false;
 
   if (!IsRectRelatedPropertyAvailable(mEventMessage) ||
       !aWidget || !mSucceeded) {
     return;
   }
 
   nsIWidget* topWidget = aWidget->GetTopLevelWidget();
   if (!topWidget || topWidget == aWidget) {
     return;
   }
 
   // Convert the top widget related coordinates to the given widget's.
   LayoutDeviceIntPoint offset =
     aWidget->WidgetToScreenOffset() - topWidget->WidgetToScreenOffset();
   mRect.MoveBy(-offset);
+  for (size_t i = 0; i < mRectArray.Length(); i++) {
+    mRectArray[i].MoveBy(-offset);
+  }
 }
--- a/dom/base/nsQueryContentEventResult.h
+++ b/dom/base/nsQueryContentEventResult.h
@@ -19,25 +19,26 @@ class nsIWidget;
 class nsQueryContentEventResult final : public nsIQueryContentEventResult
 {
 public:
   nsQueryContentEventResult();
   NS_DECL_ISUPPORTS
   NS_DECL_NSIQUERYCONTENTEVENTRESULT
 
   void SetEventResult(nsIWidget* aWidget,
-                      const mozilla::WidgetQueryContentEvent &aEvent);
+                      mozilla::WidgetQueryContentEvent& aEvent);
 
 protected:
   ~nsQueryContentEventResult();
 
   mozilla::EventMessage mEventMessage;
 
   uint32_t mOffset;
   uint32_t mTentativeCaretOffset;
   nsString mString;
   mozilla::LayoutDeviceIntRect mRect;
+  nsTArray<mozilla::LayoutDeviceIntRect> mRectArray;
 
   bool mSucceeded;
   bool mReversed;
 };
 
 #endif // mozilla_dom_nsQueryContentEventResult_h
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -235,29 +235,25 @@ nsRange::IsNodeSelected(nsINode* aNode, 
 /******************************************************
  * constructor/destructor
  ******************************************************/
 
 nsRange::~nsRange() 
 {
   NS_ASSERTION(!IsInSelection(), "deleting nsRange that is in use");
 
-  // Maybe we can remove Detach() -- bug 702948.
-  Telemetry::Accumulate(Telemetry::DOM_RANGE_DETACHED, mIsDetached);
-
   // we want the side effects (releases and list removals)
   DoSetRange(nullptr, 0, nullptr, 0, nullptr);
 }
 
 nsRange::nsRange(nsINode* aNode)
   : mRoot(nullptr)
   , mStartOffset(0)
   , mEndOffset(0)
   , mIsPositioned(false)
-  , mIsDetached(false)
   , mMaySpanAnonymousSubtrees(false)
   , mIsGenerated(false)
   , mStartOffsetWasIncremented(false)
   , mEndOffsetWasIncremented(false)
   , mEnableGravitationOnElementRemoval(true)
 #ifdef DEBUG
   , mAssertNextInsertOrAppendIndex(-1)
   , mAssertNextInsertOrAppendNode(nullptr)
@@ -2819,18 +2815,16 @@ nsRange::ToString(nsAString& aReturn)
   return NS_OK;
 }
 
 
 
 NS_IMETHODIMP
 nsRange::Detach()
 {
-  // No-op, but still set mIsDetached for telemetry (bug 702948)
-  mIsDetached = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsRange::CreateContextualFragment(const nsAString& aFragment,
                                   nsIDOMDocumentFragment** aReturn)
 {
   if (mIsPositioned) {
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -340,17 +340,16 @@ protected:
   nsCOMPtr<nsINode> mRoot;
   nsCOMPtr<nsINode> mStartParent;
   nsCOMPtr<nsINode> mEndParent;
   RefPtr<mozilla::dom::Selection> mSelection;
   int32_t mStartOffset;
   int32_t mEndOffset;
 
   bool mIsPositioned : 1;
-  bool mIsDetached : 1;
   bool mMaySpanAnonymousSubtrees : 1;
   bool mIsGenerated : 1;
   bool mStartOffsetWasIncremented : 1;
   bool mEndOffsetWasIncremented : 1;
   bool mEnableGravitationOnElementRemoval : 1;
 #ifdef DEBUG
   int32_t  mAssertNextInsertOrAppendIndex;
   nsINode* mAssertNextInsertOrAppendNode;
--- a/dom/base/test/chrome.ini
+++ b/dom/base/test/chrome.ini
@@ -1,22 +1,20 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g' || os == 'android'
 support-files =
-  file_url.jsm
   file_empty.html
   file_bug945152.jar
   file_bug945152_worker.js
   file_bug1008126_worker.js
 
 [test_anonymousContent_xul_window.xul]
 [test_bug715041.xul]
 [test_bug715041_removal.xul]
 [test_domrequesthelper.xul]
-[test_url.xul]
 [test_navigator_resolve_identity_xrays.xul]
 support-files = file_navigator_resolve_identity_xrays.xul
 [test_sendQueryContentAndSelectionSetEvent.html]
 [test_bug1016960.html]
 [test_copypaste.xul]
 subsuite = clipboard
 [test_messagemanager_principal.html]
 [test_messagemanager_send_principal.html]
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -789,25 +789,16 @@ skip-if = debug == false
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_simplecontentpolicy.html]
 skip-if = e10s || buildapp == 'b2g' # Bug 1156489.
 [test_text_wholeText.html]
 [test_textnode_normalize_in_selection.html]
 [test_textnode_split_in_selection.html]
 [test_title.html]
 [test_treewalker_nextsibling.xml]
-[test_unknown_url_origin.html]
-[test_url.html]
-[test_url_data.html]
-[test_url_empty_port.html]
-[test_url_malformedHost.html]
-[test_urlExceptions.html]
-[test_urlSearchParams.html]
-[test_urlSearchParams_utf8.html]
-[test_urlutils_stringify.html]
 [test_user_select.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
 [test_viewport_scroll.html]
 [test_viewsource_forbidden_in_object.html]
 [test_w3element_traversal.html]
 [test_w3element_traversal.xhtml]
 [test_w3element_traversal_svg.html]
 [test_warning_for_blocked_cross_site_request.html]
--- a/dom/base/test/test_sendQueryContentAndSelectionSetEvent.html
+++ b/dom/base/test/test_sendQueryContentAndSelectionSetEvent.html
@@ -112,16 +112,42 @@ function runTests()
      "sendQueryContentEvent(QUERY_TEXT_RECT) should return same top as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
   is(result.left, textRectNative.left,
      "sendQueryContentEvent(QUERY_TEXT_RECT) should return same left as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
   is(result.height, textRectNative.height,
      "sendQueryContentEvent(QUERY_TEXT_RECT) should return same height as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
   is(result.width, textRectNative.width,
      "sendQueryContentEvent(QUERY_TEXT_RECT) should return same width as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
 
+  // QueryTextRectArray
+  var textRectArray = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT_ARRAY, 1, 2, 0, 0);
+  ok(textRectArray.succeeded,
+     "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should succeed");
+  var textRect = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 1, 2, 0, 0);
+  ok(textRect.succeeded,
+     "sendQueryContentEvent(QUERY_TEXT_RECT) should succeed");
+  var left = {};
+  var top = {};
+  var width = {};
+  var height = {};
+  var left2 = {};
+  var top2 = {};
+  var width2 = {};
+  var height2 = {};
+  textRectArray.getCharacterRect(0, left, top, width, height);
+  ok(textRect.top, top.value,
+     "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same top that returns QUERY_TEXT_RECT");
+  ok(textRect.left, left.value,
+     "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same left that returns QUERY_TEXT_RECT");
+  textRectArray.getCharacterRect(1, left2, top2, width2, height2);
+  ok(textRect.width, width.value + width2.value,
+     "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same width that QUERY_TEXT_RECT is returned for offset 1 and 2");
+  ok(textRect.height, height.value,
+     "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same height that returns QUERY_TEXT_RECT");
+
   // QueryCharacterAtOffset
   result = gUtils.sendQueryContentEvent(gUtils.QUERY_CHARACTER_AT_POINT, 0, 0, textRectNative.left + 1, textRectNative.top + 1,
                                         gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK);
   ok(result.succeeded,
      "sendQueryContentEvent(QUERY_CHARACTER_AT_POINT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
   is(result.top, textRectNative.top,
      "The character top is wrong");
   is(result.left, textRectNative.left,
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -180,20 +180,16 @@ IsDOMObject(JSObject* obj)
 {
   return IsDOMClass(js::GetObjectClass(obj));
 }
 
 #define UNWRAP_OBJECT(Interface, obj, value)                                 \
   mozilla::dom::UnwrapObject<mozilla::dom::prototypes::id::Interface,        \
     mozilla::dom::Interface##Binding::NativeType>(obj, value)
 
-#define UNWRAP_WORKER_OBJECT(Interface, obj, value)                           \
-  UnwrapObject<prototypes::id::Interface##_workers,                           \
-    mozilla::dom::Interface##Binding_workers::NativeType>(obj, value)
-
 // Some callers don't want to set an exception when unwrapping fails
 // (for example, overload resolution uses unwrapping to tell what sort
 // of thing it's looking at).
 // U must be something that a T* can be assigned to (e.g. T* or an RefPtr<T>).
 template <class T, typename U>
 MOZ_ALWAYS_INLINE nsresult
 UnwrapObject(JSObject* obj, U& value, prototypes::ID protoID,
              uint32_t protoDepth)
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -359,17 +359,16 @@ DOMInterfaces = {
 },
 
 'DataChannel': {
     'nativeType': 'nsDOMDataChannel',
 },
 
 'DedicatedWorkerGlobalScope': {
     'headerFile': 'mozilla/dom/WorkerScope.h',
-    'workers': True,
 },
 
 'DeviceAcceleration': {
     'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
 },
 
 'DeviceRotationRate': {
     'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
@@ -429,22 +428,16 @@ DOMInterfaces = {
     'nativeType': 'nsDOMTokenList',
 },
 
 'DummyInterface': {
     'skipGen': True,
     'register': False,
 },
 
-'DummyInterfaceWorkers': {
-    'skipGen': True,
-    'register': False,
-    'workers': True
-},
-
 'DynamicsCompressorNode': {
     'binaryNames': {
         'release': 'getRelease'
     },
 },
 
 'Event': {
     'implicitJSContext': [ 'defaultPrevented', 'preventDefault' ],
@@ -960,32 +953,30 @@ DOMInterfaces = {
 
 'ServiceWorker': {
     'nativeType': 'mozilla::dom::workers::ServiceWorker',
     'headerFile': 'mozilla/dom/workers/bindings/ServiceWorker.h',
 },
 
 'ServiceWorkerGlobalScope': {
     'headerFile': 'mozilla/dom/WorkerScope.h',
-    'workers': True,
 },
 
 'ServiceWorkerRegistration': {
     'implicitJSContext': [ 'pushManager' ],
 },
 
 'SharedWorker': {
     'nativeType': 'mozilla::dom::workers::SharedWorker',
     'headerFile': 'mozilla/dom/workers/bindings/SharedWorker.h',
     'implicitJSContext': [ 'constructor' ],
 },
 
 'SharedWorkerGlobalScope': {
     'headerFile': 'mozilla/dom/WorkerScope.h',
-    'workers': True,
 },
 
 'Storage': {
     'nativeType': 'mozilla::dom::DOMStorage',
 },
 
 'StyleSheet': {
     'nativeType': 'mozilla::CSSStyleSheet',
@@ -1276,21 +1267,16 @@ DOMInterfaces = {
 'TreeWalker': {
     'wrapperCache': False,
 },
 
 'UndoManager': {
     'implicitJSContext' : [ 'undo', 'redo', 'transact' ],
 },
 
-'URL' : [{},
-{
-    'workers': True,
-}],
-
 'VRDevice': {
     'concrete': False
 },
 
 'VTTCue': {
     'nativeType': 'mozilla::dom::TextTrackCue'
 },
 
@@ -1552,25 +1538,23 @@ DOMInterfaces = {
 
 'Worker': {
     'headerFile': 'mozilla/dom/WorkerPrivate.h',
     'nativeType': 'mozilla::dom::workers::WorkerPrivate',
 },
 
 'WorkerDebuggerGlobalScope': {
     'headerFile': 'mozilla/dom/WorkerScope.h',
-    'nativeType': 'mozilla::dom::workers::WorkerDebuggerGlobalScope',
     'implicitJSContext': [
         'dump', 'global', 'reportError', 'setConsoleEventHandler',
     ],
 },
 
 'WorkerGlobalScope': {
     'headerFile': 'mozilla/dom/WorkerScope.h',
-    'workers': True,
     'concrete': False,
     'implicitJSContext': [
         'close',
     ],
     # Rename a few things so we don't have both classes and methods
     # with the same name
     'binaryNames': {
         'performance': 'getPerformance',
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -111,18 +111,17 @@ class Configuration:
         # are.
         mainTypes = set()
         for descriptor in ([self.getDescriptor("DummyInterface", workers=False)] +
                            self.getDescriptors(workers=False, isExternal=False, skipGen=False)):
             mainTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
         (mainCallbacks, mainDictionaries) = findCallbacksAndDictionaries(mainTypes)
 
         workerTypes = set()
-        for descriptor in ([self.getDescriptor("DummyInterfaceWorkers", workers=True)] +
-                           self.getDescriptors(workers=True, isExternal=False, skipGen=False)):
+        for descriptor in (self.getDescriptors(workers=True, isExternal=False, skipGen=False)):
             workerTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
         (workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
 
         self.dictionaries = [d for d in parseData if d.isDictionary()]
         self.callbacks = [c for c in parseData if
                           c.isCallback() and not c.isInterface()]
 
         # Dictionary mapping from a union type name to a set of filenames where
--- a/dom/bindings/mozwebidlcodegen/test/DummyBinding.webidl
+++ b/dom/bindings/mozwebidlcodegen/test/DummyBinding.webidl
@@ -1,2 +1,1 @@
 interface DummyInterface {};
-interface DummyInterfaceWorkers {};
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -1194,16 +1194,18 @@ ContentEventHandler::HandleQueryContentE
     case eQuerySelectedText:
       return OnQuerySelectedText(aEvent);
     case eQueryTextContent:
       return OnQueryTextContent(aEvent);
     case eQueryCaretRect:
       return OnQueryCaretRect(aEvent);
     case eQueryTextRect:
       return OnQueryTextRect(aEvent);
+    case eQueryTextRectArray:
+      return OnQueryTextRectArray(aEvent);
     case eQueryEditorRect:
       return OnQueryEditorRect(aEvent);
     case eQueryContentState:
       return OnQueryContentState(aEvent);
     case eQuerySelectionAsTransferable:
       return OnQuerySelectionAsTransferable(aEvent);
     case eQueryCharacterAtPoint:
       return OnQueryCharacterAtPoint(aEvent);
@@ -1388,16 +1390,95 @@ static nsINode* AdjustTextRectNode(nsINo
       node = aNode->GetChildAt(childCount - 1);
       aNodeOffset = node->IsNodeOfType(nsINode::eTEXT) ?
         static_cast<int32_t>(static_cast<nsIContent*>(node)->TextLength()) : 1;
     }
   }
   return node;
 }
 
+static
+nsIFrame*
+GetFirstFrameInRange(nsRange* aRange)
+{
+  // used to iterate over all contents and their frames
+  nsCOMPtr<nsIContentIterator> iter = NS_NewContentIterator();
+  iter->Init(aRange);
+
+  // get the starting frame
+  int32_t nodeOffset = aRange->StartOffset();
+  nsINode* node = iter->GetCurrentNode();
+  if (!node) {
+    node = AdjustTextRectNode(aRange->GetStartParent(), nodeOffset);
+  }
+  nsIFrame* firstFrame = nullptr;
+  GetFrameForTextRect(node, nodeOffset, true, &firstFrame);
+  return firstFrame;
+}
+
+nsresult
+ContentEventHandler::OnQueryTextRectArray(WidgetQueryContentEvent* aEvent)
+{
+  nsresult rv = Init(aEvent);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  LineBreakType lineBreakType = GetLineBreakType(aEvent);
+  RefPtr<nsRange> range = new nsRange(mRootContent);
+  uint32_t offset = aEvent->mInput.mOffset;
+
+  LayoutDeviceIntRect rect;
+  WritingMode writingMode;
+  while (aEvent->mInput.mLength > aEvent->mReply.mRectArray.Length()) {
+    rv = SetRangeFromFlatTextOffset(range, offset, 1, lineBreakType, true,
+                                    nullptr);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    // get the starting frame
+    nsIFrame* firstFrame = GetFirstFrameInRange(range);
+    if (NS_WARN_IF(!firstFrame)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    // get the starting frame rect
+    nsRect frameRect(nsPoint(0, 0), firstFrame->GetRect().Size());
+    rv = ConvertToRootRelativeOffset(firstFrame, frameRect);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    int32_t nodeOffset = range->StartOffset();
+    AutoTArray<nsRect, 16> charRects;
+    rv = firstFrame->GetCharacterRectsInRange(
+           nodeOffset,
+           aEvent->mInput.mLength - aEvent->mReply.mRectArray.Length(),
+           charRects);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    for (size_t i = 0; i < charRects.Length(); i++) {
+      nsRect charRect = charRects[i];
+      charRect.x += frameRect.x;
+      charRect.y += frameRect.y;
+
+      rect = LayoutDeviceIntRect::FromUnknownRect(
+               charRect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
+
+      aEvent->mReply.mRectArray.AppendElement(rect);
+    }
+    offset += charRects.Length();
+  }
+  aEvent->mSucceeded = true;
+  return NS_OK;
+}
+
 nsresult
 ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
 {
   nsresult rv = Init(aEvent);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
--- a/dom/events/ContentEventHandler.h
+++ b/dom/events/ContentEventHandler.h
@@ -48,16 +48,18 @@ public:
   // eQuerySelectedText event handler
   nsresult OnQuerySelectedText(WidgetQueryContentEvent* aEvent);
   // eQueryTextContent event handler
   nsresult OnQueryTextContent(WidgetQueryContentEvent* aEvent);
   // eQueryCaretRect event handler
   nsresult OnQueryCaretRect(WidgetQueryContentEvent* aEvent);
   // eQueryTextRect event handler
   nsresult OnQueryTextRect(WidgetQueryContentEvent* aEvent);
+  // eQueryTextRectArray event handler
+  nsresult OnQueryTextRectArray(WidgetQueryContentEvent* aEvent);
   // eQueryEditorRect event handler
   nsresult OnQueryEditorRect(WidgetQueryContentEvent* aEvent);
   // eQueryContentState event handler
   nsresult OnQueryContentState(WidgetQueryContentEvent* aEvent);
   // eQuerySelectionAsTransferable event handler
   nsresult OnQuerySelectionAsTransferable(WidgetQueryContentEvent* aEvent);
   // eQueryCharacterAtPoint event handler
   nsresult OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent);
@@ -294,13 +296,16 @@ protected:
                                int32_t aBaseOffset,
                                int32_t aXPStartOffset,
                                int32_t aXPEndOffset,
                                LineBreakType aLineBreakType);
   nsresult GenerateFlatFontRanges(nsRange* aRange,
                                   FontRangeArray& aFontRanges,
                                   uint32_t& aLength,
                                   LineBreakType aLineBreakType);
+  nsresult QueryTextRectByRange(nsRange* aRange,
+                                LayoutDeviceIntRect& aRect,
+                                WritingMode& aWritingMode);
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ContentEventHandler_h_
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -855,16 +855,17 @@ EventStateManager::HandleQueryContentEve
       // Will not be handled locally, remote the event
       GetCrossProcessTarget()->HandleQueryContentEvent(*aEvent);
       return;
     // Following events have not been supported in e10s mode yet.
     case eQueryContentState:
     case eQuerySelectionAsTransferable:
     case eQueryCharacterAtPoint:
     case eQueryDOMWidgetHittest:
+    case eQueryTextRectArray:
       break;
     default:
       return;
   }
 
   // If there is an IMEContentObserver, we need to handle QueryContentEvent
   // with it.
   if (mIMEContentObserver) {
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -11,17 +11,16 @@
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/Headers.h"
 #include "mozilla/dom/Fetch.h"
 #include "mozilla/dom/FetchUtil.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/URL.h"
 #include "mozilla/dom/WorkerPrivate.h"
-#include "mozilla/dom/workers/bindings/URL.h"
 #include "mozilla/unused.h"
 
 #include "WorkerPrivate.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Request)
@@ -169,38 +168,37 @@ GetRequestURLFromChrome(const nsAString&
   aRv = uriClone->GetSpec(spec);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   CopyUTF8toUTF16(spec, aRequestURL);
 }
 
-already_AddRefed<workers::URL>
+already_AddRefed<URL>
 ParseURLFromWorker(const GlobalObject& aGlobal, const nsAString& aInput,
                    ErrorResult& aRv)
 {
   workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
   MOZ_ASSERT(worker);
   worker->AssertIsOnWorkerThread();
 
   NS_ConvertUTF8toUTF16 baseURL(worker->GetLocationInfo().mHref);
-  RefPtr<workers::URL> url =
-    workers::URL::Constructor(aGlobal, aInput, baseURL, aRv);
+  RefPtr<URL> url = URL::WorkerConstructor(aGlobal, aInput, baseURL, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     aRv.ThrowTypeError<MSG_INVALID_URL>(aInput);
   }
   return url.forget();
 }
 
 void
 GetRequestURLFromWorker(const GlobalObject& aGlobal, const nsAString& aInput,
                         nsAString& aRequestURL, ErrorResult& aRv)
 {
-  RefPtr<workers::URL> url = ParseURLFromWorker(aGlobal, aInput, aRv);
+  RefPtr<URL> url = ParseURLFromWorker(aGlobal, aInput, aRv);
   if (aRv.Failed()) {
     return;
   }
 
   nsString username;
   url->GetUsername(username, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
@@ -374,17 +372,17 @@ Request::Constructor(const GlobalObject&
               principal->GetOrigin(globalOrigin);
               aRv.ThrowTypeError<MSG_CROSS_ORIGIN_REFERRER_URL>(referrer,
                                                                 NS_ConvertUTF8toUTF16(globalOrigin));
               return nullptr;
             }
           }
         }
       } else {
-        RefPtr<workers::URL> url = ParseURLFromWorker(aGlobal, referrer, aRv);
+        RefPtr<URL> url = ParseURLFromWorker(aGlobal, referrer, aRv);
         if (NS_WARN_IF(aRv.Failed())) {
           aRv.ThrowTypeError<MSG_INVALID_REFERRER_URL>(referrer);
           return nullptr;
         }
         url->Stringify(referrerURL, aRv);
         if (NS_WARN_IF(aRv.Failed())) {
           aRv.ThrowTypeError<MSG_INVALID_REFERRER_URL>(referrer);
           return nullptr;
--- a/dom/fetch/Response.cpp
+++ b/dom/fetch/Response.cpp
@@ -10,17 +10,16 @@
 #include "nsIURI.h"
 #include "nsPIDOMWindow.h"
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/FetchBinding.h"
 #include "mozilla/dom/Headers.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/URL.h"
-#include "mozilla/dom/workers/bindings/URL.h"
 
 #include "nsDOMString.h"
 
 #include "InternalResponse.h"
 #include "WorkerPrivate.h"
 
 namespace mozilla {
 namespace dom {
@@ -83,18 +82,17 @@ Response::Redirect(const GlobalObject& a
 
     CopyUTF8toUTF16(spec, parsedURL);
   } else {
     workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(worker);
     worker->AssertIsOnWorkerThread();
 
     NS_ConvertUTF8toUTF16 baseURL(worker->GetLocationInfo().mHref);
-    RefPtr<workers::URL> url =
-      workers::URL::Constructor(aGlobal, aUrl, baseURL, aRv);
+    RefPtr<URL> url = URL::WorkerConstructor(aGlobal, aUrl, baseURL, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
 
     url->Stringify(parsedURL, aRv);
   }
 
   if (aRv.Failed()) {
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -1775,16 +1775,20 @@ HTMLInputElement::BeforeSetAttr(int32_t 
       if (container &&
           ((aValue && !HasAttr(aNameSpaceID, aName)) ||
            (!aValue && HasAttr(aNameSpaceID, aName)))) {
         nsAutoString name;
         GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
         container->RadioRequiredWillChange(name, !!aValue);
       }
     }
+
+    if (aName == nsGkAtoms::webkitdirectory) {
+      Telemetry::Accumulate(Telemetry::WEBKIT_DIRECTORY_USED, true);
+    }
   }
 
   return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
                                                           aValue, aNotify);
 }
 
 nsresult
 HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
@@ -8374,15 +8378,16 @@ HTMLInputElement::UpdateEntries(const ns
   fs->CreateRoot(entries);
 
   mEntries.SwapElements(entries);
 }
 
 void
 HTMLInputElement::GetWebkitEntries(nsTArray<RefPtr<Entry>>& aSequence)
 {
+  Telemetry::Accumulate(Telemetry::BLINK_FILESYSTEM_USED, true);
   aSequence.AppendElements(mEntries);
 }
 
 } // namespace dom
 } // namespace mozilla
 
 #undef NS_ORIGINAL_CHECKED_VALUE
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -225,16 +225,17 @@ TextTrackManager::UpdateCueDisplay()
 
   nsIFrame* frame = mMediaElement->GetPrimaryFrame();
   nsVideoFrame* videoFrame = do_QueryFrame(frame);
   if (!videoFrame) {
     return;
   }
 
   nsCOMPtr<nsIContent> overlay = videoFrame->GetCaptionOverlay();
+  nsCOMPtr<nsIContent> controls = videoFrame->GetVideoControls();
   if (!overlay) {
     return;
   }
 
   nsTArray<RefPtr<TextTrackCue> > activeCues;
   mTextTracks->UpdateAndGetShowingCues(activeCues);
 
   if (activeCues.Length() > 0) {
@@ -242,17 +243,17 @@ TextTrackManager::UpdateCueDisplay()
 
     jsCues->SetAsArray(nsIDataType::VTYPE_INTERFACE,
                        &NS_GET_IID(nsIDOMEventTarget),
                        activeCues.Length(),
                        static_cast<void*>(activeCues.Elements()));
 
     nsPIDOMWindowInner* window = mMediaElement->OwnerDoc()->GetInnerWindow();
     if (window) {
-      sParserWrapper->ProcessCues(window, jsCues, overlay);
+      sParserWrapper->ProcessCues(window, jsCues, overlay, controls);
     }
   } else if (overlay->Length() > 0) {
     nsContentUtils::SetNodeTextContent(overlay, EmptyString(), true);
   }
 }
 
 void
 TextTrackManager::NotifyCueAdded(TextTrackCue& aCue)
@@ -291,16 +292,20 @@ TextTrackManager::PopulatePendingList()
 }
 
 void
 TextTrackManager::AddListeners()
 {
   if (mMediaElement) {
     mMediaElement->AddEventListener(NS_LITERAL_STRING("resizevideocontrols"),
                                     this, false, false);
+    mMediaElement->AddEventListener(NS_LITERAL_STRING("seeked"),
+                                    this, false, false);
+    mMediaElement->AddEventListener(NS_LITERAL_STRING("controlbarchange"),
+                                    this, false, true);
   }
 }
 
 void
 TextTrackManager::HonorUserPreferencesForTrackSelection()
 {
   if (performedTrackSelection || !mTextTracks) {
     return;
@@ -400,21 +405,27 @@ NS_IMETHODIMP
 TextTrackManager::HandleEvent(nsIDOMEvent* aEvent)
 {
   if (!mTextTracks) {
     return NS_OK;
   }
 
   nsAutoString type;
   aEvent->GetType(type);
-  if (type.EqualsLiteral("resizevideocontrols")) {
+  if (type.EqualsLiteral("resizevideocontrols") ||
+      type.EqualsLiteral("seeked")) {
     for (uint32_t i = 0; i< mTextTracks->Length(); i++) {
       ((*mTextTracks)[i])->SetCuesDirty();
     }
   }
+
+  if (type.EqualsLiteral("controlbarchange")) {
+    UpdateCueDisplay();
+  }
+
   return NS_OK;
 }
 
 
 class SimpleTextTrackEvent : public Runnable
 {
 public:
   friend class CompareSimpleTextTrackEvents;
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -17,26 +17,25 @@ namespace dom {
 
 using namespace mozilla::dom::indexedDB;
 
 namespace {
 
 nsresult
 GetKeyFromJSVal(JSContext* aCx,
                 JS::Handle<JS::Value> aVal,
-                Key& aKey,
-                bool aAllowUnset = false)
+                Key& aKey)
 {
   nsresult rv = aKey.SetFromJSVal(aCx, aVal);
   if (NS_FAILED(rv)) {
     MOZ_ASSERT(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
     return rv;
   }
 
-  if (aKey.IsUnset() && !aAllowUnset) {
+  if (aKey.IsUnset()) {
     return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
   }
 
   return NS_OK;
 }
 
 } // namespace
 
@@ -342,49 +341,48 @@ IDBKeyRange::Includes(JSContext* aCx,
                       ErrorResult& aRv) const
 {
   Key key;
   aRv = GetKeyFromJSVal(aCx, aValue, key);
   if (aRv.Failed()) {
     return false;
   }
 
-  switch (Key::CompareKeys(Lower(), key)) {
-  case 1:
-    return false;
-  case 0:
-    // Identical keys.
-    if (LowerOpen()) {
+  MOZ_ASSERT(!(Lower().IsUnset() && Upper().IsUnset()));
+  MOZ_ASSERT_IF(IsOnly(),
+    !Lower().IsUnset() && !LowerOpen() &&
+    Lower() == Upper() && LowerOpen() == UpperOpen());
+
+  if (!Lower().IsUnset()) {
+    switch (Key::CompareKeys(Lower(), key)) {
+    case 1:
       return false;
+    case 0:
+      // Identical keys.
+      return !LowerOpen();
+    case -1:
+      if (IsOnly()) {
+        return false;
+      }
+      break;
+    default:
+      MOZ_CRASH();
     }
-    break;
-  case -1:
-    if (IsOnly()) {
-      return false;
-    }
-    break;
-  default:
-    MOZ_CRASH();
   }
 
-  if (!IsOnly()) {
+  if (!Upper().IsUnset()) {
     switch (Key::CompareKeys(key, Upper())) {
     case 1:
       return false;
     case 0:
       // Identical keys.
-      if (UpperOpen()) {
-        return false;
-      }
-      break;
+      return !UpperOpen();
     case -1:
       break;
     }
-  } else {
-    MOZ_ASSERT(key == Lower());
   }
 
   return true;
 }
 
 // static
 already_AddRefed<IDBKeyRange>
 IDBKeyRange::Only(const GlobalObject& aGlobal,
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1209,16 +1209,27 @@ interface nsIDOMWindowUtils : nsISupport
    * @param aY        Y offset in the widget.
    *
    * @return offset, notFound, left, top, width and height properties of the
    *         result are available.
    */
   const unsigned long QUERY_CHARACTER_AT_POINT                  = 3208;
 
   /**
+   * QUERY_TEXT_RECT_ARRAY queries the rects per character
+   *
+   * @param aOffset   The first character's offset.  0 is the first character.
+   * @param aLength   The length of getting text.  If the aLength is too long,
+   *                  the extra length is ignored.
+   * @param aX        Not used.
+   * @param aY        Not used.
+   */
+  const unsigned long QUERY_TEXT_RECT_ARRAY                     = 3209;
+
+  /**
    * Called when the remote child frame has changed its fullscreen state,
    * when entering fullscreen, and when the origin which is fullscreen changes.
    * aFrameElement is the iframe element which contains the child-process
    * fullscreen document.
    */
   void remoteFrameFullscreenChanged(in nsIDOMElement aFrameElement);
 
   /**
--- a/dom/interfaces/base/nsIQueryContentEventResult.idl
+++ b/dom/interfaces/base/nsIQueryContentEventResult.idl
@@ -19,12 +19,16 @@ interface nsIQueryContentEventResult : n
   readonly attribute boolean reversed;
 
   readonly attribute long left;
   readonly attribute long top;
   readonly attribute long width;
   readonly attribute long height;
   readonly attribute AString text;
 
+  void getCharacterRect(in long offset,
+                        out long left, out long top,
+                        out long width, out long height);
+
   readonly attribute boolean succeeded;
   readonly attribute boolean notFound;
   readonly attribute boolean tentativeCaretOffsetNotFound;
 };
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -335,17 +335,17 @@ MediaFormatReader::OnDemuxerInitDone(nsr
 
   mIsEncrypted = crypto && crypto->IsEncrypted();
 
   if (mDecoder && crypto && crypto->IsEncrypted()) {
 #ifdef MOZ_EME
     // Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
     for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) {
       NS_DispatchToMainThread(
-        new DispatchKeyNeededEvent(mDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc")));
+        new DispatchKeyNeededEvent(mDecoder, crypto->mInitDatas[i].mInitData, crypto->mInitDatas[i].mType));
     }
 #endif // MOZ_EME
     mInfo.mCrypto = *crypto;
   }
 
   int64_t videoDuration = HasVideo() ? mInfo.mVideo.mDuration : 0;
   int64_t audioDuration = HasAudio() ? mInfo.mAudio.mDuration : 0;
 
--- a/dom/media/QueueObject.cpp
+++ b/dom/media/QueueObject.cpp
@@ -13,18 +13,23 @@ namespace mozilla {
 
 QueueObject::QueueObject(RefPtr<AbstractThread> aThread) : mThread(aThread) {}
 
 QueueObject::~QueueObject() {}
 
 void
 QueueObject::Dispatch(nsIRunnable* aRunnable)
 {
-  nsCOMPtr<nsIRunnable> runnable = aRunnable;
-  mThread->Dispatch(runnable.forget());
+  Dispatch(do_AddRef(aRunnable));
+}
+
+void
+QueueObject::Dispatch(already_AddRefed<nsIRunnable> aRunnable)
+{
+  mThread->Dispatch(Move(aRunnable));
 }
 
 bool
 QueueObject::OnThread()
 {
   return mThread->IsCurrentThreadIn();
 }
 
--- a/dom/media/QueueObject.h
+++ b/dom/media/QueueObject.h
@@ -16,16 +16,17 @@ namespace mozilla {
 class AbstractThread;
 
 class QueueObject
 {
 public:
   explicit QueueObject(RefPtr<AbstractThread> aThread);
   ~QueueObject();
   void Dispatch(nsIRunnable* aRunnable);
+  void Dispatch(already_AddRefed<nsIRunnable> aRunnable);
   bool OnThread();
   AbstractThread* Thread();
 
 private:
   RefPtr<AbstractThread> mThread;
 };
 }
 
--- a/dom/media/VideoUtils.cpp
+++ b/dom/media/VideoUtils.cpp
@@ -485,9 +485,46 @@ IsAACContentType(const nsAString& aConte
     },
     [](const nsAString& codec) {
       return codec.EqualsLiteral("mp4a.40.2") || // MPEG4 AAC-LC
              codec.EqualsLiteral("mp4a.40.5") || // MPEG4 HE-AAC
              codec.EqualsLiteral("mp4a.67");     // MPEG2 AAC-LC
     });
 }
 
+bool
+IsVorbisContentType(const nsAString& aContentType)
+{
+  return CheckContentType(aContentType,
+    [](const nsAString& type) {
+      return type.EqualsLiteral("audio/webm") ||
+             type.EqualsLiteral("audio/ogg");
+    },
+    [](const nsAString& codec) {
+      return codec.EqualsLiteral("vorbis");
+    });
+}
+
+bool
+IsVP8ContentType(const nsAString& aContentType)
+{
+  return CheckContentType(aContentType,
+    [](const nsAString& type) {
+      return type.EqualsLiteral("video/webm");
+    },
+    [](const nsAString& codec) {
+      return codec.EqualsLiteral("vp8");
+    });
+}
+
+bool
+IsVP9ContentType(const nsAString& aContentType)
+{
+  return CheckContentType(aContentType,
+    [](const nsAString& type) {
+      return type.EqualsLiteral("video/webm");
+    },
+    [](const nsAString& codec) {
+      return codec.EqualsLiteral("vp9");
+    });
+}
+
 } // end namespace mozilla
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -442,11 +442,20 @@ StringListContains(const ListString& aLi
   for (const auto& listItem : MakeStringListRange(aList)) {
     if (listItem.Equals(aItem)) {
       return true;
     }
   }
   return false;
 }
 
+bool
+IsVorbisContentType(const nsAString& aContentType);
+
+bool
+IsVP8ContentType(const nsAString& aContentType);
+
+bool
+IsVP9ContentType(const nsAString& aContentType);
+
 } // end namespace mozilla
 
 #endif
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -30,16 +30,17 @@
 #include "GMPUtils.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsXULAppAPI.h"
 #include "gmp-audio-decode.h"
 #include "gmp-video-decode.h"
 #include "DecoderDoctorDiagnostics.h"
+#include "WebMDecoder.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaKeySystemAccess,
                                       mParent)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeySystemAccess)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeySystemAccess)
@@ -407,35 +408,100 @@ GMPDecryptsAndGeckoDecodesAAC(mozIGeckoM
     }
     return false;
   }
 #endif
   return MP4Decoder::CanHandleMediaType(aContentType, aDiagnostics);
 }
 
 static bool
+GMPDecryptsAndGeckoDecodesVorbis(mozIGeckoMediaPluginService* aGMPService,
+                                const nsAString& aKeySystem,
+                                const nsAString& aContentType,
+                                DecoderDoctorDiagnostics* aDiagnostics)
+{
+  MOZ_ASSERT(HaveGMPFor(aGMPService,
+             NS_ConvertUTF16toUTF8(aKeySystem),
+             NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
+  MOZ_ASSERT(IsVorbisContentType(aContentType));
+  return !HaveGMPFor(aGMPService,
+                     NS_ConvertUTF16toUTF8(aKeySystem),
+                     NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
+                     NS_LITERAL_CSTRING("vorbis")) &&
+         WebMDecoder::CanHandleMediaType(aContentType);
+}
+
+static bool
+GMPDecryptsAndGeckoDecodesVP8(mozIGeckoMediaPluginService* aGMPService,
+                             const nsAString& aKeySystem,
+                             const nsAString& aContentType,
+                             DecoderDoctorDiagnostics* aDiagnostics)
+{
+  MOZ_ASSERT(HaveGMPFor(aGMPService,
+             NS_ConvertUTF16toUTF8(aKeySystem),
+             NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
+  MOZ_ASSERT(IsVP8ContentType(aContentType));
+  return !HaveGMPFor(aGMPService,
+                     NS_ConvertUTF16toUTF8(aKeySystem),
+                     NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
+                     NS_LITERAL_CSTRING("vp8")) &&
+         WebMDecoder::CanHandleMediaType(aContentType);
+}
+
+static bool
+GMPDecryptsAndGeckoDecodesVP9(mozIGeckoMediaPluginService* aGMPService,
+                             const nsAString& aKeySystem,
+                             const nsAString& aContentType,
+                             DecoderDoctorDiagnostics* aDiagnostics)
+{
+  MOZ_ASSERT(HaveGMPFor(aGMPService,
+             NS_ConvertUTF16toUTF8(aKeySystem),
+             NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
+  MOZ_ASSERT(IsVP9ContentType(aContentType));
+  return !HaveGMPFor(aGMPService,
+                     NS_ConvertUTF16toUTF8(aKeySystem),
+                     NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
+                     NS_LITERAL_CSTRING("vp9")) &&
+         WebMDecoder::CanHandleMediaType(aContentType);
+}
+
+static bool
 IsSupportedAudio(mozIGeckoMediaPluginService* aGMPService,
                  const nsAString& aKeySystem,
                  const nsAString& aAudioType,
                  DecoderDoctorDiagnostics* aDiagnostics)
 {
-  return IsAACContentType(aAudioType) &&
-         (GMPDecryptsAndDecodesAAC(aGMPService, aKeySystem, aDiagnostics) ||
-          GMPDecryptsAndGeckoDecodesAAC(aGMPService, aKeySystem, aAudioType, aDiagnostics));
+  if (IsAACContentType(aAudioType)) {
+    return GMPDecryptsAndDecodesAAC(aGMPService, aKeySystem, aDiagnostics) ||
+           GMPDecryptsAndGeckoDecodesAAC(aGMPService, aKeySystem, aAudioType, aDiagnostics);
+  }
+  if (IsVorbisContentType(aAudioType) && aKeySystem.EqualsLiteral("org.w3.clearkey")) {
+    // GMP does not decode Vorbis, so don't bother checking
+    return GMPDecryptsAndGeckoDecodesVorbis(aGMPService, aKeySystem, aAudioType, aDiagnostics);
+  }
+  return false;
 }
 
 static bool
 IsSupportedVideo(mozIGeckoMediaPluginService* aGMPService,
                  const nsAString& aKeySystem,
                  const nsAString& aVideoType,
                  DecoderDoctorDiagnostics* aDiagnostics)
 {
-  return IsH264ContentType(aVideoType) &&
-         (GMPDecryptsAndDecodesH264(aGMPService, aKeySystem, aDiagnostics) ||
-          GMPDecryptsAndGeckoDecodesH264(aGMPService, aKeySystem, aVideoType, aDiagnostics));
+  if (IsH264ContentType(aVideoType)) {
+    return GMPDecryptsAndDecodesH264(aGMPService, aKeySystem, aDiagnostics) ||
+           GMPDecryptsAndGeckoDecodesH264(aGMPService, aKeySystem, aVideoType, aDiagnostics);
+  }
+  if (IsVP8ContentType(aVideoType) && aKeySystem.EqualsLiteral("org.w3.clearkey")) {
+    return GMPDecryptsAndGeckoDecodesVP8(aGMPService, aKeySystem, aVideoType, aDiagnostics);
+  }
+  if (IsVP9ContentType(aVideoType) && aKeySystem.EqualsLiteral("org.w3.clearkey")) {
+    return GMPDecryptsAndGeckoDecodesVP9(aGMPService, aKeySystem, aVideoType, aDiagnostics);
+  }
+  return false;
 }
 
 static bool
 IsSupported(mozIGeckoMediaPluginService* aGMPService,
             const nsAString& aKeySystem,
             const MediaKeySystemConfiguration& aConfig,
             DecoderDoctorDiagnostics* aDiagnostics)
 {
@@ -469,17 +535,17 @@ IsSupportedInitDataType(const nsString& 
   // All supported keySystems can handle "cenc" initDataType.
   // ClearKey also supports "keyids" and "webm" initDataTypes.
   return aCandidate.EqualsLiteral("cenc") ||
     ((aKeySystem.EqualsLiteral("org.w3.clearkey")
 #ifdef MOZ_WIDEVINE_EME
     || aKeySystem.EqualsLiteral("com.widevine.alpha")
 #endif
     ) &&
-    (aCandidate.EqualsLiteral("keyids") || aCandidate.EqualsLiteral("webm)")));
+    (aCandidate.EqualsLiteral("keyids") || aCandidate.EqualsLiteral("webm")));
 }
 
 static bool
 GetSupportedConfig(mozIGeckoMediaPluginService* aGMPService,
                    const nsAString& aKeySystem,
                    const MediaKeySystemConfiguration& aCandidate,
                    MediaKeySystemConfiguration& aOutConfig,
                    DecoderDoctorDiagnostics* aDiagnostics)
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -1045,17 +1045,18 @@ TrackBuffersManager::OnDemuxerInitDone(n
   }
 
   UniquePtr<EncryptionInfo> crypto = mInputDemuxer->GetCrypto();
   if (crypto && crypto->IsEncrypted()) {
 #ifdef MOZ_EME
     // Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
     for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) {
       NS_DispatchToMainThread(
-        new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc")));
+        new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData,
+                                   crypto->mInitDatas[i].mType));
     }
 #endif // MOZ_EME
     info.mCrypto = *crypto;
     // We clear our crypto init data array, so the MediaFormatReader will
     // not emit an encrypted event for the same init data again.
     info.mCrypto.mInitDatas.Clear();
     mEncrypted = true;
   }
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4be8f340c3f0476a5bd2245d1f98156934f6e969
GIT binary patch
literal 7553
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
bTlSfUssDo}JxsVu1n$Rd62Y|y_T~Qq8_<@3
new file mode 100644
--- /dev/null
+++ b/dom/media/test/bipbop_360w_253kbps-clearkey-audio.webm^headers^
@@ -0,0 +1,1 @@
+Cache-Control: no-store
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..56cf4c483c54f51c3ccfad632b321637623b4dfe
GIT binary patch
literal 44671
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
XsCC=McgHmc1KJ~>f`PXoK=A(qjnqmU
new file mode 100644
--- /dev/null
+++ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^
@@ -0,0 +1,1 @@
+Cache-Control: no-store
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9f411d0e34dc3bbc0680fc19ec94ffdcee0e864b
GIT binary patch
literal 46030
zc$}2GLw7C=&#+zFw!3TFwr$(CZQHi(cGvD%YuC2T_qx~f{edrQWpE^eV3K4I9I@S!
z0^#r=VBy#Q^dSgL_%R4dI5^b9%-BviA_zn{EC>WkCC~yG=zr3Zk1Utt+AY@;qf!%!
zE>&f&QX6Fde}ti0Z}T5j%JszlM}#8nZYs6Gz@Yz!cq%>rIfGkbuIhmP|H%JBv{A1$
zg&+zGibjQsjsOA41t!>98UHUmI!1bCdM0{C4WZ=!p@E6Bm!m5YBR$LijQ>k#wSIXm
z2-sybVhc1tnATV(BnUV>Ox-|Tk;^Wy(O9rfktqmBkvRxhk>x*S%a_;>0+%>QyxBFW
zQm7ctyn$9g;g&yzmN*TSI12*ai);)A3G5CAw)|gh|JROY-_szV5<in5AfP~C?*%fU
z^Y-7Q)*`}rCMcYiEzsaCPvX;pnI=-f#_Rw)%j;HK>%GU;1Qsq?OX*)3;DtY3c2MEI
z$hrsn=2Ox*sSm=_gJ-}rUL#h-aR}Wlqgc$2Jt}m>Lo|Lxb)2f$u+{RZy@#`Ro`!R*
zmJzdSv&4<HRY2pjH+xG~kyLV<;Us#<VmXA+dqly>-{Dz)Om27;w=SSjuZh_Ob1f;`
zbNBEuM0X&oKW(y6<S7PEgT+DOV<IgT>uDA%Qn$?8wOWDbkX-uA7etlhoK`)}Hj++2
z(T5RED(qzU1K;aT`5{Znch}xtn%$nQYHuYu<`Xv!V}{Cm2;r+|h?iaJ+T4|oF)KB@
zM{Pg1$7ZZ|t=>?Z#tA%zb3`KOS^y}A8<f(WKz^3m`oc+DdkGzcfm_Kd`vF&0H@`}u
zz@Oowt*jG`Bb+`zs?uTU-V9aj0!UQ1H63c<O*|rm@n3by2oQ$!_!l?nf(3~BOn{=(
z`T+*mMDQAe%B3+WQ^{0}he7Dbp6JcvKUm9cL_W+H1!K~wC$U4K)~1r~^?LpM03xss
znXO;nn2xa-sPhKg8LjIN6h2*t=d!TkNm&r7ot%cVU4<#(ew*g;jSS|zpd*kO_J6LM
zRWxeoEUM}~ihAw|a0<B0TA5Llw1J<35XE(;Bkhj-Kc4E<%GkBw-9=ZMl!@d1S=pcN
zR9pG*<M@tOvu8ZP+s?AssxWXuDr2g!EKSigS9BC7N<WqFk{l(QCa{f&%oGZ2a0e-?
z#C*u?%$#pA8l4I8a{rK_)H}x4!k)fNZ*7Dj(y0(1XBPv_WJ#8Lpzy}!(Ywj9amjr1
z1y1T`OE@ie@@tvmfNarjoN??x3uU<w1B(ZBp|@q)Y8ZAeH0*NkGmvw!&s(!Iuc5)S
z$C~gi44f*L7{YaMCI04u2B5`tNO`#ZjwtT%V>JTO11gJX)5TcUWAEk9<?~-cR2r0L
zGC(4rsO*#;^Ve&!%N=B-$ENxg1M<xpIz|Ni@yA~y{BS*(4rmkY-BhyK&Uh-1b2Ca|
zj%MKZWGJIn`nsXM8qx!{?0qO6j~+(pH^u&?HZelCKe$^<_%C23=UspO`An450+?<|
z^8%&$Znx(%>AaHb2i#y+uA+_b-ZS$^K|$Ix<wci#YE#<L*T?3fCJ#Q30qVQ26IekV
zGLonD|0Ng%Utxw8<BeQIvgGPp0cj>f4nL>6bEV_L4N6FN5`8JsM^EkBVWidP^iQG6
z`m`(Cio6kRFUdllRK^+k<tCsi%YTm?A7d9xNvTCMI+vb=;(?wPoczE+B6~l)ABuoM
z-%}~M`7^`6DXtt06pu7C^>iAHj3|>gyV_0olB&c++HYYsyrNSAn-6m$cB4Km*$w41
zbB|AM;RNP~q{3K*_ABJY+n%_3_(llZna~9LY*6$7BHw_m!^iwTT{Zw5O7zm<?9{uo
z`xCx)QQmbN%B%=p#6f&%;%mLHTg~_UE3VBgKfa7*);S1Y`qeW)=ec6#7EKb8HaX@1
ze>f5Gsys$=oMdq3H4@n*eyUhMT$yRE#8_ofL|GE^Dde37TDlEftzViPhh||qkJPE?
z&Dc6rYMq0RqAovCEhUTMX+))&RXN`*&uWE4yK|~p!B6dr9wd>mQM0LgI9Ly<HJO?l
z^@TU<{cM`D8ODw|Nd~qyNy=0vwK!aRX-btktw_A`-(m<KwI}7A;@AaB<|wlY8|ukD
z_3OW=Y@xT-OW1<Noma}ne!i*aU?eA^3%OX?Qaea=YJ*x;&EH0uaApu`G0M)jqgBV4
z<t$M^NX-|1Q8<{6with^{;7XBKg?4^hzlLHrxZ+W8AG@&d`Ii>>z!2`^y`ip=Q_)c
zWqG|@dP5CSoz1~K`LWi6%jk6cWc2u3p+PHU@drN05gQesal)w<Id&CT9U2cZoLY&A
znqKB2))Lt}JgoUW*4nv>0!ADV?^Jj!lz#asgYK9gRa!o^W1isWsK9kaj?d%6I(Yvq
zj)J_i%nSzx+Tne+=t_urfOUw)`ZYYqGGL4a5`{3H#+s*3YI_54#K{crRQ>+K)Z58l
zsh*nm{r>&MDpWD=OXp?>O;PuwVM0HJ(pG>k4=P_wVLNh3>%H))&d5NK3Q2Bqk`<E4
zx@0kb=;VG6E=7E@hsfT!jLEh68ipXfywEPyKGwW`Zs1Qv3CIk3ubTQow%x@02ct9S
zHu$*cQ0^||foI7EHc7&#a$Qw0d1+VQ7*{`zjK{3q?+b&vN?s`?yXe0DC!U!9$ad-{
z-GYW%l9zlYL?_6m*+NZn*h(lSZ%YLRC9a7{AW=`8h0i^yRI2*2^zLrrya{NH&T;Au
zWk4QYa(rlZ{Es1ax_#b-b|ZW)!W`8XJfH_Y?ryT{0I#voS9ypG=z!3=$^Y<tpZKog
zQ%rLdeKr(~VQJnkZWBqlgjvwwpFuns<4>}0B<)0Yn;eV&2S{V;KSO5hnlMr&qQZPl
z@Hb$huYJBs*^JGUadyJ>b(^{9s*7}idK_A>H8fR6=rLJv8RLU98j0XcEa8)%<S@0>
zK^xM$g*X#pcskQbaZpvl-QD1oa!<RmKY%ZE4Zhlzq9K8Zh1{LtylF^IR&bDFtEkk}
zu<p$#Qff+2WWfcByQ4`UB=!1Nmqjm}&SV4Qzw@Y-`^4ZLMP!Kv>=}JiHWKYzw=&k>
zmMi8ye5PIqt>>tc1loiG57a=5+9_`@%9-OJAfXseq5$3!tY#j_qOR5i4Ba^tLem2y
zpj0R%m|aU1k^DTt%)?_0*SOH9aZEJTrx$>OOqO8e*z%>hmb$ps>C*+~V%no$aUvSf
zQms$rgiVOw(C>^A800487{(?J8>pb<Nj;W33tm4fdm9C<J~3jP=h!#XJ6~ddL0r_u
zt1=P?YH)NSRQWItC)BiDG$RtD%IIT)K-YfU4g+O$u`wpYZLk>y(Pla&Le9Wa5)sbO
z`c{eG<hml3h$=%U-MVy=;u=9vy0pgjp9l$hV7scB4`iESN%F>7A)!B4^g;N*Ky6Mq
zlin2kRd>%wGnI_^#8rkdpq6(05XG+9^f4_5_$9tHsK_Zox)3se9&DPIq1a{;x#m2_
z8V1TSsN6!IZNy;Ig)-B&$2I<`OdBMZa{X89$-6u;5JTzn{|54q`r`7D-c?XMPpzNz
z;;0`4HGrYo&9DTZC-Nl`>9v%sRHp+Ypq&Q(5TcSih~<s0XDnQ%j_m)@^(#3}tFwtJ
zwF~Un_g1v>Rn-r)+Be9Z^ohS(-Uq4kCAtPMXMYsfR@56S6`;-d`~rUr67;&bXUzW*
zhNDy+Ax*bvn)iZipB%BU&PFJGZv1;&Z}72*FlT4UVJe(!&Qw~0ju77CEZz{ow()Y7
z)XI+&;USu}e51DHR?Z^-eVh?gDAC!@q@fe2O2QO4w8oGbvR2S?CPT{sC#>)z=w6_|
zv0l(3<>*zBPuu+q-JOZ%vs<65T2^oz+527*IM0NvC=2f<Te7o5(a83gkf*4W(kZBA
zkDBFt22Q0QG&o9V1WY9M_mxzd#dbU!Ei+I+R}YgX$+!e-w*=8FVP{Mo>B09ag-oY9
z9Tc*cX7D%8LbexNh`a7$GXy>;xxY)4V-Su|sUEhY?B>ntVIBe8RbTdBI{p+vxu5^y
zUu^qs&5P?7*Q+BqXk`oT&s;gIa5H4H8ua*Mp+Bnt_^ht40{|7)tXv27xJogY%Uq23
zP_}-*IO1~)raE*;UMnQffaA@)?i3ZanY8Toi*E)1W}o=5NI5*_BkV<kjItPP#wuM(
z;-)2$Jd14@s`&RD`e8e5=TVa<3u}i<fn4-szrP}%w{l2Fo6RizPqi3=JVv%srR_m)
zIA+gFNolvI8g9qVOzeeED8(6to~s#`<l}*A*rm}cOictI+-hc$i*p?)0s^I39fiI8
zE)QEA*Rap*z;%m?nh>;b*B;x<$gtF3qw22EmO|sDy!AQkUvpi*T(CK@ylQib`0Of;
zY@rtj$|;day8!XOI<E(LPQEdow>NY}rQm^14NrjT`GOtGHw%`|1(bs4hq*)7K|v6(
z;<Vj1R7hn&FR2Z(o*1TV$U!eSPz-(I_Q>;}d^N!Z#E3}pY0cC1aAQq=MnMdbP`PC!
zg|}qWIaEj{2T|yb_B?sryMUk#<U0v(o^c)6WJW#pH-AzJ`Xk@36}aCFv=Yu{fTb(G
z@1IKUW7<D#Tg(G`bf^cUQVWfci*CYztTy>T#J#sHf$m{@hpII0Ze$5-%ac8!q-z!K
zY?I^hhUAuvEJfR(DBYhM)cbcGL^;V9>ggcVB?cXmuYWe)O}jL|QumZO88wO7c^Bv3
z7N3by@n5Ghdt%qf?z-L&kh5-T-oVjh$jJ-}`|rT%a&U3U+BJHpJk~;ZD8a)33LBiO
zfCX&7ywQLRuoRU!?!TelWhf!1WIb}WPkAXUV^3q!j>yyv@A-%+e%fxQPx{b$Hmeii
zt2AiLMDqLcDk_1|@bvH$iUMQ)koYf84?{AJ+nQBCaxPFGPh!}$+7gG3It~?(Rx)NJ
zNFgN8TVNWiPmw56ap4Db+A+B}sxgF}q{&hbCgbriZh15J2S_jr3?ZDY$6fPBm4j1}
z#<RbVBaon*`B{FDe+xrOI&BqG>(YcId(dzWIL_43rT+5GM2st&Y8sa}G(ZOi$<rP8
z-KN^n?L^43DJX@LK!XP1e?Yc+S)<`7^vtWjB(P=M>Yj^3VRm*8WL(jzE9}6U+nh!A
za=7)Fp$o~ZDgo~v0tcUweg7K|>0fU_gs~<LQ(|LG2c#^H56Gb>Gd);oK>~Z4qGIDl
znLHJ6fbyGG9wEuJG{e?1KxDX;G5f4e!{7BjTb{QHB-@zg#nRG_iIU2Q@2A*iyf;%X
zr!*GwNIHY=(nsK$6Hsp$gY}Obb(_=8v|rqOAa@wnrPYlZ5UOP!=e_;0E7`f=-RjCL
z#X=ZDiCSftWIu<%9rMGs2H&Yi&(}B`(PBP2Pb#rP>vAoo*SqR5)fgG>nbNfKlD@Y{
zup5fefdbQ*9daTGkIK<=C3n|PDIcJ(z=Us8osgypi{>Db*2lI~GqbBysXt)DB_!Ba
zX=OUj8FJ(+3)Nv{#A?cFL4Vlz8FTE_&>0yibQR^XG)#%{mvj~lO#*7hwMabXVxfd`
zP;<YkM3d!?JOjDaWE+)vFra(f=%NvEeK>qo-jutopXD9qzh6wcxo@0xrZfQ7_KieR
zB%Yxhx6Cpyr#XGcyUE7g*h&4<AncOJ_wAxAn}R(OJB1-25BTp;R51iTKh2p@NtxF~
zo`5-%Nr6xdyAr5pA~~pP1uDFdCq7%xWmvQwLy7ou1e_<=?4BQx*W*ZZ%2COhYka!6
zIwE;CtvKoPuGIkeYA3v<VMifuBYr6d8&v=`d<b*O@6bgSan9<S_>pYEjlFuem$p^a
zj*OUwn}6G{4tx;;Hv*5ry$|uD%<8D@7W$>uo5oKB>cFI~ZVZGx%e7F>Zi;w3a!;z;
z^x$^`<U-&kqm%vn=r@D0j^9J-_@4S}Mt47qA&)DwB36JVf7+OcAe%?##dzxiwTu)D
zRaj(3YwyU2nJEG=(N3?6+e^a!F7zf8IZB&31DTAdU@miUoQ6d@!il-45u=)GVung-
zc{ljs)0jgwZ#U&3!n8kvvs97nLsxUcI};D4UO%uBBK);b>ye?b8!HTp;E)5totE0j
zC@GcyF~vaoIUC;So>kJo+}?bn5EZ5SgN?iNgSt3I;RREbQSEvL3JVJ{N3vdcF1j5;
z?m)CAqWonFA=p7KX%T$foXk?5(V2QjFL+)j^rx1p=oe%$ev1Odxl){tmft&r=$E}V
zgsZgV4pVxHbNAqcsaW~Uszyd;_&|F~%gRfF1m+9qyCiJrJBVIopyfrRZjD46gaQQm
z715g>B18QyWJlZUh3UXJjN)(`J2?>$qXlVc%mGc6T982Ge~ZWg_+g~F^vlU_sv=Uc
z>NP*JJBKj?x4PAB21pPkUUww(+8fFH4Pk$QVkPrUUs{ooN{!B5J`yi7Bgp81QHzsK
z>Ovm6LMBf{<^9|ev8`A$hfM40F81NQ76Go*Y_x!*e%_m}@=hnzb=SFP;(Y8_)LC;!
z-b#mbn^zdiLB+w<p=L{gB^7ydMpBb6F;fA24kJ<_Mvj+%uYa8iH4N13s6u|A6N_NE
z<Js`x#1_^i*)ey|;ITr;dK~;TnbMZM$fEZ7xbig+TF&G7!FGrl<v}gtuMDgDDW37`
zUYg{XVJ5e_-?b8ywt}H(^g1;t9a^o*8-Q;vYx%t{5$3~ih&-`#m<>ncj7y!#&m%vi
zCq_augEg!0&<FZix}d=pRqg7eC_|Au8c|O(6%8!!FKX^{#k=|vsAI}6I%ni(?^JEc
zt3)$bgDnlf2Apw&ywtPwJ<>Wy(c?V&W&#w>3}bE0USyou+R7dW6GxR5w7u~KjScg5
zZ1`T6(u<{BE<JaqAv3Q}2gDTP$D>e>Tv}8*YWEKLO%CQ_5_cb5<%zLGx^br3fw99i
zp1e?}WJU+LbOW&tC6f~)j$7A0%oS|-z6KfdlPUSlo8D(l;{+|(FNo8O$e7co_()X0
zK%2yN{rtt7&7$fEV6K95Zz@@%yb%F8g+NE>(&$7;UtAbk_r*|78dk(Eps<^sW)9>!
zhpgXuvP?Ga)DD4%F&AuXn@|p{{`{+GELO}Dwu;W9f5D(a-dD|y<TFJm{WX;ci_T&9
zty%4#dPbljf{@BGs~*}O2$d88OJxwSQR{&!Ld3jt=*}j`fxK|Rx;VMW`?92Y;{qfG
zP7>}6$%q@$e|3}u#VG(R2g>Jz+Ck95!cqHrxlNNLnT%*m!DjF|dE}>p(HKlcq%xYh
z=ABNEcuVrgi1({hg3+=lCH_{A3U#G;8h;dlS=^KJ(l{9nSy^xy^2$b`GnL76@N*+)
zU-$z3Of2`4ZML*(ibbjPqYp$)4wgM}dBjdwH3!r_*3%ixB#PUXP9}wmTDD%0oL>BT
zU;T(O-z|CorK^ywg3+e0H%bce`0RQ5%52GFK&`BWXUtnIjlVwMvgw6VcqecFBn4zO
zP7YyPpgc_X=_tLG3+RS39y3=MW}B3hXEBtC_fz}96Z|x5oL6hZJA9SEhkIw>`YW)|
zklhYJA-o7upO9zMML}Ss+}`mD;f1|=RL~;yaTBkiwS=UvWR{LRaB89d?EFd`se58r
zK)I<p1P|{Pm@AYpk^3v(2rl~ca1yuXGyVB8JQphG$Pv6d!2!bcRg6ZS7#K?a(Kyg7
zdQHRR1J6yCluGlVQ$UfId%~ecc>@Bw&d}U2*Y_I`%w2a@y|eSI#ak>GyzwB~LHxDz
z-W<+hvVinsE-i4%$10@qj1Aa&<7d7Y3hjk1CRD@AWZPnhi_K`R@Gc<0{Kh$I!IYS|
z13V>;oHgzrBI7|D%E!8hLO$$gdQZy%s=#jd^^MY+?H@*m&x^&ZjAW?PUDo<j-dxXK
z;2-^ekY8r`YwK_yOG8kyK}l35wEmXxmTHbTg33k5!w#OTTiEFZ(`BpB61bp{&o8yL
z&EwvD>nxxCWd0+LlNn#yLcx@;qxy|la!p^-`Uw&#wwo$xNH=)1pl5f6<_9YQtMI)p
ze@;UB6VcN2ka7sfbin1_h6mb8TzBJf6jU?Sf|N0C3O#bDDC^+wZ0$S+wRKxzWbmV%
zrB>Cgpstv-Whkta$kgC(miA1K$1=*X#;#-i<p{L6E(+ieAD?}Z=ZwufpEBxK!pR#7
z-KYcG{8mC;R6!4N1Ok8AZo(nWVi7(#y3~mE3SF==tM@^_BC?q&1ULBjvRKii)K*iW
zdkvUW<2f5MLZwUpJee3o-O2qOtXlNMc~Rl2<+DzWyRak}NWH&$g$>>6QPccZ2!^^K
z)|y|AL)%E3p$Ev`po+Q=#J`AZU2f{<b$|e>>2^YrHl!gx=8j!{{!w~zENjf+JLUm4
ziA_pqXNO(-KcyWlvmsSKq|Tp&PbIzYG_$Dodz1F14!qaTuAq_y75;{I7?3lvx?@$4
zm{7GFT^*yz;5>?Rt=h7sroB#IAo%EG4kNlX*_sN0y|{fpA(H4p#CcbZ3m!uxM?EI5
zG!mUqM57r^L<;9cHHEVJ#@K&te4U!|?5TK7&9lBVVPlUBSn*W^*EYrIeWSYyf^v+1
z{q1Wc0E5WKNhp~*u>XqHTQ%q(iQaENsva}(wn_|8*bQV+20ir(Uq}Xtps~AkPMAS+
zZXgMOUUwU(T|mT6*`U2#Vs2n#V2>i)LFV4!RcHZpzD)d4kW~H!9g<hqHm`Uzpk8<`
zC1RsVjCe)Yc-NIN!@csUfk8r^Jyw7qJVc+CxlZh>Y#-*(CSzXoC$e!3yA6qx7TZ+l
zNCkx?e1PuLL=R}D0kPk8DrRAO)6UGMTL)<xk$!lyY&bvNqI75)8^^~t<(GK5%z=kB
zh@o-S5+EzX<&lmvOVuxWzkp@PBL1<g<huFcv36VS^(Xg}yG#TdnT8T`_^r;ims^&|
z8UmA3+DrWmrry0K+36wR<2_gvVa)4Wdr~NBED8GzM!`X5%p*75#-x8O-UAgBjOi{j
zmIrQ4<nWlghb}Sxu7C_=Q?mHbd@TSo%Ep_r3?LVy4R9C3+~fO5Z#deTm$=6e0|-CV
zb|m$K*t;eO&pWefn4u{VTsfL4L^~%FW(`aQ^niG!0V+|4!*oGNx`0}T=!^tB$z6Ts
zC!V3mv!(E+e%)dmclx^Z{?w;D!srK`_!Y(3*4=N`QwWWIrs2B8L<LUi5uVK8Yj^_x
z;;2__T{zplhouf}q8Y<PHBet}Olfs3Hk2qo(3l36zDIfRIA?_8%Cy04^Kx_re3U0V
zc=7Xr83x?!E}FSZ4X<XON%vYt)?kq<!<~il=p@UHf4Mbln<jwN>%2GK?4B%Shs*dd
z14eqFnHV4$Y0B?Odc6fWO&yQ)1-z@b5{X0+iZ3Yr0%>lvjn^j{6hsbQ7#Fqn1h_=q
z|Jdc8jaToZ@<EguCMt7@9V;ij3B8HzgKR_8czJPV+$k4$LaMmOj;^WiATG-(b5SM^
z4n<(OZ7U<G;xyzO$&%Fhx!_c>ehjsWux2!SCrS%@F#6<xHx0uy(Tk9l0=`MteYV_!
z;D~c`+=RV@kIO`c9c<i;tzlvz<xmY4mNd)rP%Fb_6xF+qPnEg*_1Km^4*jpjq(vqz
zMVIfo3Bu`2A_n_z{A>bzj4{*>;ZcyCGIkQ`$J}O(v>^!M`o>YCc$1ktVTv=aX?e5E
zNE3td+uIz(i)%B{cAU~W9AUa4%_isA{b|Kgs@R=qqBTmH!%)L|hV6u~O==O$0~JEU
zKhgw2Pix0A%qIoh)J6s#7rB5C8pc+v=fmdM@9zPWm8tXY*`5HMG7Z02^P@yMbnU9W
z6eQm!6c{yPzILOOX?_w*`Eew1H3US{Xu6x^9bdsK68BkO9LN)~XYFj@prIx+zeuwq
z*SEu8<R+r*99ArsKha4agX<gN^+P|va4Y%Kt-uMfQ%o|?CK`NDcTV%?Nto0Sg;jt_
zxGk-n50m7@Ka+1(Pg;>YmA&#O^{Q~jRtJA|B_zS1?Ty%jA$Peh(q1h9Cfe@4{IT#l
zYzPj%8Udn_!|EU4c}}uv$Tv<){|sO@Y$*qWrzbg%j^gV(#fpp%AGs?mM)lc+QCvl<
z!h7B{rL<|MkLcSDw}=&*30S+sna9pRBa8_kprs(zZMbF;Y*tT%#D*;;^p^YGb)<e8
zfw}t!-AT_W1Tc`ddETR;o3Ke3TR&hY@;Ii0di?guYOUhVAboEeR@%w*kCYb|H5M$X
z_!P+=*!{f#Wz*07(NwEWjNUM*3flU}0q}G>mhvSoxqYHG@YAoqMGBpsaAjEp@~LG@
z?(}r4Ixh&^%dw2oK7WA8U)Z|})DLoEB_Nngpt3EWP4X37l{HkKoxq^Q?-PWy(Kgwq
zgF0Es?B9?yZdaF)Vo&5&if@Vo&!a2(d|g=e+CCtUjrP{$+cu<6a=B?`2@YW0)r+4c
z@zy|MoVJK-e&3c!9=9UL<Y9}fN~>k<9e>iRI!!TsRm)PhG1!A%F=OF$NoAAe;pY@~
z8*XS$Q#z)Uxr-ySTbf?`tv?eI5ig)4qi$vodxVGd!!IYOU^B&+p-2RrB#Zzr!d{2k
zWa#|rOYACAx-M_r!=ils9~cWy-9M)q*$ZK<jKfH?F(Jw{!FvG`dNx#x)yO!uw^X$X
z{-g097t_hCfkC)J$=i+r44{d$UVe1lg_z6>)=bF5)Gee6JD!(InnP4oB42>*_*@;I
zNV(X<k6qTe)z|CA`{bU^9V*0-5n4XL_ShJM%IvAk&$Zi}(Qnd5Y{Fi`9&ZoSj&$1C
zk*MAM8@}pnUfxqZVp||w&`=bls1q6{{7F1b)=ssjhvlYYo(E5qRqE{s95sfkJ36R1
z8!O_i!Aw4CCK@SBsp_`$98O;bA1S+0aLmKj18+?-ORfCNI1GE?b)TE?L<lpF4{fCi
zto9^rkGGsVDGScqv3*#ekc6(&rrIW1eQh4}U*5f99px5QO+03sgcj%g$RWvfCtOZi
zrdBkDF&-Gq3X8`MUiyEMxL|VTSP#mm9zd^EOM2+z=`CcO8Q~=~d=!fI;mxX@F?<U@
zjn5=8$EP4z12f<;5x~8WHYQft1g0EEYgUV_-hat(l(_l9fttwf=d{1->|~?1LU$UK
zMQG(ZUMBVGEEDSL)NBU$*1T)bjpH2U5h!EJ;&BW7N}NuhAX!k8f>)U1QZRk_nBTHF
z#V@^h77>Y2UlF;C@bo>zJ1LSj(2)ZFeaUj$lxQ2K_QiLS3xrIDA(Z<+-px8OtjUqn
zhN+n1kG<4JwsE!qS6RKBmGBlieDxIOv6G9lwZf5mr}Ulbol>3sUDuS45{2yUvT)qe
z$0xX&$jBk~s%FI<ZGNh>(s`z)0l#UI-O*j&I!V4?OGAc@OD*9~n!P;1jyM^*HLuSA
zzfD`PhzcbNGs-N>p`!6KXH~s_^XlPk@(M3ftVNS!TcPH7s^@=!QzTI$x}c&i>25g2
zyH7)!U2J9R*!|I;uU07L%Dm2g@LyiFR8KZ-<&xLeWH}iB`m#1nOT*n`&RQ*{rSbzG
z78zcQM>AD({$&F3(KRnRWvt&0C)$;pMWfygc``g17%yq++{dER7O!URwVD8acI+pd
zs_hCD^tG+udc*})`Rk3Z%G&nB_#{Jg!ulZ3VE~M9Vqoc^$48w_Y80(o&#BnKAJvwF
z&!USmkeQdEg32qIcUM+2YiFs<730h!))Q%QOLXKkjka};Z=TfGQW#0<X$!OJLL4S*
zrH&G_P)t=Cwp&cP#;kh7R;p1~>HbgtN|sq3RoHc<&$0jNM#$LlDBSccT$71JrqZ(;
z52sy;EjQ)#SG;Azp<B`IX*(a<8$4|@c5$Nw0?yh{Yi8Kas_8pb`Z^#BsXC|q&w?YK
za77w?MoHWg^Q@?;@HlCQZaKPP5X)+bg`h6b1Fl>f(`Me?^<Km*c^iT=i#`6KZ@&)E
zifauHKleueyeamVdIa(u@%7<`)!I}Z2=0J#x>A1?o4x>Y&xqV8mAA*TgC`sMpIALY
z1FSZ4f0pgf(@5r!$-+^oY0;sS3~(l*&I#a71{I}9uIeU>KeUbWdMDpZquZFergI@x
zXfM-eN{&l4OZa~OB>QHV<t`22LIRXL!Pw2|A+(LpphC9w_X2yTRI>O>Oh%$7gRXAJ
z3^#gaEM}ZlP-l#FtPKhv5LM;48t%k$$)57`ysSRag0!8L{TW?Q4%cY`rML14SGC)*
zh$B7=E%Vwe`OkbMCS`3W@G`&=JP^RUdV(-8^z#^7BF~<AR&laV2*6y;XJjHbwZR$f
zl7y$wNnx%*QR8#(#d!!!0ant=rr(MadO9|Ly4}qv3_4(JoeQ8F$K_M?jrjM7Q_NJG
zzNz{hh@sGE-PZlQ`=#n52g?Wh5yUA>MsXLWRYNF$yutJ;=lZ0o&&`=9Txj>_PF4xX
zSLqox#HgVTop_)Le%sg)jpzzW3}gSTA#<(?bv|r~3GtCwJCH^s(p?;K6VHRK3P(`#
zR)g_RHvZ%Kdr_8*jbA~GetRfXYKh$1{(BEge+;cp$;;~PP`ELfIA5|Jz8jMI`gI7X
z%DQD5eK0!qN0d;z`*(omp~&GhI-$9Dgm{jG&^aQ@&ID6y_r3s+XH!01#a#)()9~!U
zLP(bP*a4jfTj!e(DvaMC-@%6~7`qu?vpBnw;gN$RLUaoLTT}?Vm&wG1@L(VM+&Man
zoRJfXU>O%8Mdoue-b*hkOno1{=_$GzDhR+P!awP5c3cxRR;!?fTJ^q(_~0Wu2EW1>
zHBK3)(=S_F&r2KWDz6wn-GbQ?G?vPnihgW`0rAU)?XF#WOdu;&q}>4!bgr0P)7()X
zeQ>Tho{n#hR)v^4!2$Ia>yE%eRQ-~3&7M6HWW3O8hKTb_S;yJp<-6e0rTX;RUcV3y
zJ;(#yB=8`!l2t9wB8hl4Ag_^!1Zl#ZA0hEss?o>Vd+10V5x^M27Zj471&^~@#584A
z&2(%Xv7~`X4L~eN8$7h_+WfO;fv#0r4V|x-%|;`?Fagu;!KAZ&$hn@XeCD?|D=l6!
z(B3?g+l$VeOiCJVP9twQ(YzlAW#e?_QR|@SqA=A`i$y;!=%Zp#F28J)gCNz~lbs|?
z9%+#5D>MeU4PDB&BFWPupPVOaW*gFJ>^8@TG-~V?H}taT7GOZ`z>?)%J^S83+Fd_n
zPb8aEg^u}y9${wJCf&r6v-s+>Sw@l|8S+S)0i@k?QBu8c&az3!)bFECB=fj>$Ms9|
zR-QTTs&O6Uz7Bfvg*x9qVc$1fIyd#BFVfNgQIGdb=irmE{WmoBqo%Qi7l?;Qx7Gn7
z!}Cs}Yrf*%ji(pu>TBT(Os=LnGo=I!3snbNJSmCH^8lq-y$Z5#23oB^TJZAfB(Ch=
zFX^c?m1-{n?h^(rM>IuY@E>B3<PZc<hrjuT#|S3g;SQC5+E5#?R6>#WD4N39?C-4v
z_5`g+qzGOO2Mzil%u25v3uP4ZG$X9bb!x&XjWB^KN3@T52_hzJLkN@BuEr<ixuie&
zBg$sti@Io{lT|w$Hei&^MeJbx_Utm|ZJ9qsKt_WLvYBCObMnH^@X@`o51dzg{u=8V
zhyQ(j4z%)J(cc(S!aOR)YJ;Ds2G1`5#)V(b%~jLND(q~dt3UFLDQXgdsQbwOgy9Tj
z=QnB9W=rl#R%_b&jk$#7p8NB|fBi@n{V(M6>EGY!m+W@iR&1(UwR%ON%7SdD43SHR
zi}TVjvlx%|*F=HR6<1fE4_=nLf_0<0^)<pMy)h!xG_w#Y!CfTyYcD<6*h?;N5#2?j
z;LBA4v+HnJWGmWk%`fdpAd<eCajT;c$ycm&6r3B91owppOOhazeGayOz7oNYXs!+_
zIH&|rl72DCiWWbiLOq6NL;X5*RG>{z4Nd}KPHbZI;KNd7Q=n$^FHC?6x)vu!Xr9l<
z{?Wmsl}BvESC%vkOsA~-5xl58x03eZ#j(1cR#)|bO?kc7dXXeHv)C*6i0D|}7^X7-
zy5mjMt28^4a389N*##0G{gMph6!zvB3dA*H&@6U*3wBGG2**cbPaYlT^^*Qd{YGy`
zd}W75?o6oQdRJ>U_6;;4kyT~P`S(gbIxYO~z0=S35w4y_z?NOx#O;bEsUH?;>HMt^
zZd#Q>X>L734Y2kT#9(zW>3iEtbRg=wBO_$0N(D<ede3BVD-u^x;lM??=H!z&j#mC_
zuRa)ji^eB220q@t$w0zCBitp~c*;Gn6x%gvZR{AmChWiR)(jY|K~-VB;QPyMp8O)y
zaSzCfp6&b7amWcx-u}bq!gt@o1f(^zRMrCO{@AnTxF(h$Hs~F%6Y~!Ze49<rh7-<?
zD@dXA*PWb!cpI~*$iIWc>8VAyPE-@a7R&I&jo`uUAvUyxNtV3Ln-ysySPVI}!c6*X
z>_#5T_$5PIGEG-)`;O<ASy^c3h@u8r!^xjeasoOE)2683fZgiAA_QfK(^D>NMuG+A
z^-~+<BN-LzB&SL`@hUC{227OBJs)r2pIG=F)CLcVy8-Y_Qk?CUJ+v>k+xiCpftMUU
zSt^9><Vs!Y<gZj#J1364aZwV2he?DqD9Crq%zK^VB|#q<JVH5){mdQgDJWyByi_h)
zK-*?P;|OR!13Y$~@UGKs_{*xt)tC%pJu!p}@Ca)Ng_`rw!ukkDA0=9kZ$TTS{@jZs
zV!P?h9k4Bn_6*&N#@dy3)e$cf;ce?j$eeafo@i~HpSs{u|2ngBvbTp_!hMY=#tT8I
zmj!Pa`A%@ekTFj!^nmbnG`X+hy*DIGYGLgCm+TqQgMWp#9au13JzQ*D$TpZz)W(%!
zAk|{JX>@6i@ZSS)Ks~_e1J{+hO^YinCo08uWO!X<AS@qYSz82!Z!Q;rP_s`R&F}N^
z4@m<&b=}kOI`;#3eKT|nN_e7T5*6gox2y%;7h5JVk*4EkDzY?L4k`*UApwyLu9`L8
zgpd$&nOu6mP^oc^&G9+%lyr_;UTRUyxyIM9`op>$Tak!)PiU23nYMxT5IeMK2|yP2
zK5^rJi^iIbWxeYM!&$OAm>}qReZ}_BlTQ~Gw5DK0GaK`KCf_l)g5pDknyn@hDSjw7
z%}M4Q8#)fcOkViubNcsi^c6J76*Z<$0{S09d5iedM3fpZg=(6>n<Vl;e&y&NYN?#N
zGwzLmoZuW3Rb`8IpOf0aOCd>SwfrU9c=vAQ*@MfyCK&yU&8I-uX<>4X=tQ;4@xtPI
zG7_KrNSHecPo3w)HZDj1p0O7o!S*(*DyusQ-3f#^8v296-A-mv#WCxh&Q1t*(gMsF
zEq4-rYZrVI3F=>^u-1iWS|8mO<4>BWu33i$Y$}z@rRQtTgwhFJsx7Jh@Au<ScG6w}
z`VK1`@(G%t7mCEsTeIkfK#RpE&YKH*Aej$szx+!H_j8KWs`ITlCH6%+N0oQ27e^=V
zu&9f7vd>`*2oQ1GBMAiBrs)ytF@A{U#(WpI2vl%2ruq=orq;f@Zm|vF5MLc<JcWw8
z_WeO8Crz&i&wyE!m6EDC4}}~xgaW?fGR4^9mOBwCrfVkU&Q?8ZY=mD8H-q64tDk1Z
zr80Z{Z4zxTU`v=jOl)A5P9XGvZD3x`x!+Vq+rxz&`w#V~IPuNTtYg;03Um_<sFV{t
z?&|)Rx+>3GrJS4ZXD>cgdNI-C7soFDv}XP`Lp=C;qC1jkVq);+EVTUHBpUfu6-*Mu
z)5P-fDFSHBhzOxn$hn35WlvAHd=;^dd(Bm+n2%9g*AI{?#j?4A61B;H>wBwN%k};*
zCxl##Rot8uTiP*zHxv#Z;g;|&`KEwhi}=>qHcNdA+DL@q8H|Wc7t<G-w)0%hGO#ya
z6$naU=%I&OlLvl;**Bng1JsE>$&2is%0I6oung{kPb>6Tnpl_&ZYq(a#+;n=!Ug{A
zgU;kY6IeTCO@X?O2A$B*)PP|<1V#9}f4-4TaM=E$xs!H%o^%A!&WPMwW~%)mQ|_sv
z7$pw%+=>?HNU5lVpZ$j6B3j3GMw||+qkoaE;pEC(nm*#GbxrE$W1W<JWm%G$vg#0w
z#g4fwWk*^6{3eIgzHXLS*`7?Knf1rn(t^%FkdeWV72>W{hpSwdg$rxkzb^cA)Y`^>
zZh;^3b0C2nLf%lLL8EgRfsv%Yz}EDV7hPPf==~c*P~agJ3baK(0&8JEBau8(FK6W`
zHytSvf&SzTH<srHg1H95iMwK?yF2#j6$E+W7}{Mela0_b)yGP+iXg?-9O&c~dap6F
z6a#rg+|h?eToV8{rBxmN9-@^@tr`Y`0oGZK73QJF+%*Ejnub6v7|>s#*1V}`iM``1
zQQ=%bD%^f&D`*dANk$y-$=lHMhnXr~_YzM*Ig#W%*yv9h*7qx(bgZ0CCU!aIoZ0_x
zu#i8bB#UDyc%wz8=B-YiSfCKihWU(2W%m<}b}Q&dfBd)P@JC!M2bH-u9DA|IgR1q<
z`N1KvK{n*syc)d}oURseM9|J6B|_BwM5s97gAgDHzi@U928@HKey}3bznUK%I0+^~
zT)Fv)CUIteN%CUA(T)BshscIALYYWKF!=elS&W;Zkg}TYs+OMB>_HuF&Vu{%8NyV{
zfHN;SLYOp#iaB~SbmC1qD7?adI2y?R^)JbWP%|-wZ2WJ-?4(PTqkA^felEgL{mB&!
z@m(~A-kzXy{N~^WFbh#1Khh8TazajgJUFtYeSP{UG1h4)prRyp_{@I}WTc!_EA4m>
z`mF=55S+qfw<=5u=Z0e@{UNU?SCfy{V|tAM>XusXBN__z1YOAiN^&kUNK1U`UJCTr
zf^M+wJtaGdz<C*Liuj2mzG!c;2g%@AD3uxGH`~Qlq$gIHiz102{Z-<jDn}J!P~V~&
zpy<k-SL3_e5YRUZ3f!28X73$18Alez#;fi<jA(%8IsJ^Bj__c;=jvus?&6(fd=Mmj
z!Ck1KFqL4brOo?_{MxQTfL-{di}U)zERSctvRxx63ezFxjK)P5{IBMq@OiB@-ID1?
ztkfo&D$05fH|bF_xjB)t+X;=@MfJL$&AxlyYQ3uDskNHPQJ<K&kKs7+NSBDKaGc_&
zVf>fHP;I`cbQ_-P1cRfM=cdb7fVOWxvGmpF&X!^wo)+)EL9Vc=apU?uz8Ry2U0cpA
z9YKSV&_(Fin<AiJ&`y6Xkb@^Xk3(muQMq03S417$ZfIcifpr8<8pp%sBjj8I2-+at
zev6fg6-qNNFj*2VRl2TVH2qPa;gr|xn%=MszD~;B{ukKQ&+@*~eW_rw@9OMVbz#=u
z<H1AZRo}H-<WUoaP=0P3qtQ#+%I79?-)qKOKEP631VeTET!i>sZ&hFXH-s5JYHqox
zk=?*wG?*F-C%syRo1mG*)M?hf79^=o9c|9eX1Q!1C58p4VZ#W>OBt8bpsZwg)2%BV
zsAI(=4*HRuJQLv&XZ?)NY-m@@6{>4(*ej&;<%307oNIHP>h@)$SL5%D0z3NNVn!~X
z|MMe&w0ZbL4fz^*SAFz+<&eBSxp+Ycg&h8Ou{oaD{Zpnrk1zRhLnuTmAw7nJtC~Vn
ze#WD03dU~rYqZLm&+zC~!`Gx@Ue+aFk=J>AdgIr4u^FD1n&%|pxiG+Za}y<+(Gjux
zci>n@W^CO6ZKE2(|JihBzL^sz=cTS(?0(4kk%Lk?@BQhPi5v!LaAr$RqHYtK*sGTE
z-#gT~jUF(1`2yn{=nnE0Uyc&A%M37~W10ot`iU9sbg%|XUBm|0ceCHO#)xv^T})%)
z=`L%XWkT?N8s~uELf)UiX4ycfZ(9pAH{0E{Ek(V-Anb)vq!2ykZG3;Wdnt!5)5!h6
zCi`k5=@8;3IYiy=gJ0EX-C%G6g#$a+!Cf?v(H?0#sT~(IB%ve`aw3eB)Ti)s!9%?q
z(1MsfBDITemPavlDFu65Eh{{`Dk5VRd<GMncVp_?G3qBA!&U>9^Qr)W8}O{_N#d}f
z(H0{{8sSQ}g0;^JYRSwNJ|jx%zh&3KxwYsNR%JmPoZ;Bcv-_`Pr9O=gxM~%{#0{U}
zAiPBm-0K_(HRRw4r3~u%CCX?}3Xxc87+#=tgCP`B>;pc2hQ3m`hkrp{vap2~U?k{f
z9mOgu^`u_~B5-gBG(E<xpUa20Cl)y`r}Xm?gnJ&ngGljM>N_*azz4DIN*D_a_J}Js
zPWi2+&m}Z<MQT2!_pVbLx|Y=o`Xbiz_)|EX<VWmHD)Ik#qSq8HOofZw9}$#b>oN$b
zFjCB_fVBoI`qz11MC5=TO;rt_HRN1N`iNq2caVkr!!oJyjwZTBTh9K=TC4vPP(H~0
zxnp%adeHvb;Qdi{uvofXqbQr-NCFzrN@!(T8i-^1H^G}sx)}^M&wy7WepCr}XkcS&
zB!z1+HgERKe*$$D2=6u7qYH!ylQmED`-?HaNZHoU2#7?~8C6+|a-GrM4Daq8jr0wN
z!sT})06f6<Xq{d&{}orzicHLq2hW2*zA40_?;FaqI$(xWyWcPcF7(J!J%ZXv9d(HV
ze}{P_od9_wKA8LznUMl_WELqz6`FStk)hznbYID1%jWwPlBPlYMMf2`PA7`JjViHG
zu(Y3_%VH8mx+O=A;8!{7ySK^e5-O~~Th!Fs?@Wfg|K|EVJVuMwm3V$266cHFLmRrL
z)`~04%<CNtKTA+U`bMqFz{U_&l$HORRx5U$<fOw{d6>gpWhsn2R-w+@G0Ziz%p@LM
z%4?5Vb#)OuMT1dlbgOk@?2@vdQJ5sX^%(s1hCfD?P@8nZ9RG_gbTu>RCyEe-Tvsh=
z&izrj2Z*U{C?Ri`J+;~ddUA-jFvb6SY5c5`f!w3n2A(`LDV<LpF3v>~x0>?N#pb>L
zHS7{cDV2idRw1P?Q864VgT!g^C@7u1!(0DGg2zLff%loA)ZnJ1arViO$HjC4_!e}w
z!G({Z`qjcPqq<Hi7PaOu#heZe#R3u|HG}+VX(&Fr9$0U4NQTx`Od=X%K;+4o{-T$a
zz579Leu)8I_e`AK-Umb^8CI&9i;ovJBAZZ9+*p+e?3KKv1`mYzb0yNswml0c;(g@k
zQ7H<eZF*!n3y|sH*8w#_T}vk%)Tk<exSj-Vc=*z!ygZRb(GV4BdXqL9+H;^{Wp*T}
zh*N$@UsB_M$|bLhl*H$=v&+bHJjdcZA>T)2wpLetBT@3$nZZP*<GwYL0XG>-z{fs8
zkHw;~m0oB&XuAJ8a!Uc?`KV^gg^n)O{KWcw+(ldeO)q%hlWOr84Z0%!0&q8=0Uzrg
zbZ7s(9U3K@(`>h{4C<-kw^&AXV8E&H=g<cU{9x`oFMOKM&xKU-OXA(VMx(|o3$evg
zQzvaye@nOT%~Ra<0_~be7QhB;wpRqrE1U5~pxPG8<j?C`IyjBzy<(Q)r~<Qbe(^Ff
zzF(wHa=XYDHo~?>Bv;8&0V+ejyhb6ty@fH%7MZLKC;pd>Le9V~&C(Y2D6QtMIZDNr
zVeN+3@^w$3=0cp>nXVk*73Pn(sQPpeQVH5Ke;M`+=f1EuMW<HnTSHp)WBBR9Z%`IL
zisXZouF5)5GksL>e)qLQN|dRw#Dx2iOQko82aifwG3u8o6*I088CvI*6Lw~wsq(q@
z`UiXeLn-?x0%Q1uGjM+P+jZ7M${D=!QvW;Y%or#Zcz=}pN2Up#D^KsYlw7$@AKL-u
z{ju(T64-P_IP9^3q&Q8@kK!4cZ0u7{2OyET+Ixtfj>|`n&H=<%(#Oha$6$LyAi99E
zvNG%SJs<RbKk#zV3(cw3l#blJ6x=Z|P=~ada`ZLEA;3f23Pv#<zXd6uo&k4$)yc0M
zu03?too_0Z%O_S=rv%i+TwAQD*e2>-hfiVLDBWh@aTX_OBmCV*C{G(R9zJ%cd!XDJ
zCQE>DNs0MrRuRJ29c%Zr{>><s-Tp4b#!#sMywmPxq;LICg%$&nx-5my3D;bfl1!1@
z?rBYGMYDIpPc!RpbhS0sRFo5SX6KK$8Fcc<$O=AEvo{baL?&?;7ugMHXT^5!M1a=k
z4&JYgk2$0Z-0B>G)`RWX1{4PF$L>aS7z&%Ziu~EJ>F8xYo(2Vsn`@G-%0@ZryzU^^
zJILxbp~1uCu`@I)Y|#WYb3$XzW~QS@dRad9mgj<hekI>6R2Q>JUGL>);%Db(Hz1`v
zx7U}nQzIt-Wq?_uRNafoTGr<BaR<aDzOyXDg+s)z3nWxqa|ghorfQEThAdh%NF3bl
zw_$lv+#)pRCpxnb!}dO>5(HTggtK$sSyqAG^ac86#$slJ>W``u0Wp2TpW4v<h?Ff@
zS_{CUGeP`9PrEK&yExbFfVl>ABn;#O<r24JSkdxv$XMVM?^U+0Tj?yIPQ<kE4!;Z@
zrhKADfO#B6zKp6Lx6Xm$ylJ;OMgh^dDhYiiOi%k-r(sVUMMmS73oq(*;Qu}pu!g2}
zs@Pj|V_jboqS<tm!JDF4G4d2De`fV0>}$&f(P1LmQ%&Ae0mzPzHnOBGUqrB@sY7M-
zca6p$E|JAfa&;Ks1gP@hXxT4BnZ{`;fm2WUdFB)xA=s*?x<z6rQXG4hO5*SX<=60!
zl&}#SFUYc*C61vQ78d5W$D7a22QPT`=V6l6h!QgsOCGEGq^>^)uLooy4|+x-hjuGz
z6fIGXH?@a&n>YRo<Hk7GraBMb_YP|6{fWF;>B)WaCo%U`-~vSNQ;il8G5DVfo|@E?
zw<S*R201SJ2iU5RTPPR3p*%9E?uC|;$syQ3?pgoiH=)z@5IZCE>GRYA2aTgkMui{y
zQW+Nx8_3}qOK$s17Ep_mykXeSsAx;3Lj%UJ2v3^w>K+%K9P_%(S2R=^otj_i51AEW
z5%(6!FfQ6#K#K?;@O|kkjW>Ef$IWv1PPOUUU0`7<n$?_PPk4qM^R9-@tp-bU?IAaT
z2{;q!WrTs2N6^Cbxf(LRA6vT#ac?*EoRTP=P|Ksz=wi#F2+}8l6LTuw7@(yZJ)WnE
z9kATUth7pwSH{$L#`60_ibSnkZTb~%+y8)GR@HO4eigr_J5Ry=Z<x_&f?kCeIN1aU
z)c5pq9=yC^#@v6$BEN6o2sH&XoM55E`}_Wkvlo_t0k=<#w}z*c-!z~-gB~4H!x*)T
z__;EORHH=dH3*0p2-xTU`?CH+;3T20Ru;`$fgUe-W&YP_3-0C*sFp5HUxy15e8;Gj
zu22x+`H}{i$!~oyID!|EOtksMP1FL`j#)&9VJqGEwc&w#D))e>-e)=Avs_QRA&tT`
zn#TMkNasT3ud7|Go&>Lz9tR?l)8fGn!uB3t>~s#Th-&~Ms3-oUrh_;c8DzK-3Ij#s
z25oOJG56NxHMry{T8&#ao~&F~%rghtY}Lh{naN!B@+lMnqZy>H^g`?#bl|(N&pE_i
zob2`c=>V>LB-mt>eCIY*1Uq?#_xBOWV(mC+6#-j^ol+M$sgjzm!5sFZQ|~g456qfd
z*juB|LTd^DM9SQyIyz5EKdha;-(ldl;Hk&CuCOWF3s}}tPzKlX5sH&%@D+V_nak}Q
zwnAi7)?LHF*<zHx*y5g0W0Be*jk848Cj7JPgKR>9K}?fwy=4@|t=8zHaJ<`*W0thk
zg+bZr%;mGH?A0muOW`cV49oIQnfP2{{s$VpvOlA0;;4{=+U--oS=L0F?P?wce82pI
zfX@0xH@r2JFwrzWx(V2gufz+ehM?f{k};TQb5`;+7X#4$qrse_Ghw=J`^2_wJL%ZA
zZ5tiiwr$(CZL?$B*7?pD?|)x6YpzjMdu~<AB!^d=w~G_6B&zJa!au34+8myV)?huH
zEN)<OzhBRm2uQDloNTG<k%I<dF5s$A=S9}&3ODSgLRuRfN3fuCBXAu45hrs}xdi27
zJOG<q1B_vBtT`bT*1CQ<^gm%yzff>-ISh|BJ5yNFz0F)dAXa{HaAPr&U(f1LKzM-a
zzY}F!SO=t=7cFYtzaH!2(fu6~&^nb|&^>>s=;{Duu<}uifMr;bUO_U(MBkH4wE2Hi
zkD|kkT)Az=g4Vk&8Q0b7CR`JQyc*dTMo((8sozJpDu$gLn5lB12<-3brNv)zN^StI
zlPb`OVted84Kf%g#2#ZzFM*F^dwPuJe@VT;Ie%&s(J3US6czT1Rm=oKuAZ)|uD#eG
z&t##x{-oz|&|ih^EDL=`XJr9-cOZJv(~XE-7%LYTU1S<VQ4IoM>poA~Au4)%MB_UI
zVuM2KblO3~R;-BPd3vOkS16}^Zo&~A6pI`{T5<mT=0_c=cgb3|kA?RpeUj{h89LN6
zvJDlt-8Y1VH3ZOG$TzE_X-P5r>j%x^<)G0~RBg?%{L<2?jF`7GN56ud605X}>8hSt
z<Q|RV^XegCg*gl`q;Geb-^`Bgy8;;u=kBq2Hgqy?_9IiQj7~zrD+ut0#v{(!E$Kew
zMET51lvCNj_g2+3F31vk%oa%MnWjEGuJNtF!hQZ^?(9_};lz?08C0wn`~qq~=QjoZ
z@pwg>5|x;X;yc9brCR94TRMk@z(3pe;03x8E;0K5NhM_q3+>(yIm{s@X8LtU$q0ID
zL6Uy7W`b_YL1#wFAN#^5AoC53$8how1&<BOpEkT<U2OlvVs&n^Qy=ml;l0?BQ}Io-
zUaKeh@eaT(GX#dKAU3CJ&D~>ZD`}+5Q-uV0Y4Y;`GYQ}`9PrKxSzQr9_gNGkc#iv3
zrZ_|LeM+#&uJcx@5Pp{b1!|v$(=HP*q56A%U>T^j#nr7&Qg%!fSnOtGEj(ZT706by
zi8qM){oPMk)bfF>x9H(=^W4B1(3{`cn7DpDqndK5&PG@;5I{Y&YrW)=GA~~sB{=`y
z+z%j8qEYlwV~DRa#UfgWrK$Yc*o|<oG1YU&F>bj7_TbELt0$#A_khcLxPZnQ%V44J
z<p8qmbgf*LfHIv8))!LZmn2?DEWF-B51Lzf@V*IRP+n_MG133SFfDJle_|h8?;0iG
z1w00}4QNUNvUwi|_fMgPKf!rqEpeE_h(@l!)!f3+)h3$CXjDJAVn?Tw7BQ7+d$<KJ
zs5&|KUz!uQ2L=ZDauvUFtr)5%3@(X^lO=yR%gv$Dyjoq%4g{Pvk^Fm=ChWZiCFJQ|
z5H-u=YK|ztB*Q8*9@5H$yiu-k6rtr**NoXb5*O9jR{n^nTa99&FA2PwKaRfw<NA{3
zue^x+X54%CDZ^szp2U!jDDc=Q{F5PXmioE@K*N>(Ea}!X>*&5DY<o<&k6KuB{uqfZ
zO`r4?BkYHi-H}g_A}Sw_619Qo{8TVj$2Hy|$lh~FfZxa;^^J;v$tyP|u&p^Q&1oF&
zo7;6ktT96h^&SQ30>XQD<xuc6n{*|4Ge;t<ihpw*PU;tzj92g(G_#}JMZO@1XfwLO
zJYI||1A7VEioll2z9)oM8&!f9<Nj1XTur5@a`}sGS*Vp>u2Qdk`28JrgZz{f<i{lT
zZ`m{q-YW?<wYx~tzG!W3(g3`AuNt(iyO?R2_vMvV=;jqwR7mHDz$sviw~UY{dj{}?
z{(wU&%VTp_yc3xj*apI2NH#WpTRar`oU3rkwE4IEdzM*6e8tL1%BBYaful>{`&1gd
zu4n6+&>6O9$w-UlFaPIGjD{p71k_hk51i8myr@Yz7jr*dJ8ntbJ<Z6!#jmWUlDMoJ
zYr!r6C0|EPma33jEqYVUMd{!q*ySHh6zSL>HBpqp<g6ht;&Af*)$5Y1v}fOVx|h%=
z9wf60S6sZmYwA?%6R5v=A;1p&nrx=s1WxKa$e!ayToB3ewmz@nafw;YHSP9zl&c3#
z(mCer?~#Anv$5V-rxxsq>LsGa91<uBDyB>C0{Gl_@6=*1gZ)=8RCGCL06L2{-}q*o
z`@cvW2KlT~TpzE+38A^RQ1@l--^(mS&s*=vhB7guSm}`hEf>JnPnL1-lrrK7)Z7+M
z=?|kqNeW{TgWvw{Fa|TXi&O2x{FX3C5*ojW!MBl^SRUtu>j=7Z+R}h9hGca3Q^FL*
z(-TV0OpqlDwT%B&8BRNygNbFB@v{?Mn~N?Et2Zt0lj}77ZtBO?I9_NnI2}91>wUMx
zI8$itMX?b)SO43X+fN2@jSrwy?<k8aZCr3hu$o8G_~2^5CO!V!`gZ$hc5TeQIdd%h
zz;~do*Iig!KS9N7F=SiCTqhd^x_#9i6Nl|>D&=Z2di`kE6GQhKLAnX+G)r@I-#T4T
zF#M|1oM;Pkry5xcgK0xLE;>8|1fnk(ITr3Y!d7UvVL!?*bm;|W!c<G9YxsF-SA@eN
zscN6nRrx<NX?fjMT}P;kuSRgp@LQz#`;hcFnH!Qra#)DCpd(GsmpoC1d_5N62_eSb
za<cgQnd@S_7bS$P?<z6Eyrj5kwp*(^iy9z=Qx~>(RvroVQeix>L@Iz3SLRC@O_tn5
zUs%ivS}CYwhl3a2m%8La@V{H3b!5UOPv;SgbR)X0D?lIElH*#%q`G9NhUO5!>XB5g
zK5TTJ?P*&KQ3ks~BMjN-)6O;tY#_j@3DDU7<@hrh>EsfeTY{OFw=?Rh$Cq8JAd#CB
zRwS?=01yTMdH*;0txIp97<JXMHiIZNJvXlz>;eLS1sMA0{&vi`|IqAm`#21qS3V(L
z)TvGVPMc@`FkRo;V9m2G7sA;FZNZRwONF;}B%3+<VRMS1Q%WP07aJmeiCTnX!;q31
z<bjO(;>hK5G@bk;>qT=*x`W9{Oz;RP2EMWFT|L(dH+YI*KPf3Ib@I^lmR09~)Zu%v
z@Ljf0-ZY8^cs`tnj=&o&kz02#s%@u7WSe@pV=_S3X%(?OnV=eXzy8ua^IPBE)NlbM
z+$)nKe--A{Kd6~Tydh`V7708C089WtKL2HG8qVQrK6gPUI_yB8@QiM7`AxV@p{`E*
zitO*%Jc@J|JT(II@=7S@eiOUn|MMz|(?0dDdaz=7)m9-Zxpl(L5qE~nioA+vEVqLI
zE>WouOXB2(-uCr88Y9*L)tZy_(h0+HNNdjs=qR8+gqI5V72ZwWh6}kjt*Y<qCWR#5
zPkr`U$cd?dKD{|mS|Rsm``e?M%=xz9=-j)REr&4ybQ$AVCCSR)(^p;>?N^y?fjyRC
zvAnYl9bH+7E8D<^Z~bQ!4dw2_dnLJYhfB3F2H)`g>_}(U0V8DVhCBF3Y^+48P`XG^
zCIAou0P_7W^>t&SiP1ruXK-CJx26}Ruad9MS*q5qQzoBAr>#wUH<-3vYNt)&f_aK)
zT!Q2x{);du<|}1W3!7F^sux5%Zr9_Ro8P9ebn3y+Z#o+z3<Rc1vT#B_8L~Q<gR4PL
za8`*hat&I+b#&YVc7t|GNoAZ7$AwHeI8x!Z6{}$pHU^(UE@CQPSmS_&@g<p6>tfX+
z&wdwrQ-sX7C(uqLn9$H^c_=7;6C3~3`#nD1b6&Mef*05!w}Le+9~MT5I4F}Q|2O>b
zEA0*hc_sO!Yq5UGJ3&f}tJ0628sUh3PQdp3hrHV5fte2A48uCXOG%$Xh)48JrR@sO
zBGr|z><0x2aARYB*DymtsOss(Pc4Fn)s>E@04r}4h;d+2fCxp-hGXkgoj@$kfn}1R
zO=G!$r;MhY!B?MQf%4d1Bq$O9C<6fb{fBdueFoXacx%sS+we58yXQBe8-$ltoHUtD
zGg^ayMxhkZM}gE_w&Xagfp!&^u1tv8=u*slvxZAlb3SrC4ms?zR9j*e;=FBU@3441
zhXvCpDeb%ZArPtExoDbX*!|0C{%dFFci4Q8kb&it(wHKZM{M|S`40}Oa5-LIA=|z0
z*{~JD@i~;8H@7u?bb&?cjBdG6Ls-klj8XRnLX}{c4wi{HQum<#k{zsWcwiT-#o9NA
zn?6*aX7lPFBYJ`~=yf)5ha^svvIGNPxQ9Cl51d;%Rz?ba!ns=s!6?SLp|3TcKQ>HU
z{*WjCVxXiJw`b=tw&M|Hg^7A6|GrIDS!>np<*{hwt1nJ1xfM5<S8`R+g^7}##t@xF
z{uICMa^A7G|0`^+&fryr=xX$7ep)v>7|JdZ#0db51AzSh4`VWQ+fzK-s0#SQeBpi@
zD_t_s4B-notPs4}-}Moai=4BV1s-0mi;ryl$Ve|{<Ub|%K>ucVum_u3hW_&8t3yu(
zpyl;IN15_gpy*#t{~jB*wpQ*EZU{eD)HlxM0RIZ<j{9!i6v=})3zXcc?A@kmD*EDz
zxoKAI74?MD4__fdfg}+XHoLKcoe`T5L<508p}zA{bj=RT#?oQ=0_eHFR|&t>xQuM<
z&|SD;Q_C7|vZlaFFEhvWJNP%^jal|&%;|JX6uNa9zIG?aAM$*JIZ-__eP|-T_Yz7L
ziScAqW!v1=6$~lm&&(nfGr<<7i9sIeo4BF!Ckn;>gl56>9GA>~V=&VWI%;ee3F-#`
zE&xCQ|Iv|i&HsqjTF;A}30`9p>oK9@;3-MMC*|4bg8D^}Vi+P!9a~gcv*5(!esFuB
zFj+8E=@<BzF|&<yMaseMxmu;Vm^6gH$R55y{k5y41}P!jD)XC&ot>#g;1Fg<1FtiH
zHTQlAV$2<<)q3hY?MN3;B-K<SKz_fIk6(ld!GpPpKi-7no^8(dZ^!@C-yv4H>-i)n
z3_8+#-#Cm8)Htl34vfx9vOTQb%osTkazuVbD$=h_Fi_$$rW8MB&s0b3yI4Mc$HOy+
zNO4>synhXX_sI+&4=0eqSn?vMBSsV*B@^OGr<A^So=Fnc!-n4|yA5@DIS);6=_y#n
zc&?@iaKM9<583s%(sDh({X=JcLDzb-=UMvZ&TslQg`B(s5y`(&D<dFx72B2i_9qJ%
z+gx;y9Tbi)GP7y+7@YgPb+Y+MW}@OoIEktn-+rZ3v`Ek?00;&E6!;(ETu->6dNI5{
zy)VmPN98zsr*f(%KC0veCr98^{2S<VBI-aZn!pR>pJ~2?V{6}zYN+Aizx*SJ0+`_g
z6a^93DtlMVTMS?k?N(}IR^miDZ+9jT*l%i_{icDOzlnH%!#AOI>}&d0dtu$Aja|nJ
zxZOEx$l%*Qk)$%*6xrr`03p1j9$ssN1IR`XR(N?@06adExj!-*6A!xei5>+0eB;`_
z-7{1;Iz&%{P(tVcFOlK4T>K@IM1i>@<l6aB7Fm$Zxfa$fpB}0~<4^0`O7fUvjU00+
zq;j{HLmVBAQ?vJqZyVzGh9e_xeN9Pl^_(ArYHkDCLozDV*oe-3J<neGwDP!guOYTg
zO{FoLCt!o==YFuZ;M1@6r<2LCV4-cKRRDIhAk+*Z6yFDgb@NHOxTzx*^=wg{2ajdd
z(0RUN)Df_FLza>lAkfXMPPF%r<!La7gU{{WLTu;ZDR<PV1zwS$K>!df04V4`>IMPJ
zUcnaUqZ9<WTT-i|o;r=1dG@|%=^$=ccq927aKaAs9y&H{=v5g$HWo49m%yfI%LWFp
z?^!Q}dQxaUMCsu^tu|=ozd2%|k>vhbswQ2w=d>!N=e06o^TS?L)krWBrg4{LnYs`l
zCNPYkb>IVrv@;6cv}YHO8C#M}J3^C<5Pm8gZM;NR!axia&C9Sca{8CwtxE{5PvVgf
zGgH$h*oY2+{M-dJXkuU<B3ROOI8hHc?V)x4<T5Wq?=d&dkI14tJE872i@Xpw%+cnK
zu!H503Lpbm%>Twi7#+rH<1N<|o6~NVH3bHx*T9zL8UB{qsjrvwLjQ<0Rm6l)wQz<S
zz~AVS(q9&Y*ApZmH(J&0K36?uT`C0vEj#I^zqx9?HW$geu2Wop6P>zx;+>Up>3W6p
zM$J5QSEuKp$3pJ;l{Nyn(+8cA{(?V36;%fS$pL_Z|07&+G&T}YY2Lio3jLuHs3i9A
z^7D<SXwg>b<VETN0#ziQ7y$Ga02K0nBM}+*cNHc-P$XN2IS|;;Ns>G{4a65_D4Z+Q
z=CB${GB*)C@t1}shXW0Aq%Lr+3;u9|u6=ixm0_@(H_^kf7sI}^Q{psKp9or!CCM}p
z_a2cdwVaV1cuS#82<$$5CNmc}Uy;$NnLWeNi1XM*mSD#9-9Vplg(9doSIo21Tp@LV
zw7%2_actsZHL!kFF>BeyZ#`vDVQ8og*+T42_tRzY+-VeeX%A^4e*{Z~C3DU3(9*w+
z`si)J5!Fz}CgIvE<oM0qU-?*iN=;fx95tLo+WpWm$A(KBM?8MRfcauN;gl->mPEej
zJfAf=2^AHLmsMGuplI(%ePWR2bwwgOd5srj7HUJ@-Gb~FhoJKJm2=X9Yll|wS6#fs
z5Tt(&ib%FNQl-PR;USBZv};3ox*Q_hR)Y#F1>6Ts!CQwntG-iX5fE4t`@hCi|7=tp
z0!v*JqXU|7wt#~0!KMG_Ohu!ZMuqoshkg{2Vnl(%zM$Y!mL8)M=#=(M^2Vr@Sv3U}
zEf=1iWN9tI3#uywX3uFSGrNt0s|L4`)M%?0QZPhXm36{`x3-RX|J46yRSPf6#tT-#
zXj(d<QUgI^RBLX`k{qq&6d2^L(Q%x9LUB4l^*Nq!9iPhAARrr}UP|pA$6-@xFK@;F
z$OlM>kVX_xd=N*NQbZau6IbR`3<02I{svE}f45I{eg<Cyak$4u3mQ1nR3Zz-0kCve
zTN{Hy6FOyJd~Vlt!dbE+K`^0j*2wnNZV0W-`RvXESCWDC4Y#o$!y;yoS>`4Opf0Du
zSN&L2Sq--4lw3Jww_u^)O!7p+-H}0W!b#m1Kv8W99OMl7xBc``$+S*#^bJFTsN71V
z)cMr{#4|yUc%>7<ign5l^B;+8Icz2<NtCE@6nzTO*2b#gH*K+wp1)VJ0ZQ$k;Or3+
zP^9)G*IJDh8uJOd0C%hI2Z+b3n9W{x)yES}0nT4RN$p{kz@WP%V%P=Z&|K}|v?`^B
zH&QmBnwrG^U>WC}Lv>r_v__1)<4f-ksr}Rm6&W3<3OkzD0kjwP_Er8pP*#>WJi9*4
zeQ-udU{r4AZOJDKq+YOcNCX9fR!>W>1lR!+Fa679b`YCe;y(&%1)}($6Z6eyWzo_J
zU4(J$KO%4(RJ3TIJBU9&EYPCL8dY@q>ex1$_IkPR8vdx+&D4g6Vs@}Ut!xTZWKZqk
zv8l_z8j-=^NCfi7mVHt|>%t-Z)zvITY5+>*I&gQMw-u@Xzmm(bz@e)SnlcL@&9=ce
z<T6eL`?@2H<vU<YoZv7#PD6Xj8}oFxpgtq8R&SlWd_{SrOkV{bH+aRL-<pBsXaUKz
zBeDKn!X5|DZ3}&^&KjL%UIGU5`O%$GW2T{2z^$8s<K(N-;?TFkZ%`De;ffIuecn3s
z$hAS_fk&HjPn{f%Xd_}uDF|G*sL6Lq>Ndqd!c)=yj1P?5EBE2@!17j+C=ei#WGVVR
zMhK;HknYhbPlS$vpT)B|M#R`lm`j?19E9Pk*D?(7$h|AZ$SqNmu3dNFvR&>jN{5>w
zngP_}p7mt-Nj{B;Xl21g_R^wEFO0Qb{_jCC+7N6zOfqB7(rt?x$1g=#Rxy=gpX~rH
zP9!%@`6Xv5$v7I!yydbUozxv&BfNNWUTX17O3J=Si=lR|t=j^|)Se?DLD&l3)>^H#
zN+<7?b;`Id(=1o=G#R>Jp+qns;U>>5Xbv|88r_C5Tul@aw@pT5%QhFMQMb*M2~kAK
zlPo3P*_p9Mp&!MyKp%hibMM)8x7Ux(0LVt3K86N4q{c5+m~wH71~V^V3(;5V45HCK
zDKe!D!^;0Oq!bqiVT<oDanAxfq2Wr8@sbVDhPkE;lU>gxWByIB)VnWC2Dz%b$q`71
z_fCGM#*sr$H{KRl4QIx<faD7iv{JZB)(=~gv!{FyYk%z;8rR!qZFW@<#;x3OG;i|g
z?#7eed2Rj9&jG)M{ApN;gk#`PmvX@_%^^x*;*AQR)i@>xW^zqzVRz)le^Vu(YJ<>|
zefVl(pQsD46(bCQg;WZxpf?%?#b)G$dB(3<MoB}r3UZbkhTbFxl5&>ez*W-z+%u=0
z36I>DC~+Q=;|$EwVw5enZ<U8iuMS@~$vXa?lh}A8Rqa5?$8`0fPFPyC6sMoIu3qTC
zSX1NU)LHJjk3{_z<HBH$RB=>?Nhp}SSkXK4ncfE-E9vKn<&Z$Fe%IYJec0ORfVWas
zrJwuQV!~$yZJ9L4!S_doS}my(CiLH4J2+l91#&hk3{R1JA@0I1h@O>gYfURpFZF7;
ze!OVGQ+0z6%=tR&S4ULY>tXpv-!xLnf&up9GC)z*A%Xj|tRFdn#dy64ul{mxWh!xC
z=hxsQg9IzQ9$7swyV~{^RdHxtaOOkoglR(c5VqiXYb1IPw!Xls8>nAYU_Txkv;=np
zmt1P_wQGhq`LQ;Y=3_q4ADf^p<duDn+^}o4Ck5~_-5qyYIkj<^ZsPm63-#HV_pYdc
zJ5!Y4^#2qbQmGDnbpUCzH)m~_xCF9GO)L^v2>^-*0EPbdDSxe=FW7LX413fzpD4<~
zF0&e8%}#?ThHF2ML2@8lcXZc+MZmBkagy$ZgL2^v1yFGR;n#!~NzdoH_j^m@@Z)f>
zFL0zmRu*}x7+BlT*NN46rUg#DIp<Q5hvPxF6VXg4B&<IUan&tY2$&xT3wDdGhgQ(l
zNtC9u&OqSF&Chtm_i^gLu`7uVXF5?)Q+nm3FNT7hd97v2Uge*#Y}e&|tzGv|mXBa`
zj9-re-e*%SR;=nnkKLl(g^+>d_{_RLWm@Cb%J~244Ack!3i~e?zDGo|d5D1?97_tN
z$_0a|o@M(U4x%5`-?$Hk3@eZjSLqe0$5S5|d0Tr~N1R>UOcYuO{+(GdeO=&(mF&`B
zMh+%|lNs9W@ogz+*6Q(bFabd(k(w<t_&5a0mE4pb2rX)MT-Oa8Vc^%8zlM+R9+G9u
z5|F}E5v_OBCZJG<tzL||{)|sA50cIbRFkBOs93Rp;Kx`LlHz2c*MLnLY0@W{fIJv^
z19je=7R#9}E&I9MV@9lg8))+~oN5bPJ8AD1C*;_0(4+N>>5cv_x7&Kbq43Q{lKaRx
z1-#asjr#jN+V!~xWmm5eE|Fr2E=ku1y3e3%arb%rf3HD1?2~!5zd0`jLL`KpPi5|W
zf8o-Xv`{VBGSY0bcoOA1#-5%0ipH@}{q}9=jEVu&ZY$zlj#9iuf=vNHO8}to|1eIX
zxZJT{2EN=&sb{+LWd=v;O+WXsleI$~4vXz~^UmOo%l66GC7TfSyT+}e)7{wFh$>>L
z-9IK1CMS6@>aOaC=4W(naiF&r?iCB!%}$Q!tty{dG!+$0Fa&QxvgZ(N;CT+$r`@7k
zb_&q@>L7m-A~$=wcb8Ga?Cj5<@MQ9v2*D@Jp8czX@roQ)V(9{xlhPHa)*cHU+5Xx?
zng-F_w{aRE2`&%K3;-iBOK&O{4cwREho}p)k(Fn2iXyY{w%2CZW7{^d*1>8rD@>QR
z_hA-!m1{5jmw+@kmfmE&ZfEHfv+_vx_e7(-eIIJpExINJ4mFJ#{Q+$n`FR>;6aoyX
zZ&i^+DeuGITmNwF{7ij<rYoW7adH0Kaay0A;T=YP+ITFp=;6n}R7#e=NMCaJ1mlwN
zV}g|47&p`PW<ArAX~?9x;nJ+@Lih1Pt{w54BhwhMAIG)OF1MTr4;NwQmGL%~Q}s=;
z9Uv<NdwlO?G5I^`{R{pkumJq45Z$DC-tWpzQDM`*q-IOIO{<puoX_zsFxje$)E$=u
zFm%~JC=yf;0D1-hMf}&=(tsEc*7t-57D03cejOXh)1wN<AK3d+;_Y4!b|9m}Z*4c=
znE_5%&f}xi!R!VfkiUHDi)(pbZ3{NwF+-mkCQZK&%3eGf9foy35N@r}6N5UV>Nl_>
zXlvV{aNzjs+hbH0?ifo%!`r-$y@)_OkVK7E-Hb`UQB;3`qxbC%on56HTZb$U*tGUs
zfF`}uL_+ihSu$&FQXR!ylV8~#j`wU5tLeo%(|6I&xDNfI3mzCgv^g_72_hdcPiV_t
zMy;#hM0O{=u7}d(Ck>^o>R}AinMc68Zy|$M3XaQJV|pYQs)?p@0RYJDp_!|$falqj
zcV?c}y6_v2heX=NOU|`GR-G2pesZ>UM#r+gc#M;e_zO{88*v^wX2UdxVVwTCG_gQ*
zk<jN$bA^+zWUB#~)|**F(J9=K6_%`0mm@Ufm0~$U7~dj6i2z`908r%rsk{X}^Aq0v
z4of}EVlcEmLm~X;xTcVQLlCSDwsXQoOn@cQ!~|nE2f0aCh8R9AA{V6ZGGv#77$RwX
zk8nY32?4{Q9ZvjETA(XI*mmg7c{c0BLsKohAi}zyhoeqJXwvX$xFt7_^s}h?!#+x5
zu>lQSCVGmzB>bp6^^2Frl(y5xOGwzQrEd`eFu2$Mq|VjqsM=weyf3%kCfAJ7-87%>
z?q2PpgCU3rkq+1?{ut51tXb)=Og1xVHE@FjE-5~HLd_T$*Imgq)VXC^(W_W_cX>?1
z?yGz+W(&{-tQQH}-vNOpOl9z$NF}6mqcsy5trOCqbsQN{2<%hJ(8Eb%pJGF~<-s00
z2vcR@0X}FLL|!!vwnLZ*ZPi8#p;Ot(t|mFlhS#DX{V-#yL@kqigKPpAxr!I4BEjbX
zV0Hjd)PE?MWzgBirVf{RMDrq6K?g5sqF!8TV;4UK&!7?{-!sbR_*v!8MjYtjcjcya
zex$)2una7zC7~;NYn-w6?T5*xk<36?;|<90$$<3o18Icn>{ViY6AtcNc}k0CyowGs
zIN0LsJB90LL)-#EyIj?mm^>2`<K??r!F7d~s*<M9axZ$;IR-j@e_oF}HCY6;5)1DU
z3Vq<Z)LHXPKn!<dnL|4eKXJUBY2-H0&b-%C3ymgD9pS<!^}8E(F#QY=&O6j*#z;VZ
zgA@lr$boJ~YIixP-onIba!5!WSvoRfB$GnVw3?N2Qb@&<o}4|fSjB1ipEJ<sJCAkD
zUsMUZyS^2l1d)Girp?F9C^qb+B6u%Uz_PW=Ea=s<Xy^qY0us&t0m-OYc1}*tmi`?<
zV02sRWFeR>wbLmJ<uO&{B!83w>K0>&d-Nm~VEi@{cv@<rtN$jhO~lBuNy#Wlz;vJX
zP<eK=(f00V<QB%;VKj}Y=&ruJAH`IeR~$6`4k9P=P}3Ww4q;MS&Z#{eGDByZY^wBJ
z?TI=nZ#CQWn8>8D8q6pVP^UupnXcTvK2X<HIsBFcS41nM$tYgDMt}Co==SRw;zeZL
zMVs%w0(0DX5qoN{-UlzoV2QWWPuH!LoEv*65*!Wy)&u}W|JQq7+4%J2n&}etheSw2
zih$u=q$`P(551qOCY5u;hk@$wPu=vL*KxZv$-8r@QpF;D&ai2hw5uTu%QOHfN`3lE
zjL=>BU^y(RgVDL^O<(1*F><zF^SrO&wB=xd(9%kAm{INs_UBg(-b`1Ds}&od>Y)LN
zNxY8S1QT`-hDdXT`+XrMeflBm5Z+YBidBt(FRacX;l+DUF!FEp%*FGxebwC1U1eu%
zzYe)am+!5{aL?`5dha4Gqw_9uWO5Yn#q}OJRD+>FB|RiDYUgoGG3qKpsbm6Kb^?Uq
zTIn?s8%}L1PAZ`i@bzQO1rE8lRre0&@BP7a;Gq@17_#F`I4qUw?Nz^mLl(6Cn}Jk!
z<p0-dY9cRO*X5yaUv04vgrbx24h(N*o<^EK5I0#jfbbfoo}v1FUZwy09jN;OmpdX2
zktLq&ijn6H0+teQmpTK3DIb;}q1l7DOSLiw)+9~2P2^J~#pMh9fFvl-Y!%{478NG>
zN3Gvs5R7h=sHHZ-8nu5Kdn=FXo{(V>nkJM5gyPUiUB8sS7wc1==UAyrVss5mq}~Aa
zA%rXqCMjPC+qFnAJOJ1e02K3IjVxuhxp|S?Pr|)CI!an7Xa7D#eqcaj9`Sq6+P@kQ
zW&})JZ_uc2`Jz8y;F)YU^WKfh7^5Hbl_+g=hsOKz5|SZyNz<n2+n&@YeBorShHle(
z>}c^Q^Ri0*DUw?h0t+D4g@H}jdfRB7XQJ0GCQ|YdF>{`x8>A`@Bq@-015G^v*|nki
z9@Cn;Qgk(9Rj+c@J#@l`P_qyn1m>;;W`D!+1$k3;2W<!UfVk=n=#f)f3EyS|ehI!y
zSTU|2N?e175kHNT*bbVtrnj*3d2zO*;>H-iPPobFwk=_j?kdx=B$_43D3&A6F0Ugl
z!`Y6fZ+g%8h5gw#+F<zGM`J^oe&hK7yj$l07aVcS_9Mx?Hv&fiOp8vdU`Sq<n!9=(
z`7oNf&8HNj0Y6eCQ{js0Sa&V>6hk29TIb?+4;Ba`-hdA4Zb_=YVFe*fL*=j?m`@f3
z7VURg%-t|5-cjSo<O^Gtr6b3mk^#CMx*gOea-Ez6irv)$Mb!boSpcBe|C;E#{Rt|R
z#9Ekip=^;WJ!2@j#RsuhO6eEl_1e;8>nYNk2mtN@0LA@xJgdW&Frt8VW;^CXD}_LY
z`x@G)mXAvedLBzu?3`u^nGLQL-L15AbayokgQobA5hP_^qb6mn<B|+YpMSA@g~G6t
z{=uje_VKzT27Kd~CbrLTbfW%gJreH^9s;xuG$LHC1f{cyYF`F`#X4nKCN!7q7csow
znY{#EwHj37UOqE0M(Zv}CZ<2Uytk&_nYL?Q05vX2Z}sp-({YfHYL&HR`Bq`Lo+qTg
z$-fu0Yip=8im)TIaktPGN67?@O>QSzyFhP)IHs=e$a1IF-`=8;wmF<CG@<&~gQKMD
zbTRPhO0(WY^l7<XF9Al%IOXkd#IgMEv~vAr7|JEaBBUud`?qAoK?k$LbopgaiJZ=8
ze&Hm<g4F1hAPQ!iag$)?Zd>5h*>?)cK{s69F>;3hLL?W6HqJHXw}Te-th&q}anA!`
zl@8$Nf4SJ33F#;!C=WD*Axdc<R_}`Dh!+nz#q<|1y}}{OI`v~$BfAy`Qkc7wfwXXW
zOsd->|IG8NcouW?<fXpWBpUPBuVqEY-|$@VVj^Fs1SXI;8_<21sb~>g?EFG}Xua(g
zcYv7mS57Sms{3d(E+5BRMKmOFH5UmASaAdFsjPZJ7B&MEkXsnm8^UR2XLRlhj+Z)b
zd-Q+iZ-}BPC&;F5UFB^UJg$dcf(X^4w0V76`FWe`PV#bJD<<@4X-Fn3evP>pv)7Qw
z8v_<rh~-kMUw#0LY9BEC&a$HZr<lf`>9vRr0Wq^oZq%V?9FM8tXBOBlhLZ{eayeAQ
zXE+(%<EehnUFu1delI?N=%1O;mPj+OWDQ=KHd2V1+NDi-j5&_=dgyIZ0LzLi<4&a5
znC^w|><fk5hbg&ZuMqEBjq_OGSb#)M12JtU9k9a27tQbAXGtkdLaMZ8j^t-TI0lV?
zZD?AniPQV*(n4#ZypXFAU4w?zvATLIow=L9OFLC^y*iP|!+c!E40s5I@NR}@$UA5@
zh(ck#-Fcp@?&PIZ4X?$=X)|MEIi$3i;+fUMRdX?S59m<dtSn*(tW<2eNU=Rd#)-*I
zjjcu0Mk2Ey4R{~q$X4=?CcGln0uL2KbKgu=5(*`TU&inCgi`2^Uhr=PR{WZak#q}9
z=4haPnMgOnt}kZczWe1jE$=^-cb<iWy&tn}QMm0^C}oI|`%Uj_*{Lf_3-kmae-@8U
zm8NW1k>?qKS2`Sw<qT$*`_V_qvyZ^?0M4+MsD-B~93<#1;hRD#0ipgAi(59F?m%WT
zO-SMmfvW#30^HKEGz4kTYkn2drrZ&O74MU0qXYP@!W&jJm(x3Xwb$Ox4KWhpw1{Fw
zi5tJ$p*q}pdC>CV99Lr>R(ynpS&r2q^iY4Qjl^=|XSlwoA0K<RsWz&M8wKu}>HR6~
zfrSY0@uQg>(vuVCKNz_E_c}eIu<n;mHbu~PGa<@6`({ntz(z*sPFEjX=3s90PXtDB
zuyKTq79x<?S<G2bHeFiZTN8-=P(dw1X*oPYIaLQV$21>R3xs^BEcSU`VDMvDIceno
z)$N=(`paw*^M-u955@-Isj*z`DM%?g-40R|h94ALbDlK2D?LSkHV9L3zop;r6CM4r
z&+te+l?$@*w;1u>#wLwur6T^?QJ7rNkyY--v2)Zhcv^P+jIl}CM1ogj&9FGAH|L5d
zo!p$oT(3cqzBK3z2{EJ8fx)*(;H_B{Yeh~BskWV`?kj>C4Tx_z9e$w9Mj#IzS-}Y)
z<5uLJMTB=VpkD2CXm`bqsG9TK)DiV`uo0Y7_#2*7Hmyc1^ZkGp#W=XK-?Ehxpf45H
zIJVjyUNq)-3}?enxELpqzX=j}(e7DQ!G76n4=pi$?a8{apQ>O}<jkc~luKjMWuk35
zF!et9sv0FTBwJ@B)e~r3V%#?l3YS!W+r-y74ly?2H-+~{Fvyy^_W(j!K>qlM(kT&%
zk<dD@?~jWVs@I0_xrsBy=PIgd%gWne&Nt`TJzq#@nNtGCQ8&r9TQ&|9eoDvY0>`b&
z`&iG2U8<lX%pJ2YsO})C>wHrm^_e4s+p!Avnm=iQ3xWO_#{?`-h&Ve?N3c$9f$-G)
z7NWAZSm2&?k3r2Akwz-8YITN?npV_<hHPu5istI?5^X`gv+Kvb?fl@_nkplg_aN(^
zwsi2{1xx?(6R3xo=zJzW9@gjEU@IzE6Br;G8~p^aPRB|_ea`M}l)$0u5@~;f-Cfrm
zi5yKri&5@fBLDMslD*K`gE4tpgylGG8aZ<Y4Rep4fkZyrc*9BpbfR?9VdVMh`@R=(
zaXnV_86F;eiXU~+RGxQpn&ijkX`HqB5&PRvXKz**kRNT=7g}19JeI>?i8f)Gj)9e_
zOA^@^lDvhVjuTNqKhDqkcDvDV`NjUd{p#FDSfDtXEkX?z6xlcS(R2u3DJ3={yIj&v
zRnUAIyKk`}Th$t+RuOXSh>^s(ld;)7qO*Gu0WI7!1^->w8e$D$<cOBye~ZniLe&NG
zsIr)#rsP2i*0>(hditUsI|&NMmuNy_B;baOXymnqd5g1q_wQGWj*oxYhy6E2z4njj
zID(M9i0j_6#G`NAiG8P&re6WrxmIQgo1VDPct$4`7bglCyOx}hbMl`DOP!dCe#@Xy
zLx_xCZ_~Ej>k3oq`WwTatNMuq6EUr?7-nMA+(Q$?+9G=r+ax!GNjE4j?lmr);ByoY
zEC^2ag~5s%plZKd`ZbDW-+_WjEY>XJn+ZS1UHg>D5c?^WWd6Xas>=D~I9h%G_&iuN
znZRfN&8?)Y{?#@+rnX-!;xvI-W~0GTZ(sOBmIPQ^k;1!GzsjI*fw7N5NiS6E$j3N(
zk1@%@1dWs;T{JbW1)9dbS&|1U!A@Hk5qb{SnkC$SVwVqJHNut@VxfSe5AacT&^o)a
zbQo9=c+9KGkCGA1$^p?U)l0bCxt2vUT%&G>?dqB(B9KqRbag@5ZW33X`j>)gB$SCx
z(;$^q{vBfeQ-8YtZPDjEFje`rgA}g$G2s7NBkCkdyx9<#Elnu0D@_<whbY;!IJvh!
zyPkE?s|wY_I`__)s{zS3a*3P?Ey=f;nSu*HF}p+diQ$55XvgOGhi_RW;U3~h;~E&_
z5j2^1lN>d~m}yMmLy~6yWCRr{)8TDAnc1clg@d4T_26ww#*w$BSIn`MSEM1zoHj(r
zQRmRF93`U`Tl-Zq6PW1SdLgI~k%dFwoH1TOp0<HmU#hVuS@}`HRMK<ZxNNfq)kC*S
zFzr}HU8&dX)MPQ`RBiNCMz^}k<FGp_IT-3$*5#oEV3gtCZ7lOEdW6rG2>ysr2eME)
z@!W{bo9XKginSMiX8F~A>k9@FzH6^&Zdyz<mr-M}*j6Jvq+-#XBAYr}cB<fZE7|-q
z{q~U!U0C7h6(JqneriYXn<el~ZA^}=?*3D3lOUFiWA$LvWm%YX*YI`a?<LY)Q5pDM
z3}j$t0M!`N_cm|`sP~H?Uf!p<HTnuOo3sFS@FM-L%iAQXxf=mq4Z@jbnqOdR>C+A?
zmnc>Xp95(+9G^q8&!jR(kY&_NEg$x(pYp!Ztfi!_bamLeq9_-0+Z0{$cv~i~T_GF=
z{45A&+Rm{!)!S6$q>nJXBLT0f(f^@VJ|poRpFpjjw*T~8VpmpMl2!H$jO7Z4pWI-v
z$0ZAneABM<C;4)Z6ZEFzh{HRXWALsTgnY>&V1U_$p9!J<qh?io;hNt3I6cS{@CP~2
zz##;|p`|H3omOJoX_inG7{Iw1neGP*l9I0A7047iI+;vzk>~;)+IfcomGlAy!N3TA
zxG6TbGQOw}rhQVL8m<0GUc--O5=iZ}tsRb^O$XF#$}|BUANp^vax$QsCP3HGDE2Z&
z>iV6jMtk`amfW-;b+Z|*G~C+`=ART;5se;!JQ!W*>X_@;H^uJ9Vhw?m2O1XAza|F7
zqK|B6-l^5U2pd9}pASILX2^NWE-{7+CpTmFsQElw^W3Q+JbMXjeSS22*m|E&uBz6w
z)Fd`-^#j%efRW;>D@|~LY^>3*lCD(yoM4yNijDnUQ>wp5&aK1hn<lhiL3e%30{7nE
z*{e=rHE{>ElPI$zULpsjLXfW!>G0kMAOfP0d{E;8<s?S@CNLtRW}M+H?D@a-MPx0D
z#&n&ncd5!Lya$~{(Nu*xW)riy5h8`9R9EXD5*d+pl8^C1FN<<YP^z$1&LU^75)yR~
z*5i9Hfm(;QZ~QN^YVRx6n_^YYAO46q-{5}(hw<Xd!WkB}luMflJ=B~<m7Qm&>gt;l
zcQeVL>)H~}i;B{#UB;7yxrg@#B=0N_N#iI7m7sHM>rr!6htcvo=rkujDN-Cm#K-Wb
zp?r;(GTie;AkEM)P---Zfx4@Hzj*sEl-l3)11EekLpSUnGq^`DMz^n*7LbjXQHDno
z?(ceoo`VA+wC@vxT9cAYoQVr*@`=!8TNiHF@^@#+Ye24lON$un`X5e(7f%MLjTb79
zP#N|9-C~KaG5jrbW$lJni*1iuCVTNA`VJuDyHEq3lci|H*j<ed2NiG1iuwa;Or+7a
zKE3lGcd;3;h6tvG0XFSxoMWGC%bow|&;6lN3nlU5<Me5h=7~Yh1aesB+C*L6>}qOS
ze3^|852SNDyg6`fkh5{i@(%~5;#j=2I{r2^2L<0@33E*q8=X@~uqWA*fUhy6&*EmG
z7-mX<!*g*ealMLcsi=1Yb8iG;pk0IP?%F5-iEYwUA}7p#zTK^-GpxkOAW&;4ge-<i
zv0}a^g&-USzdE}-PhCcS#4y;W19YZU-dAl5^atv8%&q*ik?56?@U5uw>VD(G>*6<J
z|JC}CA#Pe3o1Sy^x#Z5eFqcsfe(f`JGBL_}YqY_!r47<$5oheYVd{a7B(=XU5AjDD
z<znvXYOBPH#<0Hmf@unBSns`{Lwy;|wV*~y5gwEIRgbNkhnc?k20kq8vVa+DPSusl
zu_M48!~76~4@l%6PvaWng(~+(Y11(f)HUx>m&89`QS*<a@EQJF^f0M(sq)LIKYbQH
z=y)nkW|%g=9fYBHW11gk;ihhK^O(e(NAT^rzVids2zyH|W_prI*RIB;6->gD^>ijP
zj4I!#<!!d%9X#B4xLx_QXlawyDetJNyf+MHRKX(&J#5#|6zPfnAnSY^(&)aw*R9cv
z{*13~1s?7F4amL*A&<pbb?0mR-9b`_brdo4h+0(7S4k0;uj$F?tU&Epla(+oV#No`
zJmr;PD4iikktST)4zNW%l-^Ad$D;PZj|Yui%qlrP;-dTvEtaEAJe;kver;?RJVHWZ
zzza-cS+99j4_Rso3?f=#%L$pq87KW*W8JVmf8EaH@pLh!RK&j}li)@?H{=9s_-*?C
z+WH3)v`=0P<^}?Kp`JxC<q|)d{OAgy3aKV64y*Xj<Nm}%9>hd2fFm@>B_ENc(MOjD
z^B`u(t)^>=?<$)y9GLf!`+ckzg3{afQHyQd@TJr@JXdf|wda6|>qluLDeDYet)VXf
z9Eo-uxtISyaP9v%uDqJ}&Wigv=>{o~rnD{6tUg2iJeefd<Gv}^krmbm?zgo2Y@(ql
zMa8}|$$u%vv%6R46C;@u0~;07g9fhyFE;th*vuX=g?^CTqZEARP?FW^nxX%bfk2k1
zg{81f?_Ewi(X#Hi&wbfOE9Q2E7PY_lSJ$Pb`h5)kJR-=oqzzT~Ez*%vkS{9lf$ya?
zgW(x?qh(n~k3;Mcr}dDtSG%0@7xesj;6z^VZj!uVCKa{L#+K-df~!lgJOs<M6wh8@
zUN}jaOoA#Q&2O61fr%S)orW|?skL#R5ULno0usw{05x2pdNO<_2DWpJ&~N<cw)Xn@
z{0pYO`P^}9f0j$LVI*T-|9fSnG>_($Hpc`BSr`3K+NCMFi_X#DBl6fW8X+(^%qS>J
zpxUAAw$6IJ+h<CnD89O>9vPyRP!7yD$L8VeBXJAcWPaVy;s|Q4UmR%P$$r_dUN{Ev
zht;wto-SkfMfzVNce&5wV#8YF>Yoj@^5!z=lxgrm^GS{7e-mc8>0Mj;Ca_natC9H*
zGWXVC{>taq?epZ=3V~VYGFJr*obYFvc3ZYW*`ySkfNspMShw>$^6v7b)|?G##x_JF
z-Og8UEKQK{vzebVQ3>Jqk5}M9e-O+yqHqU?lQ;gZ1PCFi0Q?3^{~*fXsB>Ja^zYW?
zgQBizZMaY4f2|*Spx<#SCrX!M6*Xz>hv0L(d49cY$lxtjxe#&vZ^xYtD9J{08QOyl
zk>2|mCs>m|NMKtoLE}#I@pjC^9e-++pi%Y1z`@oX4}uGlIV_LX3#f+AmQ|*M3Ldvd
z-<?Vf+koCZlV#F+nH6+X+2=1!gC`J8okaU>s!3tmob{po5fJM2T%E`SL^pUDrQbdN
zakYy%#h8qZB@b`QwGoV@1(l<nR&9~7OCP`yR2Bso%_#QnMepU~NvPi`Ee@Tv?WM$L
zXC>~?c7o9TaC>TP?xvK}Sro@7Npk?Hv@ofwI_ed)WS{vEQ$c3&;|@}5B&UP@aznod
zy+rcC$l-C%np;y`8Q{s-!gyfo)Bxm0{N=AU_ezAr+xAELkjG{AWjiw|S?^YCI_8kw
zF+;y_orh1=cAhQnw^S0_)VK%mrKa))rXZ;Je;s(mqLG&U_N5+vzxmy$cOb5zPOqY)
zG4671BuAe7{A$=qXO-o^uzvSC*`|cqOkcL2wWwW-LBfvbzte}>H=8GtML!Qi!_qjX
zCKLcQxxf;$2@#U<z5dt8Z&^Lz`p6(*YI!tVAGlZE`Q#se?Jz)HYcU{JLv6v(m4_2?
zeNJ!0i~kf)fLawWD|GQdH(i5{ROa|lNij!cdR5d${;teXMr(PwPxvAm^v#=D9dPCB
z(>fJy8m?~p9wKDU)LcUjCD+TIE$+mLMEyA9g!H9WCwnMs-6h0A>%{jgtGkOo@^K+E
zi9M8N^LOSu+;aH3zQ09xp{$wsvv)PhEc+1n<#<G07k%t-nZh6|fr#p=y?L|jzH|Pd
zA$C)xfGJDptRwv^&B%ZLCdh@pm~)?%8ndb|FDrtr!;t|r<j~egXSbwdhadBhwY&pF
z)nx>_4H*RGwN%9t*<`$y{e`jZJSIF8#kO)D(6=uJq0wZUN}F{?rAZR++8m0#f2O<Y
zHX8eGiZYkaUD<4dNJ8s#36<vW)E2D=2^QNdI%TUg90{L26*P?uKTuSC`IC^0#RwLk
z^7(J`&w_d@j6EtHgWBsi1_grV%Xn-?J13+tv7J-0CSs38PlO4#FVDz<<msFT7!u+y
zOg~ULylx-OKf0tgJ22HcKCMFmG$RsQ9<WjvMUY&rC@OgP)bs)aJ9m9T!fHd1H*nxe
zPs$@yJy0Ss1h`HW@-pKp=OT8_ScxK{(|q&eChY)nV-w|uoQ0yOiVnV05$d#>9&{6e
z8twMGklnZSF~*D)4iti){O&~%oA^j0gsy2YE)7FVKTPb6$|&jub!nvxbDQ!ZNIIEJ
z%<C_*iiAB8NaZ!xZ6Vy!TvRAMlh$ECD4xD1i6bihnp?qc(0wHBO!6G+4$)bQd`L7a
zC!*`BhVFFZBlPZNj@sRK16ib=<4}kPEvkgN`y_P`r8tV;0nljF@&*s8MK;1fWzFj6
zsNWf+V>=qceHpN9R#@pAu_mFTa8mZQ_}8nUtN+zoxjRB$ho#Z%e24Ny0rod|0fH_3
zt2M*m;08!xdsoO6qsxwgs(6|VFt}PrXDjD85_lGjQnYP=w0EG^l(H_#X?-cLh-b>j
zNvA9`DbQdr=yW;msxp@m>1z`~)9U8P2zJgxMS6m|uq&2acK6MKf68g-^VMie(Q0NK
zFhj}N*IC#GlpH$917~BrZU-Pf`(5Qj|M1xVA0k|Af~1?<PUWo?XdAk8tRtVa4A$e%
zpsgJQ%%U0T9}w$tp;P~x^7&TnvrUXDR4}tB=FS2rV6y1hvE`Z1<rfN`JiF(_3nIMX
zmG~^FY3eab?P>_d;h%bkv|vvt0>Pw0778$SH{=vB>43T^9JL9_3Va4MUE5ISchWoJ
zI3-L88&cHFfQ9LY5XK!+n}q_$DJ6O#R!Llot_2<oX&TE2N+Z`Ia<!uGZkEbl(mQyp
z<CLFC*vN4X=QB>(NgND61)w`?hc!$587}CaSul@Cw$3BNq*RZlO1p&7t1+!e+R!%)
zpdYZ1Vg_2TxLkNo5+RQ)EBd14Exia=Bp!@+%W8hVZ*ZH(+kh2r9OIZHlAKVeu||_B
z2%{MRNHbyV4$rcFD5*1V#~cKQFz`w5z%lxtdzTmE!859tN=3|{^+D{zK3umt|A%TZ
z{hsnvI4*slFO?K4ARz<PLF4)K*7FerIL|gE8d8NPA?7x@M)?+-eovs~U1JIcD-?~Z
zDEs*{?}8tNDKlhn3lgX;S!${M<{6C4{q@=Q9~<Xmm|~cgwxi8E2^I?kQ1{m|R~I%>
zPw08YHE#M@IAxZ!Uj3tJVoly8w+y96?)cFfPj^LFQp&Z)Jii4zKZ)yy9h;{)MVfsK
zE65e?Cn8(MWSSFf196XN<7#*HhY-JkN)fY4+}>!DKL&rRtAs{U@ekt!C;c>8e=lc#
zZaZP>w+V?tSO?0;z~AC~@~`>);&F2)w+~8_;A#P6eqyZD0;(vynx`2P05p`XQw*Bv
zrD&fzyV#AdbzSZh8R=cJofr;~B{R8H$#a<}tB>Hl^D5}P#s+@a2tm|pto@D3LuP0e
zIz5aJal;(8`bf70xN<I*?-2Ny?C(O-NvalKnEE30%#zhV5IzP(s-YNLP2!BN4?|6m
zx2+SsLQ0cmY_7;udMH_$nnhnAM)95`E3p;Dw92a!K}`V`zjx&kdWaFbKYBrgI(bB~
z%9d?zV6MR4QZP{Oo^mUNb8H+^f<|godfQJ*T>1x(giEHA>gRZ|NRP3!iEs|2K=u_j
zet-P38kz|NoZKEVQh+IY6fzyakU?9JR-yC(v^KhCUEfBL12v@#vHK>P(8$A^-*{yz
zC>1JGBn!wKJJDOjA4zcMFDL)rJZW^Qr0mS%Kw;DVUk&#d9f$Kh416~m+i4oxwzIKq
ztFi57<Hl^%*ftucv2ELE&^UR1&pF@!`+0Rg_nf&ibLYYZ`KilkOA0tS)mh}?MsJcI
zU-NJ%{85K9f@YvrrPsSyDpz)#p7mp*BeRl2`#0W)nF)tHM>aaHl;g_zC!Lr*2jBMC
z@Q;YZ?P-3K)%e9F`>QHOJ@hJ_A1f@Oi;QAuA1Sacotd`!Q-!&eVM3@rQYtiZY#T#G
z&inb!m18@^>SURWM~g9Q`2h{qs9FN+lj${=^!P|{dl-Na@e};_5Lfu#z6FlqK}+d6
z>Dk(DoHCs3t6#{lX~%hrb?FuJQ+H=`0C6%|(?cPhj<kS0#yeumsyLgo#p9c)>{iB?
zNH$4w@DsyKO0lglDwD;}a;5oBY!l@A&GiMuk8d-p=(uUByu^Q{o`aX_fOxPCd)Fez
z3XJdiaz6}~&T!OUjF`GM^SRKAuc;U?`N6a;g=tU-nqL85T(=>cy_*L==TuU?GX9kH
zR~xuYzMoQ*xk+fxlQ=kmZt!Z5Lg=iV2RF7|&l&_0U#+&7ji=X>JxNpgxB<eFNUR4;
z*BVK`xK6vDpq9IHzg<eLRj9`~z{^?=X_IN6a}X4wo~5-4z}VxXX@S0vqYaAqL?wxQ
z8!8S*9#NK3eKml;`zf-b-nIBWn#UPuJIwrqO=rm76<xn2v3m585hvQC-C}mBsY!}`
z3l070g0t=QvZkU1&Byywob<P<FPDyR!EH%iTggCMDO_C4ZN}h`jl*s$?-PA9&R5pn
z({-y%9@lUYy3PXCu^owo7uju_dqW^cB~+dUmq%r{z{S@&TY3K}?;}XuhZ|(O7)GD4
z!f>#6)B{;GFTY`DhKIMi0nRW^7c3RE8NC(QWf#^CGV)4WZ{p9V(;b>#fPU~n_@iZf
zUVS5Y^$guO!+T>{-EBDYy)z6Vh0&!NWYm#s3|2iT2cGr)DM$09$y6#N<|0iCg$l7r
zYYEaW@&r?65L-ETMX`&q$Xbl!Fc&~WbH#fsV7wgI)wU9k|GFRJj_%1`8Tz5n*$dM}
zrFa){K!1Sqm6>&3;rNMJi|Zo=CWfqiMlv0q+butb=&;*d;zg~W5sv!UBjhcgdQL}7
zbFNl7o2QmZ!@~_zORFF$?JkGj)Y}Cz@&`?wUL6njhkb`xu`L7kEG?Z9LuE|-m!%qi
z7jj}cVizH$09qGn%u3xEv8ng*-@mhn6S=<(b)MJn&^|Rc;8>M3=AD8(ds_k4#6P;A
zsn8A$<=ihTPH2<t6E)fhO8*{M)eH~YjdtDVAS}^4+nY5SQx`yv=~mQj*~opw;9lGM
zl@qWOzt$Bqq3r-W*IRq(%-ojjd>Xf-P1Y_;j^wcKoxZTv5gWH~?&>l=b)6w=eVDJ|
zi(G=_JMVTNYgC1zEfA<J05IXdx9lnC&5(Ny@CI?q9Qv<e7dIlz$dTljW_vn^6!zHK
z+dOjV$)BqX`QEo=t2%68L{Kz&jDLS?$h4W<F8>hj<If6tpRj$(V@&2p1(*Yxj{`ke
zc?lqlLx15GtzYe3ET&pWtmMD|sdORtl@u-!wF2~q!m2eDD$%<V2V-y?+#}KY!swRB
zk7<U<z53vd>?+vgtF6IoH;tFoe?7)k`GqEbHd$#S>kFF-!6*=@PXI9S|C(SZzhlTu
zX>bi^)h}|@iMc{EYMn0T3{{_e(@u=pYiqRdSZ$8kMTzt8qqyPFX?K~R4t(>`a3}VW
z)7ar>7KFJZs7R_>{dPZ#?pk>fz4PZ;E(PFdHhZ2SJoG3O>z}fH0$&FojJmSsCQVei
zUZ3d8iT*?=eid={K4yo^CDzN9^06nWRIb2{2z#9NcLB&YK)HiFT+GuS%8D?Dz(;KM
z?LM@@U4jOBw)@BjNh-opeJ6<fS>ZC^K6E5R?`grH76ki~6H49VpZB!Ixoz$A%0tVK
zX^q{JIM^D6QI6v-wnDHoX29jeG;jN03kP46pV6I&o4g%y>DNu`T?e~DF<c0U3;;~}
zzh<zlaI#Pjly_6ATdawpMZ*r_KK8_glDiZ8uy|}KX2))`1w{`02It{&EogKV=+mG=
zGZ<m<603QT`+(g8mZR-gWgndGXT4Z?+iAd8j!E(XA&bR}7rd0p5Xn}&r-=q=zp5Ae
z4JQw0LnycPyGyW>1BkmI;q`i1uG0mt`I+$m?awVbu;dBYr@oTmQn_7~S0DA5Zq}mJ
z9%XXXG0WwW%MSZP>KOjTwpf#q)M??2#MD9p_AYy3&Y|t#4C#Yk=+~Kecwc(mG?1%7
zoI0`4&q{*8F_#BJW$PF@@p@(UPQOh>!Ne-2vx32g#1sYg;~SDeNGNqtdIPOZ{2&GC
z<cN5)lZpIBQ;xvK$$neglF*#bHOuHNJkiz{&y?|!56$`)r?W`Tn5VARX-ges;paQ5
zB)u4?#V`Gv6JKIOr?$Z2grV2<ki27eWds7bMbiMkNYsOr21Ezfc{`&kT4RhQAy>6e
zqf_Khj3lXs1^NkD0ny03oY{O|_=F0pIoXi&fDc^~lkVeNkNgTV|CNO%FU}A7lL?fc
zlhrnxQ&6$qg)nXu)&RQlxzTxjOn!NKJoAi&OV^(!hd%>l^ZR!^%<qXf``N|54*7!I
zb!KkV?G*)-`?<82gY?Q8-YLzz9Szk%pZ<xgg_nu3l%Nye^%vZDhuII#(W>8Wd;csm
z%i4$w!AB5~7yy|3Ut$Q!Rf(GEk<Zzw*F`1@$7uL+l#rNHa5J}<-hO&jQqDp&)E_Lb
zgIk~aHJ=Sj0^DeIxCevohsJPm59#eMHmAn+h}2&e|9SA&F$>9eQ-})+--j>90Jy^s
z8}m=a43E@^wZ9Nq^%#4m@couvuh;A0KVccvU6AO?)bY5t`;~~=X(C|n^_pNscCPrL
z3UnqeN9z5$`GhjLb9Pz$zcRFiEt+!Jwozk+XFHgFRBX~8BQhfmR(9Q#(GV-LZsh2>
zKMP4ml{(R5zDhsxn%*fQ{#oE~q`R6^;M_eOBI3c;p#P7m0*2^SkHR<hZEZ4_vM-OP
zO)VqoILe;M@>guvSil!u@nCw-E|^=dK9oxbQ%ja`Pa#Jo+!7c(wF&|2rR0f7vV~Kp
zVEw^;D{S8F%H_RACe{h}j{z3?jZ8U7vT22-OsR_qsf=O!pmoJy8q&@%JXZw&KcP3Z
zuc_$a7aO^kYj3mSX)N0`(2HBI*|bZXjUzUsigztdf=;?B5DNvyp>}ixjXZnS&ta7n
zf!|Z9H=sB88QTF1&ugQmaLF#Cl@@<42}&wmx$}NeH+QDKss|;RG+AGoESgW~v${pn
zzMGG43UHYwF-ole%QD5LzuQ)=h2R_r$N~UN`49RzEm|tb3Tar>mbb{Dx};pVoT*eW
z`t~6sUlUSW6i_VT`}t#>;c_+zJ6D6sX&>rBK1XjH3O`*o>n}1DkqpON6Z5&rgxh$K
za~$-qyn<Ns)j8XvEiIZ1-c;yhD||QADDuyTuuM^|@fYp8j2pVCCY4_%I=I+r2A?Ih
zb=&i^u=$=FcLB(hF1~90BvW>?uTx3V+L4Me4;3jr95iW`e6aw#z^(LN%*9074U^`{
zrq#JAwy_xVJ0HeY)_#I86tN8Gz`dLXKBwrZCyk)x+BeG=QzDqZ2(8$V#DKl~FiiLM
z*&QM&{SmU^k$mDx)*lkB@GmQv3C0cnEjvNmepOPcW2=2fok3su1V?Y2xBo#8kxCDh
z!*ei8_CBjmOJDSJMK?8MuNBKEm8G%#3c+u9V2u5j#)ejxr)51Lg1Os;Um%K1r7TR}
zNJykc<{g63;tpelojFmwIjkl7_#4YS$NI;dMrp^ZgFu7w@|xLx8DO8?;@9SdbNKG4
z(T8Wm@h#WPVQlyE(li}DW+8Y30ty2FQ~v`h&dRAs%RV>jOYW6`U+0lJ>iXcV2$`0k
z2oXGCJ}=LaICxR)!=|0`Qs1PmrS`mO3bvNoqS%}E;hd+@*IP>nV~L=AhJ7Fp_So~n
zBa0VDRGeG+ogSR;t=)#vw6Bf1c<ZLgF_HSazEFtp!YJ-h?^0CvIXM+Af)Lsq37FLH
zY+%XPxe+uDuphP!WW=C^4_xb?@N85jlnwm$PA&=vlT@$@bs)K|DH4b-Qe`wY$l@`U
z<jj%_TPc*5Yhg4cbhR13Co$C2&{T@Pa5T4k+1S+3^Zg3$pka}5+#LvsZ45h_=-6qP
zh0TMzK+N8CrS+ADC~D@f@K8-tiEg=dP&!^P&&)9tfEc_m1L^70&=x(%xGfGX&cYs&
zY-@=6YTcp!QDjFv3!yiXLPTq*E+cQ$K1G5rS^c>yk34%{xaJlsvtb=Q<ikd5hQ-T;
zb=JrBvc~}k*oY<>>T*J4XbrZdT5nW~ZXsw@Zcj^#B<#(*9r;AF#dPw2uisJjQ<>G^
zqww%!*p7D>PwHIQSw<BeM>mRCS)7wkY?CabXU>L$fE!^&lcE^dtnASy{^2b~O9R66
zD)czRhV~zn{~Er=-M?=Qx(L+phQt<v_aLAW0PyGkjqWf85tMK~jMzR5B{H$ut@S+z
zeiM^vqgRIHJ&vue5!#^Szq&AD+t|k^(}Iz|5*AcfvL)wwi!z4#H~Ak$1kH?l@t{|^
z`($sPeGEtC6Ohs3zbqlUus?ZKTc%P+^8ytAU58Z_Csh3~beV;<!%jZ2K$qt_y{=ka
z^`cI8j#-<s{Zj!?-nYe!a(WwXqc61KZ-deG1Qx|f#kitNxXxwJFpKAnx=)+Mb!Eg;
z*?xtcVP(mj=g0r!Jmxq;BaRYeIhNnv5xHgZ@I7c0(_!7vHA=BJPq-AZRUxxJw`*by
zhpzsasY76qfR9(C=G|_JJ+Sm=>o#u0RSpx`I0OZ8`kyfEfQC~HC2TNM_`m#*n4UdV
z_Pxo7*CDLY8%mCVvBx2s&0W0l!}Z7-ZqlDHu4~~jKuI|HJLMs@7y)Z>z9-a_A8!Tl
zaUC+BxnWfuPne5swm3zG1XrUp0?xUT4sLMK&7I_j+3KrheqnePzlqUy81XZd=~OU}
zp>T&;bTGnQAM-k#euPC0d&tn0FFqdHxN*npB{H&OEx7c|Bd1EFhoPb5&pbFm@<$hU
zv9MU5{RIKB>gYt%nPX5&+zSh*WYrJQEFe5GA%aA<{cY(&a5Mxo0syA{hYV*un!VzT
z<WYF`-K@EL;9x#Ag7t*h+9SUsqdb<9hMzm#7h`XPxiID%J;3A&r%e!kH1z>HxAM1v
zZ*@pO`JN^0!#o*Mv(C+a(23>}Drr^>zjOS0-r&<%hw$k%Os04EOA+IKK3x#f8AWZo
zrC-_7nR7$kec0Scwnb(HD(#7EEmo?yg5Wj3BQi_M9({Cv^ubK*=lX{(|0$Jn-oqwZ
z4P)rFgk$4%{JYbi<1l%M@Zl04jvPJEFv05!c61+n{Zl+zCJgp{+4B{U)GVuhU{8po
zWN$sRfL*8~ydG0j%2iV7qmHt25W+(i<y0eo-ShjPQ|^f?nLg|HZ*RMY*E9k0+58Nx
z$>|^tz46#l*CL8{%WuPnTNVG1-3C?eK8vI6WW$W|Nr~uwbrfCMJ~{7jH?L{?31R4B
z5u?b~?Y%L!s<7;R9h2>Y>2z<&a_3#TmH%};3L%@ZgQ^T_8o#(`jQ?LX5&pB0@k71_
zulrni*~09=U=HnjL18rnbP52b|A(=#W_}TqiNBaTQLAqZm%rr&GRCSmYm)G>76XHK
z6s`)TBOuU-0AR-dof(dIy}88IXy*sZPNl9&AK#3s-)Ga>P`ME-_G&Qo?Q|1z`>Aa#
zxc>SZHc+4Cx*4FzU^yF}|9HYx<Cf%Tg?g0yj>(GLD3tHG)R}DX2fZTgEj)dqqX{Qc
z1*u4$#4AI-TY?ZnE(3Pk&;JTAqESt<6laEIJXRY)`F?{M9(N!@nLmyd`Gop;(_`HA
z79qB7PpKe=D_k!W4f`1v)i^kb8o`7T^_YG1{%XqDGKK<LY+Dp)n~&5V_@(EkM06S(
zf!jMw?-xPvkDyJtLtlNLn%$li1IdS>>cUt)yAPliq7z%>wa7Nc*&|CKyZSJrS1YPY
zRHoVZKIdloo=4nqp&HxETHi{SYWoXZR<+vCE4xpRA)!4s=4`ZoflpB~t=cGn89al#
z#p=nZ69BI>3jU>948L}SgKK(`%}~H=kIeEG_T|;vWG*54x>?#X^V&#pxnit?x}4#o
zA~Ui$0u>6iH_s@JvZa!8FIinGZ3(7bsAL{*#O47l+3<4;G5oxO8!{!kCyALSAA{hX
zHiq?VHHd}LKCIz(C0m$P7?DY8P!(58scaX@9tUbM@Kx!3)zsL-r8sFst67q8<*SdC
z%B>QeTFi<R&QxpIeqbs=3=@GF5-3`TRrrK?K&>|0^Ra?e==yyb_NoGZqn*jx=xxA3
z3`W%enZ7dps4Vy$(^f$;tjGWApaXk`ImVKz?KL?D=Kw=|f&p4LYPbRph6C-%w^$kK
z$QyCfr64f)U$UsG?;>V3*7LK=C6;L$ZO70C@)6QU@LE8Xj-|uv3n||Q6esyY+UF>A
z9K!jx1A*p_b=}`}SS>3TBm9Z6#H$7cBh3EET6yiuO49oVVQN17yK9gdo&YKTn4OJ_
z+9XW1FEFL6knp7Ut8k<ZuEbTGTouMHu9-eu-xc0lPh#+^UazW!-YQIWj`<E)hP7@L
z8{?V>F6XxvTW{{ulC79_qEmoD$!2C7${1=CNKXZep@a`2_O>qR7>X0thno~ZjB1<A
z1+7s&(<4xD&T?wH6ivz}M7ymX?4rVIggy=ME@OpTA{KTkeF$u9HOz4Dw`LmGS_j}S
zZH#^D4lEAphNM5R5ar^2<nF)r5RFwumJ=vbPa3_Y9T03%$+5qC*njV+Ojh<t{zesD
zLhgUXq0zAP6#v!5<(PSBvS2c0<BNdR>$^iwQ0Cs<ti%V3nqo}k=RTGSZD+kR-!m=y
zhqT!<GC(ZDsafWWCWmvYgW|fATjt11(wzdiI!>@?5r%u>oV#+>CjFw>G(EwD+@*t%
z!S<`WDHE5-f%ke@SE~5p29m~wt_SSEy_g&Cg^k(R@aFD}v>I2viN%6tb=@U`_OPV>
zgKVk;fI7W`7R;AkfYL5A_H9&ap`oq*ixAiki9}Y$`3%>J;6CY(jocUmyL3DU2-=Ce
z%j~$6<Q!WAZi1D*Iet=1mg(6Lh*j*71`mSUmz?|eSrYau2OJ1nlE&uRkued!i|r)F
z<v>zFvnILG@0_%cj67CzdOb@&0@z6)M&vBHr-Wz4d1Mb~DCRfQAf9P)D|2wm&+r#b
zlJZ-f<F6pqpyL7w)8kMAlc2mQAMX@qM^dwJa1c9*0@tQ*2pKAJ(eJWqr*f)w$!2Z8
z^NFmD?5cR)wA+R`q?DPVGGx*-u7{wmiA~Bt5auVxtQKlpj=FpE&p$^XHcJLojp47s
zF=<^sjXoV5AA~8@^?716UGJ7Impl#F@s1~j?#ztZwRcss%@d(ygRunEX>Gm+69zeZ
z>k`ppL1G8!xAcz%w*wtnc_UhtYc8K8iKTiMvIdk<G<Zj1umg{r^5bH%+a|-Pcq{OF
zT1)Akf`c&4b4hE*cvW370*+I5*za?fW+M~UyG0H0Q9WnHS_Cm*A~|B7Bc9rR4kKju
z5>pp-C4nd6nb?8yZ8Pn$8Q+6rj#<X^yG-RTP0uQYI-5KbhNDi|YGG~9He>M5BQ>dn
zn6c_e`R>$96`Mnx>tSJt0&^=snM6)#Cp|_uwX;Vhs9h=>l-)qfVfsZ{<tvWjco~Q%
zezWkrVm-NlMcj~b<P#kn8Lov%dm+Eb$>_usH{&?O9bcBkQ5x$oH7nXSCrq69dO%HF
zVuX`d)b+P^&ita1nuzmr24D69%ra~houFpxdUB=J$9S)8B!on<?3pWbL9p^FggRm%
z%=}L_&e)eqN$Lgs&wSC#d*WQNV##kxUmbrs%`h0(T#qxs9DT7))jE1D%*dasV|Lnj
z{po*UhF*G>1O94^gUxuh8|Dep_FYyYbjnsu?HLi%nK*-~Dwjr5KZv$G*{n;DkR+Dp
z;$omNW~vm%Y;)z>CgAT%h*etXP=_WL%32&sn~*~E*>p(0=*W@XtNY{LK?Ss(grku8
zM#*0k0ofl7=b%AJZA;Rj9GFNvio>-c<eeE5fUJB>5z(J0EIryMG)dOGmh~O8w9On2
z5RjP!P_%bW<Ov<0v=M?D)NWn_vfaP_?y1Ue!I4Nv#NQCnDzNoYFYo%dP~O=S=JP$6
zo6A<O5Ig~aW&{8;|J#Yvte9+JdLQ?cH36-_zMAEB?g`8_?f4E3S%Pi9$xba1lCrR-
zcyxR66{aTLEOZR+h=jYTlGxL90E-E?Hm)nS^ALg}rzBHzn>LxI9|f-9KI?>ZO;17G
z$Ma3_<elt^@l0>&rURT1af?}|7ixQwrX%hpz%o=?(yoOUCLa3Oetx46eeoksy`qhg
zgjUD{&j{TqNdrw&KP6G)Y&_rAw+Y(73tsTp#9Yr;#$5d^U!=!E%F9ejKpfMYft?P!
zxf1&?k*LE3&=98jPPSMaxwd^lt>uuO-tio+nC}Vhd&;#$Lhon^?=i`>`ZDySZsrT8
zFu;222Gs(9JlS*PFP3TYh2;x1XS)rdZ)xLfhWFXI6O-y&>+7^sj}^x{gUsxJzC<Ip
zxJL&kF8bf07@iI{07UqK?QkZ^<9S$7K0>9>rX4GjUEt+zsOWG`^Bq_Ye~Vpv+ugZq
zz4huaL(yo@)p&G#>N?gCu0ow&MRjj7KsS<^?K%53fH)9W_sx%0@VTNS;MaoSfQ*`9
zfhwK`^dXCZF9x{=#s}Pw@h*nPJELGDboT^JITjAArEu<m?<47B=-jnCJhuOTJ{Pni
z0GRb3XVV5K@LiN$)Q-S&mZ1YRLCdSbpLMXaEE*K)#(rYFiQJ9E+(k8Kn^Ck<X`f`U
zb36Mh##>-pP_~0e;Lv93L&xj%fHM4<QhHm9P8h8Q$4OCJ_g91?easg2bWZk~l9|=R
zus>5yUQi5jy4TMXASskf?7>lqO3&F&LNspALu+*tabG@7)6+i2mfHH`3==|2R~g*~
z$z@}8TFyXTTljB8sa0DmQ`|P2VsCK4@Tvb_y(IlJ4x(syrl~0`E1JKNqR&KO^~)G`
zb9o75h+9R3{GJMnK^0J4?fn5VfV%kM)J=W;#+;D%*5%S&x(CYg2pR+)x^42OmoEjN
zhY$-p`8-@gojpbtyyilT*CM_yUF<xr7hG-`=Hz|u;TH;+eLe)b-XCGrrY30q1z5KV
zw8a!PadTh>pCKnxStZjYmVTGlNXTe5MS-qP+49d!$n3J1GcDgM$6xjm$j>Z=+|rXm
z@G1n_5di%4U(`v~23Qn0HLC!l-@aJLIl0!lHCjjTlB`9sa-{OW*?;Hg#Ayi3SDJbV
zenqCWp~k2ATsW=glO+y}%cPltH-l%ZX;f}r)N7;3LV+fLbvanpzo<|dL$lGP7M)Ml
z>C=MzWBohu66OHgcTTUq`fUhD`3@IizKkToIqWP;9B`n`xFuSZ1Q(eKKjT-MikyZ|
zat+CDn)p31{q9%?Jw1w&CwPApaRF4af%FCuyVuk?ox^Ij>Y$YC<`GEBcXIK;0IYVP
z48d%El%wX;%irQ2d`Bb6JWw8Vq`{&NvX0t$T>kFRXX4Y*R*b#k1qN1JJC~Uki7^sy
zF%ikDb1;OI;&efx^L{Olt)kj~7!S%O?#TtW-;iC({CU{TTVd*Bse?S^t(n??l435_
zfjrSJ+h@o$)G(!Y;lBkI*$pqy{?>(3ry((%)*=YSCtvyJ&zw$b3uokud~>e_;ifa%
z<WW<VdB=PDOFgG+n~*>9{Y&AQe||s>fkvuomZ50#Hd+q2m_Gb6HsJuo4@H*onZjk(
z<r4<=!>bfjDWG-{CEl$gZGyx!XeuBR25S|RH^hGN-jVLSG9+hC3($|ycTj;$Gg#y9
zW)%GYTU+P^05JPMTUW7V!k-W0#C8{do(XA>Oe5s)lw^(SM&ldb9KODrh2_JvM>|hR
zog*2wDaUiXg9S<JS>L-Gi6ge9!#82fAR&IEm5s|W!;sbXeE*;CCs?Qg!je>Nnt^EG
zB38xm#*Du{r;X<oq*=MKB_>-AGb4`OA?)qje8@j3;$l?Z)^o*Bwz;#@tJYjwhzBkU
z#XFWo5kWAfwoeMKZLZyKnmzHDfLyb~tQ*nXxsX~R$ZGbly3I^S&%M8mHM7sqf6s8P
zn`H5DV=+{6|J2yil%P2dt(Twlo#kAn+841OwVN->r*I7Fan6~>8}Ib~TSm3KGZ_lY
zM!qW{an#&Diqv7Iwfr~<y_U^WZg}cdMPn}K|8=J7)!SB{Af$Cs!9FZ;i*zU2Gstsq
zb^~OeN+$Hg;iE>`G#tnFxWQ2<%FD^Ro3eSL^waq%9(7RC;7<Mrqu{m0MkJi%2h0w3
zSeO*?I)LMl?TF)vbng((J(#gNWG9gZ;O|d;mT+gj7+r7`<A+3JOi^h-wYS(<7Sfqm
zl^7-E9fTJ6Vdu_78cWdrdg>j56ii=<(u+KP<f5Rk9Q*w%|3F-o8s<PRP0NYqK-Adg
zCoTP=EdzdK{fc!I2PXMnI{<tk_<v{8dH^uzKj;!xZ4?qe4GQUbzMpH8jYYkTgzzJM
z@^=lq5j&0#mZ9NV?-ttNPy^<v(wwdFn}C4|`Y<$0zC9|^zpd`ypz+wsuALgq7NFr4
z9K_++d@U_WS8DG&%R?=J4=e~XKfbqqKSvw*o16EWJV?BTjAEmA56NYm{_kr@wz8^1
zx(Nr<c}p6w)}*-+Q0j_P9DZ64JMH%NSXQc7FBWvq!4s*mH=W7}MDakKlXLt0jOjl(
z@YgOW*4%2mB_0(_{7G<t9Kio<Vl!PbGF-kB%h<&q0RJKtBrVH3AW6u3u>KhG^qscX
zwaMtgC>@JVIQ;!yPaoGSKkwr?!G5BbW$QL(Ch6PF?>}l%so7b2qK}f20iEWtazbYN
zedHT6H8u>PsHW0P-Bsh2=?eeSu4t+|dtGc{J(UmCMq2c~azNGEh5CUP31k8TcZ<``
zf+QtpM-egyX0>7?WkOk>n|ukqDdc&vCeJ`dql6d{8?Fhz{?s6^!039}4i$obL!jpY
zz}){N7E5*wK8MZc%~vsh{Da9%np{0UCfDe4z^91(-XdXo`MAa?U%+Pwrkfo-5a$)o
zC{SgBw|fPLF{j}2++WLXVjx^JvP;*Ju$24Gg0?ZYmSOP6{8&dDC3!7zdMMv=1PC_a
zIu;^9C8fj&)_h*Q|Ga%&bE5oXY!4V*tbp{L^v3I)c>BCPp44ac_WZY;;obJ5U&WJ}
zgl!##SHA9XehRkJ;bOXD!zY=;Q%?db(v5|0O7YH6HuckTD3-6z0g~RHX<x+sfEj}^
zWN25k>=oyBDTXQ9_PSq0VA6352~;t$EAKU<oSYCcNHhOBpb~aZv53MozP?-WbgQ28
z2)%>f;T{73HJ8kCv9jXdlJEEqY;+{W%LMHkbpSudd;(GQtKPH_=naTZp}wKmA@MBk
zl=BWS{{-|WAk1!vSV32vSghr;X8rZ=<J@<GUShWilUd96Vp++3GcE0Nni%h&n3|3F
zf*x45cZ3noE0dDFLA9~D_|2fcE|0XwYN4M)h<pPU)&2sO4k0~!OaZ&IM~&uNi=Kwo
zYoHZ;G1c?ptU2_O<AVN`VWAid1o|ET%=^!7nKl6N*J197<1NY-&9;%mS#8?kmdslU
zN~kDQsbXX{;&pUZS(5mq6dMH@N3Kz(rwF?jNMVESqmw^b2?dFuT$<ZxmW*pBBle={
z0ZG;9LOgegTSxbaPC&_wXK0uSrn;srSIc3x?m6?f0JR)q$D4-El^>|MWqjsWrb^5f
zv&!~KF*Az=5A;Qju!#FBF6bfvW+QZQV?@u?7phCr&I%f-Rqu|1<3ZN-Wl?v}jp1da
zrx=&iM0O^e2bS*B_+x~N6U3G99O2SuB|`C%{|;eL{B`I$Gp-N~OOr#a%&7m;AlOtX
z%hGy|^XgM>T7`7=K5%3oOJ9rR(Vn7!AErmIkt{lo@E3(|#uwBLvi*I=SQ(JW|Ea6H
zJh(J_aSh*!zXW4t4|L4eF9Eq9+Rxt`g!`%dfIr$?!Rq$LcSuw@48aaR8q49v6%X}~
zh1v4Z0ue5kniDH&WS_Ax;}0DU#yn_+J$}8IO1W3<+LP;dL_h78#r*SLq#)*i*tRM7
z7@?j@=fAXaBJ8nT9VrV71v*pQ<?w?+2X8Pd-O+e75_+kF%p~dYYW03afvN8>(wt<N
zqoVMBSpPD<RSjDv$;w9-@K{(Th%}G!7G`@?ZQOIt$!ZfDx?dcwwVqyuL?&X<Vo}<K
zR)^-DP4@D6G?#N0f-4~~H~?V&|NZ38iPC@HgKzH>$0C&^CAHpGg~Ar41D+LDVTK+z
zuM~GOP2lGmz&YT}w$JXjV+te{!ru=Wekp&dF;7hkz(y4J92Abs5*FuROIxgWJa#Pb
z)zIhk^yp0y*qwwrJ4ZnBS&Fesu|;@9*2>`^wvYCj48g5G{y~z>PoH8uRZSr?2&(wL
z7p2EjP)$K?6XR1WPxW&OtKz}(Px%^L&Iy1OXitgoo%Rq%4qPAJyju}DFcfaBW2~<r
zOlnIWJ0k(B00umyjgpc9t*pBc=2^7`tS7N6w_rabfPzYo?Yq9isibTfyk-g$x|KT(
z1@<&6exH16LiSqU^Bb3D$0O2Wv98d{o+<bVsy?twBISZ^u*=IHZXZxR1QHg4P2Jow
zm~I-wClDtc{KX5w_+B!zOxyfcgnNU(y6AoDhm=5WOx-4w2IJUoieJ{L>e08pc4L=F
zTg<y;YAK)=_@FQyn1YFMbu_jy*rqmDdAN4sPt_N$X9_2lrLKczf~2N#TXs;l@UF|q
zJrvQez#3c*LAuuXY=kyq@3$4-3#%b8JOE(9e^^9LbSnQMZ4q>}?0H3Ck%2y&-WT!M
zaNjj?H9_(g4-ti6JqU~r09g3n`nib4q<N>L2M$xU9{WW<gd^!gtfn*V&8BXIYUL^B
z5Px_DRILKpb1L;02_HAw;7xzU8|>o-muW3^pG&>27$u9QbK>eBiZDK$G_~8c|4YW%
z4@B3)^O<mAsDvpUcE{4XYqLAw^<Zai*|=f|k1=7iVk9-iA6Yn4c7W)EP!n&hZ;IsJ
zRV#J&AnmCC)YQLxR&68HG8_Gw)sqvi1=TLuEq_L+<sB<fSATP)8*VEP!*1jAH_yP|
z?8y3j4<4(oZ^bhH#IC|}))QF{%ipPUJDxA!H5#lbK4$(l%ZlXA2f?D2nQi<$A!~Sj
z9JXf*4XT{T<~+>k&DxIkAWCz&qXLIp#=?*5?MQ(}UFl+b5H%)34UxT;UH<ha8hRtU
znNbV)cw4#*)u+MGa3}S&T#gnC4ApEs{neyKABhY>BEpkycr;O}gibF6pFv=J0KlUE
zg1cQmj22klq)n3iv5$2Vv?fG_S5d7pTD@N0mN({^QKpr-TqM|hfqPPP7kdLiSOndH
zz2}F5>m=)HU>7M@5s4;6<vF~n)tX5Uze_-@So?P$GIIj7R3t)@@b)KhW)0xtU(}kF
z`jHT((wovZ3Ocu4r0zayl}nxBs{OOo#x*KCWZI@(?i)2Xi;kqh1!9h6xch<%3^1V|
zhmku%KAE(c$_sxjdL)eqci9oi7WAy7x<}^8GYWVq?ETZACtk&aWy28Su(8#?Pw>s=
zOc%gMIeefg#E$wcd<w3w_)}+#Z0wUly*o)(vEUyJv38Cm@hH|Dd^s-qWW4EuVxjDn
zs)B6?p!{_hF>&(r99N;)afROjchder3+Y-v;&BqJm+EsN;#O%iyuB;)u(ihYI_wC$
zx+kGjfmK0qs@tKYtOUA{lyG^8rj$PA8g6=Ha#(tky~N|Mv5{RX_pi33^H_JH#ovt&
zpBMn`Y}GFRWPT>EPh^|EB~6=7yO^&><h7jP$ixN>c7<U4%dMi>_lz(1b#V>xM!!}F
zjlfAJ3f3d;@c8)=J&rFk@*(hYxZ0FWWLm35$-HNJ%Hjzkac`lf+0c?!4H~|_z9wYF
zH(W&I=#R*@hJh;theBYo0Knq^u+QIq=~9^|3VG@jZi$*^x0NPr+i34KQ<P2d3Yh6B
z3!FEX2uR+3{CybU{R^i*LGaigwGQJ;JYPy`D|cj$3s(&8A;hj7!FiBEAdLJCicp8y
zgR4+(!}~Xp-hbc$!X%~P+Qr7{R2GPD(|wjEI2EN@dL#H4Y~s>*4E+#rszx{tf{xuP
z;2X9&NG<%qYJa&LVih&OD^V&h)+FqkXsp=LNTONP%626T)=3v7{tWPgYFjiWF7nNE
z%1YoSXrQY7h4cr<W&pqQW`GI~tK#K6?_XM1&@fqqbv*Blx{Su}i77(j*InG(KfizI
zmsm*exkmr`Zdxh2S8XjMbF}dVKDqUa<;)**x_O}&oZSQfXX9l6rlI`iB(htNdxs81
z?D@SrJ;|=f4Qa`#b)BKf9=+z?e4HYRj_V_EhgUnUlqj(KjpbA{4gb?uATgQPm^J(7
zL1m*ssUMR;4kGSP+%gYJdcp7XX_N5|bg|${1icP_5spG|GX$m+04({BVHTjT50x?X
zwwu~fIpulo-A$^sE@m{<b2df!QJ5hu{~+Xf_T(3)4dS?lFUM`%WgScLKCV;@X2;f6
zMlYcj7pBsBhxXs3oM!fg=&2;?d5)g}h}~I7ej-foT|G4tK>Qk%jm1dfxsXX9n%U-<
z4&2h5!@N;p2k<)Iy4^28O^v9brbNn9u(=PRb9%Au+*!SSo4em1hP|Yfc&4y5zkknL
zw4fJj!?D7y!O<&Sg5olZQ2iWuCjb}O_M2ZV|BK};&gb~*2?yU=kK5t#IDb6o&ko>`
z<aX_Q%X`Ac=l*y#!t&m{0UM-3H@mh97Uj{Sta%rbtHLamUHtIGEFX`nfeO*n&EjH*
zviz4>+aeRVZ%|<>(E3*C_SJaU<XL0VvG-}v)D(_hc#Ok&nT=z!Gx?lCPoNwt&5_Na
zWaOhT^vH-~V#K<JZYaEc*pvjLqaB^M^8GDm7rRE7JdDJ|<j#47geqw#<#6a%{=1Sv
z>on+>PV_AX-<)k+b-yN^&0)SA_hqH9&(-xJU9fIlXdtCCO!h46L(<45{_4N&7hPP*
z^+IqG1ZE2WEd9?7iP{&Fq?-Gix#Z0iF}*EEk~8!k)`_>W2j`+c(uS*rv`m*SkHE7s
zw<^~@R=M3^ja>qXgDU*2Aj+aD_9tXoUSRT%KTQ~XM$|ePuE@ElY@ke%pjZ3FUM3OM
z42;~*lFrq7*daGy_Znrw?Z@;!b5qSi&f5E{lUW2(1U2ETj2C}e>)v&HwS;Cp!-=zk
zD|oT>>$xylDEP;>L<CoyA`yZ`*WfU<xOV3`<a`lmB*X-fVtR$8_v+c^-;G|Lq7GKj
z$NyMxFy5f}5h?p=LF5FJIh_Q5!+L|wOPL`8J3;|OYOy;=aimn^_AW|Hvivy>;N6JY
zI-a5G&FbW5f8V})8Ey=cN+Rc}l0O^1YMfzi)VM^RPD`fTRPM6k%Yv7f2hVb-1i{qG
z69_bj(OS7@J;kLv0~&g?uZ(O1(lRM;tYb;3Z-OKh&D|60AutRz<*C~hf8vxv($`XZ
zAax~i2%i}^^D!?tzRcG720JpJ=1KRK-7?}iLX4hw#74C782^7N8q6mESoR;vlSj=x
zv@I*Dk6d0QhEiXIyY4{8NiF3EJhvaIb<<$Kyeb;pw=@J<;qa9D8~D1Sao-%nZcc93
zHN4b@muE!KvNt?=x_*8lUNa)jJLPXNVHlnUz<5EPUQc28sMSmp%hT_8rLJp!72xw#
z3WOj)Lsq~qK`5FzC?Z_rIoOGLFs0YqrqoOD+>w#+OU@7<2_^q#LD3{QKdb7j3qjf7
zJ@cyRO935#-ky2|?`#aGjyD73K1lc5KF+%mA5CQ2qb59YsBYBxoAnbOE5?xa7MFt2
z594p;yZ$?Ltdaw4gL66aT$BhH^==EJKiFHWpPNCN(Td1RJ>PF*eom2>P1dJ!CI7u6
z{MK`do%XLAZasIsH|U?RUG+RKkmc>YQ`8IIU*>O7bXNDZMRUWox3D5479-FTW0BB>
zO?zDXzK&YgAYg*v*I*DcP}PF{?ydz!O?`~8H_(=X^zulZ>ILdIWjIE+_;eIc?2S%x
z^F6F)xEUxwC01J@K|s3~1Rlk7j2<GUGBzv9DAK83Ji%Z(<|?xfYgEaX`}H&db$e~4
z4b4x}D_Z~fjHGF)6*x5p0c1NDiU~kqNdds}{}{=4jg<3x^e9lavA&1QnG}3VA`4LE
zynKmRp0ql|R+n4}!}~hm>;co6$X5VK{LMT?b{dE%w3A+CD!wZX9|&hRQeiCh0AXcz
z%xT1V-WtQUH{bVau<M*5cZ;<NEmk%M=qy|1WSa&b$NHaYsaMI6a4-GPOccz|_(Wj$
zX<zpWrirsDMxsM292g9E*)~_&SuvO16RCYavq8MS9FQQx&9f!CKT-VFzxpg4NUW>p
z$m=L{Cv$N2voQ*llk>4CNk>{>A@YP2{6~vz>jXK~3NRo$+^K`lD{dsqj4VGWxL)l=
zB%UUO!o&#ea5|OF(?%<$@#l)?rL?GjfaPJ>#v)<hoUrpOxqUG}6v|imXt&>ziMRZo
z>MHu>VTkEKR7o99;-4|r&=(!F;~iG}XTp)+@59G$$S+r~w?%2SbICqO)vCCyujtSV
zE8DWwvf!4UwI762x#i=76Q{k?@Yy}<hQPv-=}mr-1EP~p^+V!-fm)@Eg_*cB_%Zue
zC7eVQ9dj|giA)qlTVC(q^joik+8nj+%L*9Jp3@skl)MJN#B9WO2;9#1Wc;qH8<vJV
zipU$YMwuCW*PMTd6P_fDN5Y%rBeY!992rNX#z)&ABmJVAz?qr3y@f%P=fR2$wTlE@
z=jN6*5CQ_C)2Zrw+(N8j!>;z)J$Bhae2n~%hcsW=ECTfLQ^R<9*9DYMS#H!L5&@0r
o7eck6f}dXy<B-*Ys(>hgOoZwkc5xjsjSxU<#3KawHy8-|e~G?AO8@`>
new file mode 100644
--- /dev/null
+++ b/dom/media/test/bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^
@@ -0,0 +1,1 @@
+Cache-Control: no-store
--- a/dom/media/test/eme.js
+++ b/dom/media/test/eme.js
@@ -414,16 +414,17 @@ function SetupEME(test, token, params)
   });
   return v;
 }
 
 function SetupEMEPref(callback) {
   var prefs = [
     [ "media.mediasource.enabled", true ],
     [ "media.eme.apiVisible", true ],
+    [ "media.mediasource.webm.enabled", true ],
   ];
 
   if (SpecialPowers.Services.appinfo.name == "B2G" ||
       !manifestVideo().canPlayType("video/mp4")) {
     // XXX remove once we have mp4 PlatformDecoderModules on all platforms.
     prefs.push([ "media.use-blank-decoder", true ]);
   }
 
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -1344,16 +1344,66 @@ var gEMETests = [
       "7e571d037e571d037e571d037e571d11" : "7e5733337e5733337e5733337e573311",
       "7e571d047e571d047e571d047e571d21" : "7e5744447e5744447e5744447e574421",
       "7e571d037e571d037e571d037e571d12" : "7e5733337e5733337e5733337e573312",
     },
     sessionType:"temporary",
     sessionCount:3,
     duration:1.60,
   },
+  {
+    name: "WebM vorbis audio & vp8 video clearkey",
+    tracks: [
+      {
+        name:"audio",
+        type:"audio/webm; codecs=\"vorbis\"",
+        fragments:[ "bipbop_360w_253kbps-clearkey-audio.webm",
+                  ],
+      },
+      {
+        name:"video",
+        type:"video/webm; codecs=\"vp8\"",
+        fragments:[ "bipbop_360w_253kbps-clearkey-video-vp8.webm",
+                  ],
+      },
+    ],
+    keys: {
+      // "keyid" : "key"
+      "f1f3ee1790527e9de47217d43835f76a" : "97b9ddc459c8d5ff23c1f2754c95abe8",
+      "8b5df745ad84145b5617c33116e35a67" : "bddfd35dd9be033ee73bc18bc1885056",
+    },
+    sessionType:"temporary",
+    sessionCount:2,
+    duration:1.60,
+  },
+  {
+    name: "WebM vorbis audio & vp9 video clearkey",
+    tracks: [
+      {
+        name:"audio",
+        type:"audio/webm; codecs=\"vorbis\"",
+        fragments:[ "bipbop_360w_253kbps-clearkey-audio.webm",
+                  ],
+      },
+      {
+        name:"video",
+        type:"video/webm; codecs=\"vp9\"",
+        fragments:[ "bipbop_360w_253kbps-clearkey-video-vp9.webm",
+                  ],
+      },
+    ],
+    keys: {
+      // "keyid" : "key"
+      "f1f3ee1790527e9de47217d43835f76a" : "97b9ddc459c8d5ff23c1f2754c95abe8",
+      "eedf63a94fa7c398ee094f123a4ee709" : "973b679a746c82f3acdb856b30e9378e",
+    },
+    sessionType:"temporary",
+    sessionCount:2,
+    duration:1.60,
+  },
 ];
 
 var gEMENonMSEFailTests = [
   {
     name:"short-cenc.mp4",
     audioType:"audio/mp4; codecs=\"mp4a.40.2\"",
     videoType:"video/mp4; codecs=\"avc1.64000d\"",
     duration:0.47,
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -177,16 +177,22 @@ support-files =
   bipbop_360w_253kbps-cenc-video-key1-1.m4s
   bipbop_360w_253kbps-cenc-video-key1-1.m4s^headers^
   bipbop_360w_253kbps-cenc-video-key1-init.mp4
   bipbop_360w_253kbps-cenc-video-key1-init.mp4^headers^
   bipbop_360w_253kbps-cenc-video-key2-1.m4s
   bipbop_360w_253kbps-cenc-video-key2-1.m4s^headers^
   bipbop_360w_253kbps-cenc-video-key2-init.mp4
   bipbop_360w_253kbps-cenc-video-key2-init.mp4^headers^
+  bipbop_360w_253kbps-clearkey-audio.webm
+  bipbop_360w_253kbps-clearkey-audio.webm^headers^
+  bipbop_360w_253kbps-clearkey-video-vp8.webm
+  bipbop_360w_253kbps-clearkey-video-vp8.webm^headers^
+  bipbop_360w_253kbps-clearkey-video-vp9.webm
+  bipbop_360w_253kbps-clearkey-video-vp9.webm^headers^
   bipbop_480_624kbps-cenc-audio-key1-1.m4s
   bipbop_480_624kbps-cenc-audio-key1-1.m4s^headers^
   bipbop_480_624kbps-cenc-audio-key1-2.m4s
   bipbop_480_624kbps-cenc-audio-key1-2.m4s^headers^
   bipbop_480_624kbps-cenc-audio-key1-3.m4s
   bipbop_480_624kbps-cenc-audio-key1-3.m4s^headers^
   bipbop_480_624kbps-cenc-audio-key1-4.m4s
   bipbop_480_624kbps-cenc-audio-key1-4.m4s^headers^
--- a/dom/media/test/test_eme_requestKeySystemAccess.html
+++ b/dom/media/test/test_eme_requestKeySystemAccess.html
@@ -385,22 +385,94 @@ var tests = [
       label: SUPPORTED_LABEL,
       initDataTypes: ['cenc'],
       videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
       audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
     },
     shouldPass: true,
   },
   {
-    name: 'WebM CLEARKEY_ID not supported',
+    name: 'Basic WebM video',
+    keySystem: CLEARKEY_ID,
+    options: [
+      {
+        label: SUPPORTED_LABEL,
+        initDataTypes: ['webm'],
+        videoCapabilities: [{contentType: 'video/webm'}],
+      }
+    ],
+    expectedConfig: {
+      label: SUPPORTED_LABEL,
+      initDataTypes: ['webm'],
+      videoCapabilities: [{contentType: 'video/webm'}],
+    },
+    shouldPass: true,
+  },
+  {
+    name: 'Basic WebM audio',
+    keySystem: CLEARKEY_ID,
+    options: [
+      {
+        label: SUPPORTED_LABEL,
+        initDataTypes: ['webm'],
+        audioCapabilities: [{contentType: 'audio/webm'}],
+      }
+    ],
+    expectedConfig: {
+      label: SUPPORTED_LABEL,
+      initDataTypes: ['webm'],
+      audioCapabilities: [{contentType: 'audio/webm'}],
+    },
+    shouldPass: true,
+  },
+  {
+    name: 'Webm with Vorbis audio and VP8 video.',
+    keySystem: CLEARKEY_ID,
+    options: [
+      {
+        label: SUPPORTED_LABEL,
+        initDataTypes: ['webm'],
+        videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}],
+        audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
+      }
+    ],
+    expectedConfig: {
+      label: SUPPORTED_LABEL,
+      initDataTypes: ['webm'],
+      videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}],
+      audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
+    },
+    shouldPass: true,
+  },
+  {
+    name: 'Webm with Vorbis audio and VP9 video.',
+    keySystem: CLEARKEY_ID,
+    options: [
+      {
+        label: SUPPORTED_LABEL,
+        initDataTypes: ['webm'],
+        videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}],
+        audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
+      }
+    ],
+    expectedConfig: {
+      label: SUPPORTED_LABEL,
+      initDataTypes: ['webm'],
+      videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}],
+      audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
+    },
+    shouldPass: true,
+  },
+  {
+    name: 'Webm with bogus video.',
     keySystem: CLEARKEY_ID,
     options: [
       {
         initDataTypes: ['webm'],
-        videoCapabilities: [{contentType: 'video/webm'}],
+        videoCapabilities: [{contentType: 'video/webm;codecs="bogus"'}],
       }
     ],
     shouldPass: false,
   },
   {
     name: "CDM version less than",
     keySystem: CLEARKEY_ID + ".0",
     options: [
--- a/dom/media/webvtt/WebVTTParserWrapper.js
+++ b/dom/media/webvtt/WebVTTParserWrapper.js
@@ -49,19 +49,19 @@ WebVTTParserWrapper.prototype =
     };
   },
 
   convertCueToDOMTree: function(window, cue)
   {
     return WebVTT.convertCueToDOMTree(window, cue.text);
   },
 
-  processCues: function(window, cues, overlay)
+  processCues: function(window, cues, overlay, controls)
   {
-    WebVTT.processCues(window, cues, overlay);
+    WebVTT.processCues(window, cues, overlay, controls);
   },
 
   classDescription: "Wrapper for the JS WebVTT implementation (vtt.js)",
   classID: Components.ID(WEBVTTPARSERWRAPPER_CID),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebVTTParserWrapper]),
   classInfo: XPCOMUtils.generateCI({
     classID:    WEBVTTPARSERWRAPPER_CID,
     contractID: WEBVTTPARSERWRAPPER_CONTRACTID,
--- a/dom/media/webvtt/nsIWebVTTParserWrapper.idl
+++ b/dom/media/webvtt/nsIWebVTTParserWrapper.idl
@@ -72,16 +72,17 @@ interface nsIWebVTTParserWrapper : nsISu
    * overlap avoidance using the dimensions of 'overlay'. Finally, it adds the
    * computed divs to the VTTCues display state property for use later.
    *
    * @param window  A window object with which it will create the DOM tree
    *                and containing div element.
    * @param cues    An array of VTTCues who need there display state to be
    *                computed.
    * @param overlay The HTMLElement that the cues will be displayed within.
+   * @param controls The video control element that will affect cues position.
    */
   void processCues(in mozIDOMWindow window, in nsIVariant cues,
-                   in nsISupports overlay);
+                   in nsISupports overlay, in nsISupports controls);
 };
 
 %{C++
 #define NS_WEBVTTPARSERWRAPPER_CONTRACTID "@mozilla.org/webvttParserWrapper;1"
 %}
--- a/dom/media/webvtt/vtt.jsm
+++ b/dom/media/webvtt/vtt.jsm
@@ -1115,39 +1115,54 @@ this.EXPORTED_SYMBOLS = ["WebVTT"];
 
   var FONT_SIZE_PERCENT = 0.05;
   var FONT_STYLE = "sans-serif";
   var CUE_BACKGROUND_PADDING = "1.5%";
 
   // Runs the processing model over the cues and regions passed to it.
   // @param overlay A block level element (usually a div) that the computed cues
   //                and regions will be placed into.
-  WebVTT.processCues = function(window, cues, overlay) {
+  // @param controls  A Control bar element. Cues' position will be
+  //                 affected and repositioned according to it.
+  WebVTT.processCues = function(window, cues, overlay, controls) {
     if (!window || !cues || !overlay) {
       return null;
     }
 
     // Remove all previous children.
     while (overlay.firstChild) {
       overlay.removeChild(overlay.firstChild);
     }
 
+    var controlBar;
+    var controlBarShown;
+
+    if (controls) {
+      controlBar = controls.ownerDocument.getAnonymousElementByAttribute(
+        controls, "class", "controlBar");
+      controlBarShown = controlBar ? !!controlBar.clientHeight : false;
+    }
+
     var paddedOverlay = window.document.createElement("div");
     paddedOverlay.style.position = "absolute";
     paddedOverlay.style.left = "0";
     paddedOverlay.style.right = "0";
     paddedOverlay.style.top = "0";
     paddedOverlay.style.bottom = "0";
     paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
     overlay.appendChild(paddedOverlay);
 
     // Determine if we need to compute the display states of the cues. This could
     // be the case if a cue's state has been changed since the last computation or
     // if it has not been computed yet.
     function shouldCompute(cues) {
+      if (controlBarShown) {
+        return true;
+      }
+
       for (var i = 0; i < cues.length; i++) {
         if (cues[i].hasBeenReset || !cues[i].displayState) {
           return true;
         }
       }
       return false;
     }
 
@@ -1164,16 +1179,21 @@ this.EXPORTED_SYMBOLS = ["WebVTT"];
         fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
     var styleOptions = {
       font: fontSize + "px " + FONT_STYLE
     };
 
     (function() {
       var styleBox, cue;
 
+      if (controlBarShown) {
+        // Add an empty output box that cover the same region as video control bar.
+        boxPositions.push(BoxPosition.getSimpleBoxPosition(controlBar));
+      }
+
       for (var i = 0; i < cues.length; i++) {
         cue = cues[i];
 
         // Compute the intial position and styles of the cue div.
         styleBox = new CueStyleBox(window, cue, styleOptions);
         paddedOverlay.appendChild(styleBox.div);
 
         // Move the cue div to it's correct line position.
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -94,16 +94,17 @@ DIRS += [
     'camera',
     'audiochannel',
     'broadcastchannel',
     'messagechannel',
     'promise',
     'smil',
     'telephony',
     'tv',
+    'url',
     'voicemail',
     'inputmethod',
     'webidl',
     'xbl',
     'xml',
     'xslt',
     'xul',
     'resourcestats',
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -1032,17 +1032,17 @@ Notification::SetAlertName()
 already_AddRefed<Notification>
 Notification::Constructor(const GlobalObject& aGlobal,
                           const nsAString& aTitle,
                           const NotificationOptions& aOptions,
                           ErrorResult& aRv)
 {
   // FIXME(nsm): If the sticky flag is set, throw an error.
   ServiceWorkerGlobalScope* scope = nullptr;
-  UNWRAP_WORKER_OBJECT(ServiceWorkerGlobalScope, aGlobal.Get(), scope);
+  UNWRAP_OBJECT(ServiceWorkerGlobalScope, aGlobal.Get(), scope);
   if (scope) {
     aRv.ThrowTypeError<MSG_NOTIFICATION_NO_CONSTRUCTOR_IN_SERVICEWORKER>();
     return nullptr;
   }
 
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
   RefPtr<Notification> notification =
     CreateAndShow(aGlobal.Context(), global, aTitle, aOptions,
--- a/dom/push/PushManager.cpp
+++ b/dom/push/PushManager.cpp
@@ -148,17 +148,17 @@ public:
   GetSubscriptionResultRunnable(WorkerPrivate* aWorkerPrivate,
                                 already_AddRefed<PromiseWorkerProxy>&& aProxy,
                                 nsresult aStatus,
                                 const nsAString& aEndpoint,
                                 const nsAString& aScope,
                                 nsTArray<uint8_t>&& aRawP256dhKey,
                                 nsTArray<uint8_t>&& aAuthSecret,
                                 nsTArray<uint8_t>&& aAppServerKey)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
     , mProxy(Move(aProxy))
     , mStatus(aStatus)
     , mEndpoint(aEndpoint)
     , mScope(aScope)
     , mRawP256dhKey(Move(aRawP256dhKey))
     , mAuthSecret(Move(aAuthSecret))
     , mAppServerKey(Move(aAppServerKey))
   { }
@@ -355,17 +355,17 @@ private:
 };
 
 class PermissionResultRunnable final : public WorkerRunnable
 {
 public:
   PermissionResultRunnable(PromiseWorkerProxy *aProxy,
                            nsresult aStatus,
                            PushPermissionState aState)
-    : WorkerRunnable(aProxy->GetWorkerPrivate(), WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aProxy->GetWorkerPrivate())
     , mProxy(aProxy)
     , mStatus(aStatus)
     , mState(aState)
   {
     AssertIsOnMainThread();
   }
 
   bool
--- a/dom/push/PushSubscription.cpp
+++ b/dom/push/PushSubscription.cpp
@@ -59,17 +59,17 @@ NS_IMPL_ISUPPORTS(UnsubscribeResultCallb
 
 class UnsubscribeResultRunnable final : public WorkerRunnable
 {
 public:
   UnsubscribeResultRunnable(WorkerPrivate* aWorkerPrivate,
                             already_AddRefed<PromiseWorkerProxy>&& aProxy,
                             nsresult aStatus,
                             bool aSuccess)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
     , mProxy(Move(aProxy))
     , mStatus(aStatus)
     , mSuccess(aSuccess)
   {
     AssertIsOnMainThread();
   }
 
   bool
--- a/dom/security/nsCSPParser.cpp
+++ b/dom/security/nsCSPParser.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/. */
 
 #include "mozilla/ArrayUtils.h"
+#include "mozilla/Preferences.h"
 #include "nsCOMPtr.h"
 #include "nsCSPParser.h"
 #include "nsCSPUtils.h"
 #include "nsIConsoleService.h"
 #include "nsIContentPolicy.h"
 #include "nsIScriptError.h"
 #include "nsIStringBundle.h"
 #include "nsNetUtil.h"
@@ -115,16 +116,17 @@ nsCSPTokenizer::tokenizeCSPPolicy(const 
 
   nsCSPTokenizer tokenizer(aPolicyString.BeginReading(),
                            aPolicyString.EndReading());
 
   tokenizer.generateTokens(outTokens);
 }
 
 /* ===== nsCSPParser ==================== */
+bool nsCSPParser::sCSPExperimentalEnabled = false;
 
 nsCSPParser::nsCSPParser(cspTokens& aTokens,
                          nsIURI* aSelfURI,
                          nsCSPContext* aCSPContext,
                          bool aDeliveredViaMetaTag)
  : mCurChar(nullptr)
  , mEndChar(nullptr)
  , mHasHashOrNonce(false)
@@ -132,16 +134,21 @@ nsCSPParser::nsCSPParser(cspTokens& aTok
  , mChildSrc(nullptr)
  , mFrameSrc(nullptr)
  , mTokens(aTokens)
  , mSelfURI(aSelfURI)
  , mPolicy(nullptr)
  , mCSPContext(aCSPContext)
  , mDeliveredViaMetaTag(aDeliveredViaMetaTag)
 {
+  static bool initialized = false;
+  if (!initialized) {
+    initialized = true;
+    Preferences::AddBoolVarCache(&sCSPExperimentalEnabled, "security.csp.experimentalEnabled");
+  }
   CSPPARSERLOG(("nsCSPParser::nsCSPParser"));
 }
 
 nsCSPParser::~nsCSPParser()
 {
   CSPPARSERLOG(("nsCSPParser::~nsCSPParser"));
 }
 
@@ -1002,37 +1009,32 @@ nsCSPParser::directiveValue(nsTArray<nsC
 
   // special case handling of the referrer directive (since it doesn't contain
   // source lists)
   if (CSP_IsDirective(mCurDir[0], nsIContentSecurityPolicy::REFERRER_DIRECTIVE)) {
     referrerDirectiveValue();
     return;
   }
 
-  // special case handling of the require-sri-for directive (since it doesn't
-  // contain a source lists but rather types, e.g., style or script)
-  if (CSP_IsDirective(mCurDir[0], nsIContentSecurityPolicy::REQUIRE_SRI_FOR)) {
-    // handled in directive()
-    return;
-  }
-
   // Otherwise just forward to sourceList
   sourceList(outSrcs);
 }
 
 // directive-name = 1*( ALPHA / DIGIT / "-" )
 nsCSPDirective*
 nsCSPParser::directiveName()
 {
   CSPPARSERLOG(("nsCSPParser::directiveName, mCurToken: %s, mCurValue: %s",
                NS_ConvertUTF16toUTF8(mCurToken).get(),
                NS_ConvertUTF16toUTF8(mCurValue).get()));
 
   // Check if it is a valid directive
-  if (!CSP_IsValidDirective(mCurToken)) {
+  if (!CSP_IsValidDirective(mCurToken) ||
+       (!sCSPExperimentalEnabled &&
+         CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REQUIRE_SRI_FOR))) {
     const char16_t* params[] = { mCurToken.get() };
     logWarningErrorToConsole(nsIScriptError::warningFlag, "couldNotProcessUnknownDirective",
                              params, ArrayLength(params));
     return nullptr;
   }
 
   // The directive 'reflected-xss' is part of CSP 1.1, see:
   // http://www.w3.org/TR/2014/WD-CSP11-20140211/#reflected-xss
--- a/dom/security/nsCSPParser.h
+++ b/dom/security/nsCSPParser.h
@@ -106,16 +106,18 @@ class nsCSPParser {
                                                    bool aDeliveredViaMetaTag);
 
   private:
     nsCSPParser(cspTokens& aTokens,
                 nsIURI* aSelfURI,
                 nsCSPContext* aCSPContext,
                 bool aDeliveredViaMetaTag);
 
+    static bool sCSPExperimentalEnabled;
+
     ~nsCSPParser();
 
 
     // Parsing the CSP using the source-list from http://www.w3.org/TR/CSP11/#source-list
     nsCSPPolicy*        policy();
     void                directive();
     nsCSPDirective*     directiveName();
     void                directiveValue(nsTArray<nsCSPBaseSrc*>& outSrcs);
--- a/dom/security/test/TestCSPParser.cpp
+++ b/dom/security/test/TestCSPParser.cpp
@@ -23,16 +23,18 @@ class nsXPIDLString;
 template<class T> class nsReadingIterator;
 #endif
 
 #include "nsIContentSecurityPolicy.h"
 #include "nsNetUtil.h"
 #include "TestHarness.h"
 #include "nsIScriptSecurityManager.h"
 #include "mozilla/dom/nsCSPContext.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
 
 #ifndef MOZILLA_INTERNAL_API
 #undef nsString_h___
 #undef nsAString_h___
 #undef nsReadableUtils_h___
 #endif
 
 /*
@@ -161,20 +163,33 @@ nsresult runTest(uint32_t aExpectedPolic
 }
 
 // ============================= run Tests ========================
 
 nsresult runTestSuite(const PolicyTest* aPolicies,
                       uint32_t aPolicyCount,
                       uint32_t aExpectedPolicyCount) {
   nsresult rv;
+  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+  bool experimentalEnabledCache = false;
+  if (prefs)
+  {
+    prefs->GetBoolPref("security.csp.experimentalEnabled", &experimentalEnabledCache);
+    prefs->SetBoolPref("security.csp.experimentalEnabled", true);
+  }
+
   for (uint32_t i = 0; i < aPolicyCount; i++) {
     rv = runTest(aExpectedPolicyCount, aPolicies[i].policy, aPolicies[i].expectedResult);
     NS_ENSURE_SUCCESS(rv, rv);
   }
+
+  if (prefs) {
+    prefs->SetBoolPref("security.csp.experimentalEnabled", experimentalEnabledCache);
+  }
+
   return NS_OK;
 }
 
 // ============================= TestDirectives ========================
 
 nsresult TestDirectives() {
 
   static const PolicyTest policies[] =
--- a/dom/security/test/sri/mochitest.ini
+++ b/dom/security/test/sri/mochitest.ini
@@ -32,8 +32,9 @@ support-files =
   style_301.css^headers^
 
 [test_script_sameorigin.html]
 [test_script_crossdomain.html]
 [test_sri_disabled.html]
 [test_style_crossdomain.html]
 [test_style_sameorigin.html]
 [test_require-sri-for_csp_directive.html]
+[test_require-sri-for_csp_directive_disabled.html]
--- a/dom/security/test/sri/test_require-sri-for_csp_directive.html
+++ b/dom/security/test/sri/test_require-sri-for_csp_directive.html
@@ -9,36 +9,38 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a>
 <iframe style="width:200px;height:200px;" id="test_frame"></iframe>
 </body>
 <script type="application/javascript">
+  SpecialPowers.setBoolPref("security.csp.experimentalEnabled", true);
   SimpleTest.waitForExplicitFinish();
   function handler(event) {
     switch (event.data) {
       case 'good_sriLoaded':
         ok(true, "Eligible SRI resources was correctly loaded.");
         break;
       case 'bad_nonsriLoaded':
         ok(false, "Eligible non-SRI resource should be blocked by the CSP!");
         break;
       case 'good_nonsriBlocked':
         ok(true, "Eligible non-SRI resources was correctly blocked by the CSP.");
         break;
       case 'finish':
         var blackText = frame.contentDocument.getElementById('black-text');
         var blackTextColor = frame.contentWindow.getComputedStyle(blackText, null).getPropertyValue('color');
-        ok(blackTextColor == 'rgb(0, 0, 0)', "The second part should still be black.");
+        ok(blackTextColor == 'rgb(0, 0, 0)', "The second part should not be black.");
         removeEventListener('message', handler);
         SimpleTest.finish();
         break;
       default:
+        ok(false, 'Something is wrong here');
         break;
     }
   }
   addEventListener("message", handler);
   var frame = document.getElementById("test_frame");
   frame.src = "iframe_require-sri-for_main.html";
 </script>
 </html>
new file mode 100644
--- /dev/null
+++ b/dom/security/test/sri/test_require-sri-for_csp_directive_disabled.html
@@ -0,0 +1,46 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for diabled SRI require-sri-for CSP directive</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a>
+<iframe style="width:200px;height:200px;" id="test_frame"></iframe>
+</body>
+<script type="application/javascript">
+  SpecialPowers.setBoolPref("security.csp.experimentalEnabled", false);
+  SimpleTest.waitForExplicitFinish();
+  function handler(event) {
+    switch (event.data) {
+      case 'good_sriLoaded':
+        ok(true, "Eligible SRI resources was correctly loaded.");
+        break;
+      case 'bad_nonsriLoaded':
+        ok(true, "Eligible non-SRI resource should be blocked by the CSP!");
+        break;
+      case 'good_nonsriBlocked':
+        ok(false, "Eligible non-SRI resources was correctly blocked by the CSP.");
+        break;
+      case 'finish':
+        var blackText = frame.contentDocument.getElementById('black-text');
+        var blackTextColor = frame.contentWindow.getComputedStyle(blackText, null).getPropertyValue('color');
+        ok(blackTextColor != 'rgb(0, 0, 0)', "The second part should still be black.");
+        removeEventListener('message', handler);
+        SimpleTest.finish();
+        break;
+      default:
+        ok(false, 'Something is wrong here');
+        break;
+    }
+  }
+  addEventListener("message", handler);
+  var frame = document.getElementById("test_frame");
+  frame.src = "iframe_require-sri-for_main.html";
+</script>
+</html>
--- a/dom/storage/DOMStorage.cpp
+++ b/dom/storage/DOMStorage.cpp
@@ -107,23 +107,16 @@ void
 DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData,
                     ErrorResult& aRv)
 {
   if (!CanUseStorage(nullptr, this)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
-  Telemetry::Accumulate(GetType() == LocalStorage
-      ? Telemetry::LOCALDOMSTORAGE_KEY_SIZE_BYTES
-      : Telemetry::SESSIONDOMSTORAGE_KEY_SIZE_BYTES, aKey.Length());
-  Telemetry::Accumulate(GetType() == LocalStorage
-      ? Telemetry::LOCALDOMSTORAGE_VALUE_SIZE_BYTES
-      : Telemetry::SESSIONDOMSTORAGE_VALUE_SIZE_BYTES, aData.Length());
-
   nsString data;
   bool ok = data.Assign(aData, fallible);
   if (!ok) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   nsString old;
--- a/dom/storage/DOMStorageDBThread.cpp
+++ b/dom/storage/DOMStorageDBThread.cpp
@@ -484,18 +484,16 @@ DOMStorageDBThread::OpenAndUpdateDatabas
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult
 DOMStorageDBThread::InitDatabase()
 {
-  Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_INIT_DATABASE_MS> timer;
-
   nsresult rv;
 
   // Here we are on the worker thread. This opens the worker connection.
   MOZ_ASSERT(!NS_IsMainThread());
 
   rv = OpenAndUpdateDatabase();
   NS_ENSURE_SUCCESS(rv, rv);
 
rename from dom/base/URL.cpp
rename to dom/url/URL.cpp
--- a/dom/base/URL.cpp
+++ b/dom/url/URL.cpp
@@ -1,192 +1,306 @@
 /* -*- 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/. */
 
 #include "URL.h"
 
-#include "nsGlobalWindow.h"
 #include "DOMMediaStream.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/MediaSource.h"
 #include "mozilla/dom/URLBinding.h"
+#include "mozilla/dom/ipc/BlobChild.h"
+#include "mozilla/dom/ipc/nsIRemoteBlob.h"
+#include "mozilla/ipc/BackgroundChild.h"
+#include "nsContentUtils.h"
+#include "nsEscape.h"
 #include "nsHostObjectProtocolHandler.h"
-#include "nsServiceManagerUtils.h"
 #include "nsIIOService.h"
-#include "nsEscape.h"
+#include "nsIURL.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
-#include "nsIURL.h"
-#include "nsContentUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "WorkerPrivate.h"
+#include "WorkerRunnable.h"
+#include "WorkerScope.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
+///////////////////////////////////////////////////////////////////////////////
+// URL for main-thread
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+// The URL implementation for the main-thread
+class URLMainThread final : public URL
+{
+public:
+  static already_AddRefed<URLMainThread>
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+              URL& aBase, ErrorResult& aRv);
+
+  static already_AddRefed<URLMainThread>
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+              const Optional<nsAString>& aBase, ErrorResult& aRv);
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
+  static already_AddRefed<URLMainThread>
+  Constructor(nsISupports* aParent, const nsAString& aURL,
+              const nsAString& aBase, ErrorResult& aRv);
+
+  static already_AddRefed<URLMainThread>
+  Constructor(nsISupports* aParent, const nsAString& aURL, nsIURI* aBase,
+              ErrorResult& aRv);
+
+  static void
+  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
+                  const objectURLOptions& aOptions, nsAString& aResult,
+                  ErrorResult& aRv)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    CreateObjectURLInternal(aGlobal, aBlob.Impl(),
+                            NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions,
+                            aResult, aRv);
+  }
 
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
+  static void
+  CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
+                  const objectURLOptions& aOptions, nsAString& aResult,
+                  ErrorResult& aRv)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    CreateObjectURLInternal(aGlobal, &aStream,
+                            NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), aOptions,
+                            aResult, aRv);
+  }
+
+  static void
+  CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
+                  const objectURLOptions& aOptions, nsAString& aResult,
+                  ErrorResult& aRv);
+
+  static void
+  CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
+                          const nsACString& aScheme,
+                          const objectURLOptions& aOptions,
+                          nsAString& aResult, ErrorResult& aRv);
+
+  static void
+  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
+                  ErrorResult& aRv);
+
+  URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
+    : URL(aParent)
+    , mURI(aURI)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+
+  virtual void
+  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
+
+  virtual void
+  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
 
-URL::URL(nsISupports* aParent, already_AddRefed<nsIURI> aURI)
-  : mParent(aParent)
-  , mURI(aURI)
+  virtual void
+  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
+
+  virtual void
+  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
+
+  virtual void
+  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
+
+  virtual void
+  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
+
+  virtual void
+  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
+
+  virtual void
+  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
+
+  virtual void
+  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
+
+  virtual void
+  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
+
+  virtual void
+  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
+
+  virtual void
+  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
+
+  virtual void
+  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
+
+  virtual void
+  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
+
+  virtual void
+  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
+
+  virtual void
+  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
+
+  virtual void UpdateURLSearchParams() override;
+
+  virtual void
+  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
+
+  nsIURI*
+  GetURI() const
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    return mURI;
+  }
+
+private:
+  ~URLMainThread()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+
+  nsCOMPtr<nsIURI> mURI;
+};
+
+/* static */ already_AddRefed<URLMainThread>
+URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                           URL& aBase, ErrorResult& aRv)
 {
-}
-
-JSObject*
-URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return URLBinding::Wrap(aCx, this, aGivenProto);
+  MOZ_ASSERT(NS_IsMainThread());
+  URLMainThread& base = static_cast<URLMainThread&>(aBase);
+  return Constructor(aGlobal.GetAsSupports(), aURL, base.GetURI(), aRv);
 }
 
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-                 URL& aBase, ErrorResult& aRv)
-{
-  return Constructor(aGlobal.GetAsSupports(), aUrl, aBase.GetURI(), aRv);
-}
-
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-                 const Optional<nsAString>& aBase, ErrorResult& aRv)
+/* static */ already_AddRefed<URLMainThread>
+URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                           const Optional<nsAString>& aBase, ErrorResult& aRv)
 {
   if (aBase.WasPassed()) {
-    return Constructor(aGlobal.GetAsSupports(), aUrl, aBase.Value(), aRv);
+    return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
   }
 
-  return Constructor(aGlobal.GetAsSupports(), aUrl, nullptr, aRv);
+  return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
 }
 
-/* static */ already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-                 const nsAString& aBase, ErrorResult& aRv)
+/* static */ already_AddRefed<URLMainThread>
+URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
+                           const nsAString& aBase, ErrorResult& aRv)
 {
-  return Constructor(aGlobal.GetAsSupports(), aUrl, aBase, aRv);
-}
+  MOZ_ASSERT(NS_IsMainThread());
 
-/* static */ already_AddRefed<URL>
-URL::Constructor(nsISupports* aParent, const nsAString& aUrl,
-                 const nsAString& aBase, ErrorResult& aRv)
-{
   nsCOMPtr<nsIURI> baseUri;
   nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
                           nsContentUtils::GetIOService());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
     return nullptr;
   }
 
-  return Constructor(aParent, aUrl, baseUri, aRv);
+  return Constructor(aParent, aURL, baseUri, aRv);
 }
 
-/* static */
-already_AddRefed<URL>
-URL::Constructor(nsISupports* aParent, const nsAString& aUrl, nsIURI* aBase,
-                 ErrorResult& aRv)
+/* static */ already_AddRefed<URLMainThread>
+URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
+                           nsIURI* aBase, ErrorResult& aRv)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, nullptr, aBase,
+  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
                           nsContentUtils::GetIOService());
   if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aUrl);
+    aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
     return nullptr;
   }
 
-  RefPtr<URL> url = new URL(aParent, uri.forget());
+  RefPtr<URLMainThread> url = new URLMainThread(aParent, uri.forget());
   return url.forget();
 }
 
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal,
-                     Blob& aBlob,
-                     const objectURLOptions& aOptions,
-                     nsAString& aResult,
-                     ErrorResult& aError)
+/* static */ void
+URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
+                               MediaSource& aSource,
+                               const objectURLOptions& aOptions,
+                               nsAString& aResult, ErrorResult& aRv)
 {
-  CreateObjectURLInternal(aGlobal, aBlob.Impl(),
-                          NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions, aResult,
-                          aError);
-}
+  MOZ_ASSERT(NS_IsMainThread());
 
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
-                     const mozilla::dom::objectURLOptions& aOptions,
-                     nsAString& aResult,
-                     ErrorResult& aError)
-{
-  CreateObjectURLInternal(aGlobal, &aStream,
-                          NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), aOptions,
-                          aResult, aError);
-}
+  nsCOMPtr<nsIPrincipal> principal =
+    nsContentUtils::ObjectPrincipal(aGlobal.Get());
 
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
-                     const objectURLOptions& aOptions,
-                     nsAString& aResult,
-                     ErrorResult& aError)
-{
-  nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
-
-  nsCString url;
-  nsresult rv = nsHostObjectProtocolHandler::
+  nsAutoCString url;
+  aRv = nsHostObjectProtocolHandler::
     AddDataEntry(NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME),
                  &aSource, principal, url);
-  if (NS_FAILED(rv)) {
-    aError.Throw(rv);
+  if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   nsCOMPtr<nsIRunnable> revocation = NS_NewRunnableFunction(
     [url] {
       nsHostObjectProtocolHandler::RemoveDataEntry(url);
     });
 
   nsContentUtils::RunInStableState(revocation.forget());
 
   CopyASCIItoUTF16(url, aResult);
 }
 
-void
-URL::CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
-                             const nsACString& aScheme,
-                             const objectURLOptions& aOptions,
-                             nsAString& aResult, ErrorResult& aRv)
+/* static */ void
+URLMainThread::CreateObjectURLInternal(const GlobalObject& aGlobal,
+                                       nsISupports* aObject,
+                                       const nsACString& aScheme,
+                                       const objectURLOptions& aOptions,
+                                       nsAString& aResult, ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
   if (!global) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
-  nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
+  nsCOMPtr<nsIPrincipal> principal =
+    nsContentUtils::ObjectPrincipal(aGlobal.Get());
 
   nsAutoCString url;
   nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
                                                           principal, url);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return;
   }
 
   global->RegisterHostObjectURI(url);
   CopyASCIItoUTF16(url, aResult);
 }
 
-void
-URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
-                     ErrorResult& aRv)
+/* static */ void
+URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
+                               const nsAString& aURL, ErrorResult& aRv)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
   if (!global) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
 
@@ -198,29 +312,29 @@ URL::RevokeObjectURL(const GlobalObject&
   if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
     nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
     global->UnregisterHostObjectURI(asciiurl);
     nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
   }
 }
 
 void
-URL::GetHref(nsAString& aHref) const
+URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const
 {
   aHref.Truncate();
 
   nsAutoCString href;
   nsresult rv = mURI->GetSpec(href);
   if (NS_SUCCEEDED(rv)) {
     CopyUTF8toUTF16(href, aHref);
   }
 }
 
 void
-URL::SetHref(const nsAString& aHref, ErrorResult& aRv)
+URLMainThread::SetHref(const nsAString& aHref, ErrorResult& aRv)
 {
   NS_ConvertUTF16toUTF8 href(aHref);
 
   nsresult rv;
   nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return;
@@ -233,35 +347,35 @@ URL::SetHref(const nsAString& aHref, Err
     return;
   }
 
   mURI = uri;
   UpdateURLSearchParams();
 }
 
 void
-URL::GetOrigin(nsAString& aOrigin) const
+URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
 {
   nsContentUtils::GetUTFOrigin(mURI, aOrigin);
 }
 
 void
-URL::GetProtocol(nsAString& aProtocol) const
+URLMainThread::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
 {
   nsAutoCString protocol;
   if (NS_SUCCEEDED(mURI->GetScheme(protocol))) {
     aProtocol.Truncate();
   }
 
   CopyASCIItoUTF16(protocol, aProtocol);
   aProtocol.Append(char16_t(':'));
 }
 
 void
-URL::SetProtocol(const nsAString& aProtocol)
+URLMainThread::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
 {
   nsAString::const_iterator start, end;
   aProtocol.BeginReading(start);
   aProtocol.EndReading(end);
   nsAString::const_iterator iter(start);
 
   FindCharInReadable(':', iter, end);
 
@@ -298,112 +412,101 @@ URL::SetProtocol(const nsAString& aProto
   value.Truncate();               \
   nsAutoCString tmp;              \
   nsresult rv = mURI->func(tmp);  \
   if (NS_SUCCEEDED(rv)) {         \
     CopyUTF8toUTF16(tmp, value);  \
   }
 
 void
-URL::GetUsername(nsAString& aUsername) const
+URLMainThread::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
 {
   URL_GETTER(aUsername, GetUsername);
 }
 
 void
-URL::SetUsername(const nsAString& aUsername)
+URLMainThread::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
 {
   mURI->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
 }
 
 void
-URL::GetPassword(nsAString& aPassword) const
+URLMainThread::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
 {
   URL_GETTER(aPassword, GetPassword);
 }
 
 void
-URL::SetPassword(const nsAString& aPassword)
+URLMainThread::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
 {
   mURI->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
 }
 
 void
-URL::GetHost(nsAString& aHost) const
+URLMainThread::GetHost(nsAString& aHost, ErrorResult& aRv) const
 {
   URL_GETTER(aHost, GetHostPort);
 }
 
 void
-URL::SetHost(const nsAString& aHost)
+URLMainThread::SetHost(const nsAString& aHost, ErrorResult& aRv)
 {
   mURI->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
 }
 
 void
-URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-  SetSearchInternal(search);
-}
-
-void
-URL::UpdateURLSearchParams()
+URLMainThread::UpdateURLSearchParams()
 {
   if (!mSearchParams) {
     return;
   }
 
   nsAutoCString search;
   nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
   if (url) {
     nsresult rv = url->GetQuery(search);
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to get the query from a nsIURL.");
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      search.Truncate();
     }
   }
 
   mSearchParams->ParseInput(search);
 }
 
 void
-URL::GetHostname(nsAString& aHostname) const
+URLMainThread::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
 {
   aHostname.Truncate();
   nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
 }
 
 void
-URL::SetHostname(const nsAString& aHostname)
+URLMainThread::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
 {
   // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname
   // The return code is silently ignored
   mURI->SetHost(NS_ConvertUTF16toUTF8(aHostname));
 }
 
 void
-URL::GetPort(nsAString& aPort) const
+URLMainThread::GetPort(nsAString& aPort, ErrorResult& aRv) const
 {
   aPort.Truncate();
 
   int32_t port;
   nsresult rv = mURI->GetPort(&port);
   if (NS_SUCCEEDED(rv) && port != -1) {
     nsAutoString portStr;
     portStr.AppendInt(port, 10);
     aPort.Assign(portStr);
   }
 }
 
 void
-URL::SetPort(const nsAString& aPort)
+URLMainThread::SetPort(const nsAString& aPort, ErrorResult& aRv)
 {
   nsresult rv;
   nsAutoString portStr(aPort);
   int32_t port = -1;
 
   // nsIURI uses -1 as default value.
   if (!portStr.IsEmpty()) {
     port = portStr.ToInteger(&rv);
@@ -411,17 +514,17 @@ URL::SetPort(const nsAString& aPort)
       return;
     }
   }
 
   mURI->SetPort(port);
 }
 
 void
-URL::GetPathname(nsAString& aPathname) const
+URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
 {
   aPathname.Truncate();
 
   nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
   if (!url) {
     nsAutoCString path;
     nsresult rv = mURI->GetPath(path);
     if (NS_FAILED(rv)){
@@ -437,29 +540,29 @@ URL::GetPathname(nsAString& aPathname) c
   nsAutoCString file;
   nsresult rv = url->GetFilePath(file);
   if (NS_SUCCEEDED(rv)) {
     CopyUTF8toUTF16(file, aPathname);
   }
 }
 
 void
-URL::SetPathname(const nsAString& aPathname)
+URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
 {
   nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
   if (!url) {
     // Ignore failures to be compatible with NS4.
     return;
   }
 
   url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
 }
 
 void
-URL::GetSearch(nsAString& aSearch) const
+URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
 {
   aSearch.Truncate();
 
   nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
   if (!url) {
     // Do not throw!  Not having a valid URI or URL should result in an empty
     // string.
     return;
@@ -468,63 +571,1160 @@ URL::GetSearch(nsAString& aSearch) const
   nsAutoCString search;
   nsresult rv = url->GetQuery(search);
   if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
     CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
   }
 }
 
 void
-URL::SetSearch(const nsAString& aSearch)
-{
-  SetSearchInternal(aSearch);
-  UpdateURLSearchParams();
-}
-
-void
-URL::SetSearchInternal(const nsAString& aSearch)
-{
-  nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
-  if (!url) {
-    // Ignore failures to be compatible with NS4.
-    return;
-  }
-
-  url->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
-}
-
-URLSearchParams*
-URL::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-void
-URL::GetHash(nsAString& aHash) const
+URLMainThread::GetHash(nsAString& aHash, ErrorResult& aRv) const
 {
   aHash.Truncate();
 
   nsAutoCString ref;
   nsresult rv = mURI->GetRef(ref);
   if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
     aHash.Assign(char16_t('#'));
     if (nsContentUtils::GettersDecodeURLHash()) {
       NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes!
     }
     AppendUTF8toUTF16(ref, aHash);
   }
 }
 
 void
-URL::SetHash(const nsAString& aHash)
+URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
 {
   mURI->SetRef(NS_ConvertUTF16toUTF8(aHash));
 }
 
+void
+URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
+{
+  nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
+  if (!url) {
+    // Ignore failures to be compatible with NS4.
+    return;
+  }
+
+  url->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
+}
+
+} // anonymous namespace
+
+///////////////////////////////////////////////////////////////////////////////
+// URL for Workers
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+using namespace workers;
+
+// Proxy class to forward all the requests to a URLMainThread object.
+class URLProxy final
+{
+public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
+
+  explicit URLProxy(already_AddRefed<URLMainThread> aURL)
+    : mURL(aURL)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+
+  URLMainThread* URL()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    return mURL;
+  }
+
+  nsIURI* URI()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    return mURL->GetURI();
+  }
+
+  void ReleaseURI()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    mURL = nullptr;
+  }
+
+private:
+  // Private destructor, to discourage deletion outside of Release():
+  ~URLProxy()
+  {
+     MOZ_ASSERT(!mURL);
+  }
+
+  RefPtr<URLMainThread> mURL;
+};
+
+// URLWorker implements the URL object in workers.
+class URLWorker final : public URL
+{
+public:
+  static already_AddRefed<URLWorker>
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+              URL& aBase, ErrorResult& aRv);
+
+  static already_AddRefed<URLWorker>
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+              const Optional<nsAString>& aBase, ErrorResult& aRv);
+
+  static already_AddRefed<URLWorker>
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+              const nsAString& aBase, ErrorResult& aRv);
+
+  static void
+  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
+                  const mozilla::dom::objectURLOptions& aOptions,
+                  nsAString& aResult, mozilla::ErrorResult& aRv);
+
+  static void
+  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
+                  ErrorResult& aRv);
+
+  URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
+
+  virtual void
+  GetHref(nsAString& aHref, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHref(const nsAString& aHref, ErrorResult& aRv) override;
+
+  virtual void
+  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
+
+  virtual void
+  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override;
+
+  virtual void
+  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override;
+
+  virtual void
+  GetUsername(nsAString& aUsername, ErrorResult& aRv) const override;
+
+  virtual void
+  SetUsername(const nsAString& aUsername, ErrorResult& aRv) override;
+
+  virtual void
+  GetPassword(nsAString& aPassword, ErrorResult& aRv) const override;
+
+  virtual void
+  SetPassword(const nsAString& aPassword, ErrorResult& aRv) override;
+
+  virtual void
+  GetHost(nsAString& aHost, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHost(const nsAString& aHost, ErrorResult& aRv) override;
+
+  virtual void
+  GetHostname(nsAString& aHostname, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHostname(const nsAString& aHostname, ErrorResult& aRv) override;
+
+  virtual void
+  GetPort(nsAString& aPort, ErrorResult& aRv) const override;
+
+  virtual void
+  SetPort(const nsAString& aPort, ErrorResult& aRv) override;
+
+  virtual void
+  GetPathname(nsAString& aPathname, ErrorResult& aRv) const override;
+
+  virtual void
+  SetPathname(const nsAString& aPathname, ErrorResult& aRv) override;
+
+  virtual void
+  GetSearch(nsAString& aSearch, ErrorResult& aRv) const override;
+
+  virtual void
+  GetHash(nsAString& aHost, ErrorResult& aRv) const override;
+
+  virtual void
+  SetHash(const nsAString& aHash, ErrorResult& aRv) override;
+
+  virtual void UpdateURLSearchParams() override;
+
+  virtual void
+  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override;
+
+  URLProxy*
+  GetURLProxy() const
+  {
+    mWorkerPrivate->AssertIsOnWorkerThread();
+    return mURLProxy;
+  }
+
+private:
+  ~URLWorker();
+
+  workers::WorkerPrivate* mWorkerPrivate;
+  RefPtr<URLProxy> mURLProxy;
+};
+
+// This class creates an URL from a DOM Blob on the main thread.
+class CreateURLRunnable : public WorkerMainThreadRunnable
+{
+private:
+  BlobImpl* mBlobImpl;
+  nsAString& mURL;
+
+public:
+  CreateURLRunnable(WorkerPrivate* aWorkerPrivate, BlobImpl* aBlobImpl,
+                    const objectURLOptions& aOptions,
+                    nsAString& aURL)
+  : WorkerMainThreadRunnable(aWorkerPrivate,
+                             NS_LITERAL_CSTRING("URL :: CreateURL"))
+  , mBlobImpl(aBlobImpl)
+  , mURL(aURL)
+  {
+    MOZ_ASSERT(aBlobImpl);
+
+    DebugOnly<bool> isMutable;
+    MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
+    MOZ_ASSERT(!isMutable);
+  }
+
+  bool
+  MainThreadRun()
+  {
+    using namespace mozilla::ipc;
+
+    AssertIsOnMainThread();
+
+    RefPtr<BlobImpl> newBlobImplHolder;
+
+    if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(mBlobImpl)) {
+      if (BlobChild* blobChild = remoteBlob->GetBlobChild()) {
+        if (PBackgroundChild* blobManager = blobChild->GetBackgroundManager()) {
+          PBackgroundChild* backgroundManager =
+            BackgroundChild::GetForCurrentThread();
+          MOZ_ASSERT(backgroundManager);
+
+          if (blobManager != backgroundManager) {
+            // Always make sure we have a blob from an actor we can use on this
+            // thread.
+            blobChild = BlobChild::GetOrCreate(backgroundManager, mBlobImpl);
+            MOZ_ASSERT(blobChild);
+
+            newBlobImplHolder = blobChild->GetBlobImpl();
+            MOZ_ASSERT(newBlobImplHolder);
+
+            mBlobImpl = newBlobImplHolder;
+          }
+        }
+      }
+    }
+
+    DebugOnly<bool> isMutable;
+    MOZ_ASSERT(NS_SUCCEEDED(mBlobImpl->GetMutable(&isMutable)));
+    MOZ_ASSERT(!isMutable);
+
+    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
+
+    nsAutoCString url;
+    nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
+        NS_LITERAL_CSTRING(BLOBURI_SCHEME),
+        mBlobImpl, principal, url);
+
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to add data entry for the blob!");
+      SetDOMStringToNull(mURL);
+      return false;
+    }
+
+    if (!mWorkerPrivate->IsSharedWorker() &&
+        !mWorkerPrivate->IsServiceWorker()) {
+      // Walk up to top worker object.
+      WorkerPrivate* wp = mWorkerPrivate;
+      while (WorkerPrivate* parent = wp->GetParent()) {
+        wp = parent;
+      }
+
+      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
+      // We could not have a ScriptContext in JSM code. In this case, we leak.
+      if (sc) {
+        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
+        MOZ_ASSERT(global);
+
+        global->RegisterHostObjectURI(url);
+      }
+    }
+
+    mURL = NS_ConvertUTF8toUTF16(url);
+    return true;
+  }
+};
+
+// This class revokes an URL on the main thread.
+class RevokeURLRunnable : public WorkerMainThreadRunnable
+{
+private:
+  const nsString mURL;
+
+public:
+  RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
+                    const nsAString& aURL)
+  : WorkerMainThreadRunnable(aWorkerPrivate,
+                             NS_LITERAL_CSTRING("URL :: RevokeURL"))
+  , mURL(aURL)
+  {}
+
+  bool
+  MainThreadRun()
+  {
+    AssertIsOnMainThread();
+
+    NS_ConvertUTF16toUTF8 url(mURL);
+
+    nsIPrincipal* urlPrincipal =
+      nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
+
+    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
+
+    bool subsumes;
+    if (urlPrincipal &&
+        NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
+        subsumes) {
+      nsHostObjectProtocolHandler::RemoveDataEntry(url);
+    }
+
+    if (!mWorkerPrivate->IsSharedWorker() &&
+        !mWorkerPrivate->IsServiceWorker()) {
+      // Walk up to top worker object.
+      WorkerPrivate* wp = mWorkerPrivate;
+      while (WorkerPrivate* parent = wp->GetParent()) {
+        wp = parent;
+      }
+
+      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
+      // We could not have a ScriptContext in JSM code. In this case, we leak.
+      if (sc) {
+        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
+        MOZ_ASSERT(global);
+
+        global->UnregisterHostObjectURI(url);
+      }
+    }
+
+    return true;
+  }
+};
+
+// This class creates a URL object on the main thread.
+class ConstructorRunnable : public WorkerMainThreadRunnable
+{
+private:
+  const nsString mURL;
+
+  nsString mBase; // IsVoid() if we have no base URI string.
+  RefPtr<URLProxy> mBaseProxy;
+  ErrorResult& mRv;
+
+  RefPtr<URLProxy> mRetval;
+
+public:
+  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
+                      const nsAString& aURL, const Optional<nsAString>& aBase,
+                      ErrorResult& aRv)
+  : WorkerMainThreadRunnable(aWorkerPrivate,
+                             NS_LITERAL_CSTRING("URL :: Constructor"))
+  , mURL(aURL)
+  , mRv(aRv)
+  {
+    if (aBase.WasPassed()) {
+      mBase = aBase.Value();
+    } else {
+      mBase.SetIsVoid(true);
+    }
+    mWorkerPrivate->AssertIsOnWorkerThread();
+  }
+
+  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
+                      const nsAString& aURL, URLProxy* aBaseProxy,
+                      ErrorResult& aRv)
+  : WorkerMainThreadRunnable(aWorkerPrivate,
+                             NS_LITERAL_CSTRING("URL :: Constructor with BaseURL"))
+  , mURL(aURL)
+  , mBaseProxy(aBaseProxy)
+  , mRv(aRv)
+  {
+    mBase.SetIsVoid(true);
+    mWorkerPrivate->AssertIsOnWorkerThread();
+  }
+
+  bool
+  MainThreadRun()
+  {
+    AssertIsOnMainThread();
+
+    RefPtr<URLMainThread> url;
+    if (mBaseProxy) {
+      url = URLMainThread::Constructor(nullptr, mURL, mBaseProxy->URI(), mRv);
+    } else if (!mBase.IsVoid()) {
+      url = URLMainThread::Constructor(nullptr, mURL, mBase, mRv);
+    } else {
+      url = URLMainThread::Constructor(nullptr, mURL, nullptr, mRv);
+    }
+
+    if (mRv.Failed()) {
+      return true;
+    }
+
+    mRetval = new URLProxy(url.forget());
+    return true;
+  }
+
+  URLProxy*
+  GetURLProxy()
+  {
+    return mRetval;
+  }
+};
+
+class TeardownURLRunnable : public Runnable
+{
+public:
+  explicit TeardownURLRunnable(URLProxy* aURLProxy)
+    : mURLProxy(aURLProxy)
+  {
+  }
+
+  NS_IMETHOD Run()
+  {
+    AssertIsOnMainThread();
+
+    mURLProxy->ReleaseURI();
+    mURLProxy = nullptr;
+
+    return NS_OK;
+  }
+
+private:
+  RefPtr<URLProxy> mURLProxy;
+};
+
+// This class is the generic getter for any URL property.
+class GetterRunnable : public WorkerMainThreadRunnable
+{
+public:
+  enum GetterType {
+    GetterHref,
+    GetterOrigin,
+    GetterProtocol,
+    GetterUsername,
+    GetterPassword,
+    GetterHost,
+    GetterHostname,
+    GetterPort,
+    GetterPathname,
+    GetterSearch,
+    GetterHash,
+  };
+
+  GetterRunnable(WorkerPrivate* aWorkerPrivate,
+                 GetterType aType, nsAString& aValue,
+                 URLProxy* aURLProxy)
+  : WorkerMainThreadRunnable(aWorkerPrivate,
+                             // We can have telemetry keys for each getter when
+                             // needed.
+                             NS_LITERAL_CSTRING("URL :: getter"))
+  , mValue(aValue)
+  , mType(aType)
+  , mURLProxy(aURLProxy)
+  {
+    mWorkerPrivate->AssertIsOnWorkerThread();
+  }
+
+  bool
+  MainThreadRun()
+  {
+    AssertIsOnMainThread();
+    ErrorResult rv;
+
+    switch (mType) {
+      case GetterHref:
+        mURLProxy->URL()->GetHref(mValue, rv);
+        break;
+
+      case GetterOrigin:
+        mURLProxy->URL()->GetOrigin(mValue, rv);
+        break;
+
+      case GetterProtocol:
+        mURLProxy->URL()->GetProtocol(mValue, rv);
+        break;
+
+      case GetterUsername:
+        mURLProxy->URL()->GetUsername(mValue, rv);
+        break;
+
+      case GetterPassword:
+        mURLProxy->URL()->GetPassword(mValue, rv);
+        break;
+
+      case GetterHost:
+        mURLProxy->URL()->GetHost(mValue, rv);
+        break;
+
+      case GetterHostname:
+        mURLProxy->URL()->GetHostname(mValue, rv);
+        break;
+
+      case GetterPort:
+        mURLProxy->URL()->GetPort(mValue, rv);
+        break;
+
+      case GetterPathname:
+        mURLProxy->URL()->GetPathname(mValue, rv);
+        break;
+
+      case GetterSearch:
+        mURLProxy->URL()->GetSearch(mValue, rv);
+        break;
+
+      case GetterHash:
+        mURLProxy->URL()->GetHash(mValue, rv);
+        break;
+    }
+
+    MOZ_ASSERT(!rv.Failed(), "Main-thread getters do not fail.");
+    return true;
+  }
+
+private:
+  nsAString& mValue;
+  GetterType mType;
+  RefPtr<URLProxy> mURLProxy;
+};
+
+// This class is the generic setter for any URL property.
+class SetterRunnable : public WorkerMainThreadRunnable
+{
+public:
+  enum SetterType {
+    SetterHref,
+    SetterProtocol,
+    SetterUsername,
+    SetterPassword,
+    SetterHost,
+    SetterHostname,
+    SetterPort,
+    SetterPathname,
+    SetterSearch,
+    SetterHash,
+  };
+
+  SetterRunnable(WorkerPrivate* aWorkerPrivate,
+                 SetterType aType, const nsAString& aValue,
+                 URLProxy* aURLProxy)
+  : WorkerMainThreadRunnable(aWorkerPrivate,
+                             // We can have telemetry keys for each setter when
+                             // needed.
+                             NS_LITERAL_CSTRING("URL :: setter"))
+  , mValue(aValue)
+  , mType(aType)
+  , mURLProxy(aURLProxy)
+  , mFailed(false)
+  {
+    mWorkerPrivate->AssertIsOnWorkerThread();
+  }
+
+  bool
+  MainThreadRun()
+  {
+    AssertIsOnMainThread();
+    ErrorResult rv;
+
+    switch (mType) {
+      case SetterHref: {
+        mURLProxy->URL()->SetHref(mValue, rv);
+        break;
+      }
+
+      case SetterProtocol:
+        mURLProxy->URL()->SetProtocol(mValue, rv);
+        break;
+
+      case SetterUsername:
+        mURLProxy->URL()->SetUsername(mValue, rv);
+        break;
+
+      case SetterPassword:
+        mURLProxy->URL()->SetPassword(mValue, rv);
+        break;
+
+      case SetterHost:
+        mURLProxy->URL()->SetHost(mValue, rv);
+        break;
+
+      case SetterHostname:
+        mURLProxy->URL()->SetHostname(mValue, rv);
+        break;
+
+      case SetterPort:
+        mURLProxy->URL()->SetPort(mValue, rv);
+        break;
+
+      case SetterPathname:
+        mURLProxy->URL()->SetPathname(mValue, rv);
+        break;
+
+      case SetterSearch:
+        mURLProxy->URL()->SetSearch(mValue, rv);
+        break;
+
+      case SetterHash:
+        mURLProxy->URL()->SetHash(mValue, rv);
+        break;
+    }
+
+    if (NS_WARN_IF(rv.Failed())) {
+      rv.SuppressException();
+      mFailed = true;
+    }
+
+    return true;
+  }
+
+  bool Failed() const
+  {
+    return mFailed;
+  }
+
+private:
+  const nsString mValue;
+  SetterType mType;
+  RefPtr<URLProxy> mURLProxy;
+  bool mFailed;
+};
+
+already_AddRefed<URLWorker>
+FinishConstructor(JSContext* aCx, WorkerPrivate* aPrivate,
+                  ConstructorRunnable* aRunnable, ErrorResult& aRv)
+{
+  aRunnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  RefPtr<URLProxy> proxy = aRunnable->GetURLProxy();
+  if (NS_WARN_IF(!proxy)) {
+    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return nullptr;
+  }
+
+  RefPtr<URLWorker> url = new URLWorker(aPrivate, proxy);
+  return url.forget();
+}
+
+/* static */ already_AddRefed<URLWorker>
+URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                       URL& aBase, ErrorResult& aRv)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  JSContext* cx = aGlobal.Context();
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
+
+  URLWorker& base = static_cast<URLWorker&>(aBase);
+  RefPtr<ConstructorRunnable> runnable =
+    new ConstructorRunnable(workerPrivate, aURL, base.GetURLProxy(), aRv);
+
+  return FinishConstructor(cx, workerPrivate, runnable, aRv);
+}
+
+/* static */ already_AddRefed<URLWorker>
+URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                       const Optional<nsAString>& aBase, ErrorResult& aRv)
+{
+  JSContext* cx = aGlobal.Context();
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
+
+  RefPtr<ConstructorRunnable> runnable =
+    new ConstructorRunnable(workerPrivate, aURL, aBase, aRv);
+
+  return FinishConstructor(cx, workerPrivate, runnable, aRv);
+}
+
+/* static */ already_AddRefed<URLWorker>
+URLWorker::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                       const nsAString& aBase, ErrorResult& aRv)
+{
+  JSContext* cx = aGlobal.Context();
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
+
+  Optional<nsAString> base;
+  base = &aBase;
+
+  RefPtr<ConstructorRunnable> runnable =
+    new ConstructorRunnable(workerPrivate, aURL, base, aRv);
+
+  return FinishConstructor(cx, workerPrivate, runnable, aRv);
+}
+
+/* static */ void
+URLWorker::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
+                           const mozilla::dom::objectURLOptions& aOptions,
+                           nsAString& aResult, mozilla::ErrorResult& aRv)
+{
+  JSContext* cx = aGlobal.Context();
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
+
+  RefPtr<BlobImpl> blobImpl = aBlob.Impl();
+  MOZ_ASSERT(blobImpl);
+
+  aRv = blobImpl->SetMutable(false);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  RefPtr<CreateURLRunnable> runnable =
+    new CreateURLRunnable(workerPrivate, blobImpl, aOptions, aResult);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
+    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
+    MOZ_ASSERT(scope);
+
+    scope->RegisterHostObjectURI(NS_ConvertUTF16toUTF8(aResult));
+  }
+}
+
+/* static */ void
+URLWorker::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
+                           ErrorResult& aRv)
+{
+  JSContext* cx = aGlobal.Context();
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
+
+  RefPtr<RevokeURLRunnable> runnable =
+    new RevokeURLRunnable(workerPrivate, aUrl);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
+    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
+    MOZ_ASSERT(scope);
+
+    scope->UnregisterHostObjectURI(NS_ConvertUTF16toUTF8(aUrl));
+  }
+}
+
+URLWorker::URLWorker(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
+  : URL(nullptr)
+  , mWorkerPrivate(aWorkerPrivate)
+  , mURLProxy(aURLProxy)
+{}
+
+URLWorker::~URLWorker()
+{
+  if (mURLProxy) {
+    mWorkerPrivate->AssertIsOnWorkerThread();
+
+    RefPtr<TeardownURLRunnable> runnable =
+      new TeardownURLRunnable(mURLProxy);
+    mURLProxy = nullptr;
+
+    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
+      NS_ERROR("Failed to dispatch teardown runnable!");
+    }
+  }
+}
+
+void
+URLWorker::GetHref(nsAString& aHref, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetHref(const nsAString& aHref, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  if (runnable->Failed()) {
+    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
+    return;
+  }
+
+  UpdateURLSearchParams();
+}
+
+void
+URLWorker::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
+                       aProtocol, mURLProxy);
+
+  runnable->Dispatch(aRv);
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
+                       aUsername, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
+                       aPassword, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::GetHost(nsAString& aHost, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetHost(const nsAString& aHost, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
+                       aHost, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
+                       aHostname, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::GetPort(nsAString& aPort, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetPort(const nsAString& aPort, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
+                       aPort, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname,
+                       aPathname, mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
+                       aPathname, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::GetHash(nsAString& aHash, ErrorResult& aRv) const
+{
+  RefPtr<GetterRunnable> runnable =
+    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
+                       mURLProxy);
+
+  runnable->Dispatch(aRv);
+}
+
+void
+URLWorker::SetHash(const nsAString& aHash, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
+                       aHash, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
+{
+  RefPtr<SetterRunnable> runnable =
+    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
+                       aSearch, mURLProxy);
+
+  runnable->Dispatch(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  MOZ_ASSERT(!runnable->Failed());
+}
+
+void
+URLWorker::UpdateURLSearchParams()
+{
+  if (mSearchParams) {
+    nsAutoString search;
+
+    ErrorResult rv;
+    GetSearch(search, rv);
+    if (NS_WARN_IF(rv.Failed())) {
+      rv.SuppressException();
+    }
+
+    mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)));
+  }
+}
+
+} // anonymous namespace
+
+///////////////////////////////////////////////////////////////////////////////
+// Base class for URL
+///////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+JSObject*
+URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return URLBinding::Wrap(aCx, this, aGivenProto);
+}
+
+/* static */ already_AddRefed<URL>
+URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                 URL& aBase, ErrorResult& aRv)
+{
+  if (NS_IsMainThread()) {
+    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
+  }
+
+  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
+}
+
+/* static */ already_AddRefed<URL>
+URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                 const Optional<nsAString>& aBase, ErrorResult& aRv)
+{
+  if (NS_IsMainThread()) {
+    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
+  }
+
+  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
+}
+
+/* static */ already_AddRefed<URL>
+URL::WorkerConstructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                       const nsAString& aBase, ErrorResult& aRv)
+{
+  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
+}
+
+void
+URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
+                     const objectURLOptions& aOptions, nsAString& aResult,
+                     ErrorResult& aRv)
+{
+  if (NS_IsMainThread()) {
+    URLMainThread::CreateObjectURL(aGlobal, aBlob, aOptions, aResult, aRv);
+  } else {
+    URLWorker::CreateObjectURL(aGlobal, aBlob, aOptions, aResult, aRv);
+  }
+}
+
+void
+URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
+                     const objectURLOptions& aOptions, nsAString& aResult,
+                     ErrorResult& aRv)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  URLMainThread::CreateObjectURL(aGlobal, aStream, aOptions, aResult, aRv);
+}
+
+void
+URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
+                     const objectURLOptions& aOptions,
+                     nsAString& aResult,
+                     ErrorResult& aRv)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  URLMainThread::CreateObjectURL(aGlobal, aSource, aOptions, aResult, aRv);
+}
+
+void
+URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
+                     ErrorResult& aRv)
+{
+  if (NS_IsMainThread()) {
+    URLMainThread::RevokeObjectURL(aGlobal, aURL, aRv);
+  } else {
+    URLWorker::RevokeObjectURL(aGlobal, aURL, aRv);
+  }
+}
+
+URLSearchParams*
+URL::SearchParams()
+{
+  CreateSearchParamsIfNeeded();
+  return mSearchParams;
+}
+
 bool IsChromeURI(nsIURI* aURI)
 {
   bool isChrome = false;
   if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)))
       return isChrome;
   return false;
 }
 
@@ -532,10 +1732,32 @@ void
 URL::CreateSearchParamsIfNeeded()
 {
   if (!mSearchParams) {
     mSearchParams = new URLSearchParams(mParent, this);
     UpdateURLSearchParams();
   }
 }
 
+void
+URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv)
+{
+  SetSearchInternal(aSearch, aRv);
+  UpdateURLSearchParams();
+}
+
+void
+URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
+{
+  MOZ_ASSERT(mSearchParams);
+  MOZ_ASSERT(mSearchParams == aSearchParams);
+
+  nsAutoString search;
+  mSearchParams->Serialize(search);
+
+  ErrorResult rv;
+  SetSearchInternal(search, rv);
+  NS_WARN_IF(rv.Failed());
+  rv.SuppressException();
+}
+
 } // namespace dom
 } // namespace mozilla
rename from dom/base/URL.h
rename to dom/url/URL.h
--- a/dom/base/URL.h
+++ b/dom/url/URL.h
@@ -1,15 +1,16 @@
 /* -*- 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 URL_h___
-#define URL_h___
+
+#ifndef mozilla_dom_URL_h
+#define mozilla_dom_URL_h
 
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/URLSearchParams.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsString.h"
 #include "nsWrapperCache.h"
 
 class nsISupports;
@@ -22,152 +23,157 @@ class DOMMediaStream;
 
 namespace dom {
 
 class Blob;
 class MediaSource;
 class GlobalObject;
 struct objectURLOptions;
 
-namespace workers {
-class URLProxy;
-} // namespace workers
-
-class URL final : public URLSearchParamsObserver
-                , public nsWrapperCache
+class URL : public URLSearchParamsObserver
+          , public nsWrapperCache
 {
-  ~URL() {}
-
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(URL)
 
-  URL(nsISupports* aParent, already_AddRefed<nsIURI> aURI);
+  URL(nsISupports* aParent)
+    : mParent(aParent)
+  {}
 
   // WebIDL methods
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   static already_AddRefed<URL>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
               URL& aBase, ErrorResult& aRv);
+
   static already_AddRefed<URL>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
               const Optional<nsAString>& aBase, ErrorResult& aRv);
-  // Versions of Constructor that we can share with workers and other code.
+
+  // Helper for Fetch API
   static already_AddRefed<URL>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-              const nsAString& aBase, ErrorResult& aRv);
-  static already_AddRefed<URL>
-  Constructor(nsISupports* aParent, const nsAString& aUrl,
-              const nsAString& aBase, ErrorResult& aRv);
-  static already_AddRefed<URL>
-  Constructor(nsISupports* aParent, const nsAString& aUrl,
-              nsIURI* aBase, ErrorResult& aRv);
+  WorkerConstructor(const GlobalObject& aGlobal, const nsAString& aURL,
+                    const nsAString& aBase, ErrorResult& aRv);
+
+
+  static void
+  CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
+                  const objectURLOptions& aOptions,
+                  nsAString& aResult, ErrorResult& aRv);
 
-  static void CreateObjectURL(const GlobalObject& aGlobal,
-                              Blob& aBlob,
-                              const objectURLOptions& aOptions,
-                              nsAString& aResult,
-                              ErrorResult& aError);
-  static void CreateObjectURL(const GlobalObject& aGlobal,
-                              DOMMediaStream& aStream,
-                              const objectURLOptions& aOptions,
-                              nsAString& aResult,
-                              ErrorResult& aError);
-  static void CreateObjectURL(const GlobalObject& aGlobal,
-                              MediaSource& aSource,
-                              const objectURLOptions& aOptions,
-                              nsAString& aResult,
-                              ErrorResult& aError);
-  static void RevokeObjectURL(const GlobalObject& aGlobal,
-                              const nsAString& aURL,
-                              ErrorResult& aRv);
+  static void
+  CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
+                  const objectURLOptions& aOptions, nsAString& aResult,
+                  ErrorResult& aRv);
+
+  static void
+  CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
+                  const objectURLOptions& aOptions, nsAString& aResult,
+                  ErrorResult& aRv);
+
+  static void
+  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
+                  ErrorResult& aRv);
+
+  virtual void
+  GetHref(nsAString& aHref, ErrorResult& aRv) const = 0;
+
+  virtual void
+  SetHref(const nsAString& aHref, ErrorResult& aRv) = 0;
+
+  virtual void
+  GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const = 0;
+
+  virtual void
+  GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const = 0;
 
-  void GetHref(nsAString& aHref) const;
-
-  void SetHref(const nsAString& aHref, ErrorResult& aRv);
+  virtual void
+  SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) = 0;
 
-  void GetOrigin(nsAString& aOrigin) const;
+  virtual void
+  GetUsername(nsAString& aUsername, ErrorResult& aRv) const = 0;
 
-  void GetProtocol(nsAString& aProtocol) const;
+  virtual void
+  SetUsername(const nsAString& aUsername, ErrorResult& aRv) = 0;
 
-  void SetProtocol(const nsAString& aProtocol);
+  virtual void
+  GetPassword(nsAString& aPassword, ErrorResult& aRv) const = 0;
 
-  void GetUsername(nsAString& aUsername) const;
+  virtual void
+  SetPassword(const nsAString& aPassword, ErrorResult& aRv) = 0;
 
-  void SetUsername(const nsAString& aUsername);
+  virtual void
+  GetHost(nsAString& aHost, ErrorResult& aRv) const = 0;
 
-  void GetPassword(nsAString& aPassword) const;
-
-  void SetPassword(const nsAString& aPassword);
+  virtual void
+  SetHost(const nsAString& aHost, ErrorResult& aRv) = 0;
 
-  void GetHost(nsAString& aHost) const;
+  virtual void
+  GetHostname(nsAString& aHostname, ErrorResult& aRv) const = 0;
 
-  void SetHost(const nsAString& aHost);
+  virtual void
+  SetHostname(const nsAString& aHostname, ErrorResult& aRv) = 0;
 
-  void GetHostname(nsAString& aHostname) const;
+  virtual void
+  GetPort(nsAString& aPort, ErrorResult& aRv) const = 0;
 
-  void SetHostname(const nsAString& aHostname);
-
-  void GetPort(nsAString& aPort) const;
+  virtual void
+  SetPort(const nsAString& aPort, ErrorResult& aRv) = 0;
 
-  void SetPort(const nsAString& aPort);
+  virtual void
+  GetPathname(nsAString& aPathname, ErrorResult& aRv) const = 0;
 
-  void GetPathname(nsAString& aPathname) const;
+  virtual void
+  SetPathname(const nsAString& aPathname, ErrorResult& aRv) = 0;
 
-  void SetPathname(const nsAString& aPathname);
+  virtual void
+  GetSearch(nsAString& aSearch, ErrorResult& aRv) const = 0;
 
-  void GetSearch(nsAString& aRetval) const;
-
-  void SetSearch(const nsAString& aArg);
+  virtual void
+  SetSearch(const nsAString& aSearch, ErrorResult& aRv);
 
   URLSearchParams* SearchParams();
 
-  void GetHash(nsAString& aRetval) const;
-
-  void SetHash(const nsAString& aArg);
+  virtual void
+  GetHash(nsAString& aHost, ErrorResult& aRv) const = 0;
 
-  void Stringify(nsAString& aRetval) const
+  virtual void
+  SetHash(const nsAString& aHash, ErrorResult& aRv) = 0;
+
+  void Stringify(nsAString& aRetval, ErrorResult& aRv) const
   {
-    GetHref(aRetval);
+    GetHref(aRetval, aRv);
   }
 
   // URLSearchParamsObserver
-  void URLSearchParamsUpdated(URLSearchParams* aSearchParams) override;
+  void
+  URLSearchParamsUpdated(URLSearchParams* aSearchParams) override;
 
-private:
-  nsIURI* GetURI() const
-  {
-    return mURI;
-  }
+protected:
+  virtual ~URL()
+  {}
+
+  virtual void
+  UpdateURLSearchParams() = 0;
+
+  virtual void
+  SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) = 0;
 
   void CreateSearchParamsIfNeeded();
 
-  void SetSearchInternal(const nsAString& aSearch);
-
-  void UpdateURLSearchParams();
-
-  static void CreateObjectURLInternal(const GlobalObject& aGlobal,
-                                      nsISupports* aObject,
-                                      const nsACString& aScheme,
-                                      const objectURLOptions& aOptions,
-                                      nsAString& aResult,
-                                      ErrorResult& aError);
-
   nsCOMPtr<nsISupports> mParent;
-  nsCOMPtr<nsIURI> mURI;
   RefPtr<URLSearchParams> mSearchParams;
-
-  friend class mozilla::dom::workers::URLProxy;
 };
 
 bool IsChromeURI(nsIURI* aURI);
 
 } // namespace dom
 } // namespace mozilla
 
-#endif /* URL_h___ */
+#endif /* mozilla_dom_URL_h */
rename from dom/base/URLSearchParams.cpp
rename to dom/url/URLSearchParams.cpp
rename from dom/base/URLSearchParams.h
rename to dom/url/URLSearchParams.h
new file mode 100644
--- /dev/null
+++ b/dom/url/moz.build
@@ -0,0 +1,26 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS.mozilla.dom += [
+    'URL.h',
+    'URLSearchParams.h',
+]
+
+UNIFIED_SOURCES += [
+    'URL.cpp',
+    'URLSearchParams.cpp',
+]
+
+LOCAL_INCLUDES += [
+    '../workers',
+]
+
+MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
+MOCHITEST_CHROME_MANIFESTS += [ 'tests/chrome.ini' ]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'
new file mode 100644
--- /dev/null
+++ b/dom/url/tests/chrome.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+skip-if = buildapp == 'b2g' || os == 'android'
+support-files =
+  file_url.jsm
+  file_worker_url.jsm
+  test_bug883784.jsm
+  jsm_url_worker.js
+  !/dom/workers/test/dom_worker_helper.js
+
+[test_url.xul]
+[test_worker_url.xul]
+[test_bug883784.xul]
rename from dom/base/test/file_url.jsm
rename to dom/url/tests/file_url.jsm
rename from dom/workers/test/file_url.jsm
rename to dom/url/tests/file_worker_url.jsm
--- a/dom/workers/test/file_url.jsm
+++ b/dom/url/tests/file_worker_url.jsm
@@ -10,18 +10,17 @@ this.checkFromJSM = function checkFromJS
      finish();
     } else if (event.data.type == 'url') {
       URL.revokeObjectURL(event.data.url);
     } else if (event.data.type == 'status') {
       ok(event.data.status, event.data.msg);
     }
   }
 
-  var self = this;
   worker.onerror = function(event) {
     is(event.target, worker);
     ok(false, "Worker had an error: " + event.data);
-    self.worker.terminate();
+    worker.terminate();
     finish();
   };
 
   worker.postMessage(0);
 }
rename from dom/workers/test/jsm_url_worker.js
rename to dom/url/tests/jsm_url_worker.js
new file mode 100644
--- /dev/null
+++ b/dom/url/tests/mochitest.ini
@@ -0,0 +1,20 @@
+[DEFAULT]
+support-files =
+  url_worker.js
+  urlApi_worker.js
+  urlSearchParams_worker.js
+  url_exceptions_worker.js
+
+[test_url.html]
+[test_url_data.html]
+[test_url_empty_port.html]
+[test_url_malformedHost.html]
+[test_urlExceptions.html]
+[test_urlSearchParams.html]
+[test_urlSearchParams_utf8.html]
+[test_urlutils_stringify.html]
+[test_worker_url.html]
+[test_worker_urlApi.html]
+[test_worker_url_exceptions.html]
+[test_worker_urlSearchParams.html]
+[test_unknown_url_origin.html]
rename from dom/workers/test/test_bug883784.jsm
rename to dom/url/tests/test_bug883784.jsm
rename from dom/workers/test/test_bug883784.xul
rename to dom/url/tests/test_bug883784.xul
--- a/dom/workers/test/test_bug883784.xul
+++ b/dom/url/tests/test_bug883784.xul
@@ -6,26 +6,26 @@
 <window title="DOM Worker Threads Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="test();">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-  <script type="application/javascript" src="dom_worker_helper.js"/>
+  <script type="application/javascript" src="chrome://mochitests/content/chrome/dom/workers/test/dom_worker_helper.js"/>
 
   <script type="application/javascript">
   <![CDATA[
 
     function test()
     {
       waitForWorkerFinish();
 
-      Components.utils.import("chrome://mochitests/content/chrome/dom/workers/test/test_bug883784.jsm");
+      Components.utils.import("chrome://mochitests/content/chrome/dom/url/tests/test_bug883784.jsm");
       Test.start(ok, is, finish);
     }
 
   ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <p id="display"></p>
rename from dom/base/test/test_unknown_url_origin.html
rename to dom/url/tests/test_unknown_url_origin.html
rename from dom/base/test/test_url.html
rename to dom/url/tests/test_url.html
rename from dom/base/test/test_url.xul
rename to dom/url/tests/test_url.xul
rename from dom/base/test/test_urlExceptions.html
rename to dom/url/tests/test_urlExceptions.html
rename from dom/base/test/test_urlSearchParams.html
rename to dom/url/tests/test_urlSearchParams.html
rename from dom/base/test/test_urlSearchParams_utf8.html
rename to dom/url/tests/test_urlSearchParams_utf8.html
rename from dom/base/test/test_url_data.html
rename to dom/url/tests/test_url_data.html
rename from dom/base/test/test_url_empty_port.html
rename to dom/url/tests/test_url_empty_port.html
rename from dom/base/test/test_url_malformedHost.html
rename to dom/url/tests/test_url_malformedHost.html
rename from dom/base/test/test_urlutils_stringify.html
rename to dom/url/tests/test_urlutils_stringify.html
--- a/dom/base/test/test_urlutils_stringify.html
+++ b/dom/url/tests/test_urlutils_stringify.html
@@ -27,12 +27,12 @@ https://bugzilla.mozilla.org/show_bug.cg
   is(url + '', 'http://www.example.com:8080/', 'URL stringify');
 
   var link = document.getElementById("link");
   is(link + '', 'http://www.example.com:8080/', 'Anchor stringify');
 
   var area = document.getElementById("area");
   is(area + '', 'http://www.example.com:8080/', 'Area stringify');
 
-  is((location + '').indexOf('http://mochi.test:8888/tests/dom/base/test/test_urlutils_stringify.html'), 0, 'Location stringify');
+  is((location + '').indexOf('http://mochi.test:8888/tests/dom/url/tests/test_urlutils_stringify.html'), 0, 'Location stringify');
   </script>
 </body>
 </html>
rename from dom/workers/test/test_url.html
rename to dom/url/tests/test_worker_url.html
rename from dom/workers/test/test_url.xul
rename to dom/url/tests/test_worker_url.xul
--- a/dom/workers/test/test_url.xul
+++ b/dom/url/tests/test_worker_url.xul
@@ -6,27 +6,26 @@
 <window title="DOM Worker Threads Test"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="test();">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-  <script type="application/javascript" src="dom_worker_helper.js"/>
 
   <script type="application/javascript">
   <![CDATA[
 
     function test()
     {
-      waitForWorkerFinish();
+      SimpleTest.waitForExplicitFinish();
 
-      Components.utils.import("chrome://mochitests/content/chrome/dom/workers/test/file_url.jsm");
-      checkFromJSM(ok, is, finish);
+      Components.utils.import("chrome://mochitests/content/chrome/dom/url/tests/file_worker_url.jsm");
+      checkFromJSM(ok, is, SimpleTest.finish);
     }
 
   ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <p id="display"></p>
     <div id="content" style="display:none;"></div>
rename from dom/workers/test/test_urlApi.html
rename to dom/url/tests/test_worker_urlApi.html
rename from dom/workers/test/test_urlSearchParams.html
rename to dom/url/tests/test_worker_urlSearchParams.html
rename from dom/workers/test/test_url_exceptions.html
rename to dom/url/tests/test_worker_url_exceptions.html
rename from dom/workers/test/urlApi_worker.js
rename to dom/url/tests/urlApi_worker.js
rename from dom/workers/test/urlSearchParams_worker.js
rename to dom/url/tests/urlSearchParams_worker.js
rename from dom/workers/test/url_exceptions_worker.js
rename to dom/url/tests/url_exceptions_worker.js
rename from dom/workers/test/url_worker.js
rename to dom/url/tests/url_worker.js
--- a/dom/webidl/AnalyserNode.webidl
+++ b/dom/webidl/AnalyserNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface AnalyserNode : AudioNode {
 
     // Real-time frequency-domain data
--- a/dom/webidl/AudioBuffer.webidl
+++ b/dom/webidl/AudioBuffer.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface AudioBuffer {
 
     readonly attribute float sampleRate;
--- a/dom/webidl/AudioBufferSourceNode.webidl
+++ b/dom/webidl/AudioBufferSourceNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface AudioBufferSourceNode : AudioNode {
 
     attribute AudioBuffer? buffer;
--- a/dom/webidl/AudioContext.webidl
+++ b/dom/webidl/AudioContext.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 callback DecodeSuccessCallback = void (AudioBuffer decodedData);
 callback DecodeErrorCallback = void ();
 
--- a/dom/webidl/AudioDestinationNode.webidl
+++ b/dom/webidl/AudioDestinationNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface AudioDestinationNode : AudioNode {
 
     readonly attribute unsigned long maxChannelCount;
--- a/dom/webidl/AudioListener.webidl
+++ b/dom/webidl/AudioListener.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface AudioListener {
 
     // same as OpenAL (default 1)
--- a/dom/webidl/AudioNode.webidl
+++ b/dom/webidl/AudioNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 enum ChannelCountMode {
     "max",
     "clamped-max",
--- a/dom/webidl/AudioParam.webidl
+++ b/dom/webidl/AudioParam.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface AudioParam {
 
     attribute float value;
--- a/dom/webidl/AudioProcessingEvent.webidl
+++ b/dom/webidl/AudioProcessingEvent.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface AudioProcessingEvent : Event {
 
   readonly attribute double playbackTime;
--- a/dom/webidl/BiquadFilterNode.webidl
+++ b/dom/webidl/BiquadFilterNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 enum BiquadFilterType {
   "lowpass",
   "highpass",
--- a/dom/webidl/ChannelMergerNode.webidl
+++ b/dom/webidl/ChannelMergerNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface ChannelMergerNode : AudioNode {
 
 };
--- a/dom/webidl/ChannelSplitterNode.webidl
+++ b/dom/webidl/ChannelSplitterNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface ChannelSplitterNode : AudioNode {
 
 };
--- a/dom/webidl/Clients.webidl
+++ b/dom/webidl/Clients.webidl
@@ -11,17 +11,17 @@
 [Exposed=ServiceWorker]
 interface Clients {
   // The objects returned will be new instances every time
   [NewObject]
   Promise<any> get(DOMString id);
   [NewObject]
   Promise<sequence<Client>> matchAll(optional ClientQueryOptions options);
   [NewObject,
-   Func="mozilla::dom::workers::ServiceWorkerGlobalScope::OpenWindowEnabled"]
+   Func="mozilla::dom::ServiceWorkerGlobalScope::OpenWindowEnabled"]
   Promise<WindowClient?> openWindow(USVString url);
   [NewObject]
   Promise<void> claim();
 };
 
 dictionary ClientQueryOptions {
   boolean includeUncontrolled = false;
   ClientType type = "window";
--- a/dom/webidl/ConvolverNode.webidl
+++ b/dom/webidl/ConvolverNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface ConvolverNode : AudioNode {
 
       [SetterThrows]
--- a/dom/webidl/DelayNode.webidl
+++ b/dom/webidl/DelayNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface DelayNode : AudioNode {
 
     readonly attribute AudioParam delayTime;
--- a/dom/webidl/DummyBinding.webidl
+++ b/dom/webidl/DummyBinding.webidl
@@ -6,11 +6,8 @@
 
 // Dummy bindings that we need to force generation of things that
 // aren't actually referenced anywhere in IDL yet but are used in C++.
 
 interface DummyInterface {
   void lifecycleCallbacks(optional LifecycleCallbacks arg);
   void promiseJobCallback(PromiseJobCallback arg);
 };
-
-interface DummyInterfaceWorkers {
-};
--- a/dom/webidl/DynamicsCompressorNode.webidl
+++ b/dom/webidl/DynamicsCompressorNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface DynamicsCompressorNode : AudioNode {
 
     readonly attribute AudioParam threshold; // in Decibels
--- a/dom/webidl/GainNode.webidl
+++ b/dom/webidl/GainNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface GainNode : AudioNode {
 
     readonly attribute AudioParam gain;
--- a/dom/webidl/MediaElementAudioSourceNode.webidl
+++ b/dom/webidl/MediaElementAudioSourceNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface MediaElementAudioSourceNode : AudioNode {
 
 };
--- a/dom/webidl/MediaStreamAudioDestinationNode.webidl
+++ b/dom/webidl/MediaStreamAudioDestinationNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface MediaStreamAudioDestinationNode : AudioNode {
 
     readonly attribute MediaStream stream;
--- a/dom/webidl/MediaStreamAudioSourceNode.webidl
+++ b/dom/webidl/MediaStreamAudioSourceNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface MediaStreamAudioSourceNode : AudioNode {
 
 };
--- a/dom/webidl/OfflineAudioCompletionEvent.webidl
+++ b/dom/webidl/OfflineAudioCompletionEvent.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface OfflineAudioCompletionEvent : Event {
 
     readonly attribute AudioBuffer renderedBuffer;
--- a/dom/webidl/OfflineAudioContext.webidl
+++ b/dom/webidl/OfflineAudioContext.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 callback OfflineRenderSuccessCallback = void (AudioBuffer renderedData);
 
 [Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate)]
--- a/dom/webidl/OscillatorNode.webidl
+++ b/dom/webidl/OscillatorNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 enum OscillatorType {
   "sine",
   "square",
--- a/dom/webidl/PannerNode.webidl
+++ b/dom/webidl/PannerNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 enum PanningModelType {
   "equalpower",
   "HRTF"
--- a/dom/webidl/PeriodicWave.webidl
+++ b/dom/webidl/PeriodicWave.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface PeriodicWave {
 
 };
--- a/dom/webidl/ScriptProcessorNode.webidl
+++ b/dom/webidl/ScriptProcessorNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface ScriptProcessorNode : AudioNode {
 
     attribute EventHandler onaudioprocess;
--- a/dom/webidl/StereoPannerNode.webidl
+++ b/dom/webidl/StereoPannerNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface StereoPannerNode : AudioNode {
   readonly attribute AudioParam pan;
 };
--- a/dom/webidl/URL.webidl
+++ b/dom/webidl/URL.webidl
@@ -16,41 +16,41 @@
 [Constructor(DOMString url, URL base),
  Constructor(DOMString url, optional DOMString base),
  Exposed=(Window,Worker,WorkerDebugger)]
 interface URL {
   // Bug 824857: no support for stringifier attributes yet.
   //  stringifier attribute USVString href;
 
   // Bug 824857 should remove this.
-  [Throws=Workers]
+  [Throws]
   stringifier;
 
-  [SetterThrows, GetterThrows=Workers]
+  [Throws]
   attribute USVString href;
-  [Throws=Workers]
+  [Throws]
   readonly attribute USVString origin;
-  [Throws=Workers]
+  [Throws]
            attribute USVString protocol;
-  [Throws=Workers]
+  [Throws]
            attribute USVString username;
-  [Throws=Workers]
+  [Throws]
            attribute USVString password;
-  [Throws=Workers]
+  [Throws]
            attribute USVString host;
-  [Throws=Workers]
+  [Throws]
            attribute USVString hostname;
-  [Throws=Workers]
+  [Throws]
            attribute USVString port;
-  [Throws=Workers]
+  [Throws]
            attribute USVString pathname;
-  [Throws=Workers]
+  [Throws]
            attribute USVString search;
   readonly attribute URLSearchParams searchParams;
-  [Throws=Workers]
+  [Throws]
            attribute USVString hash;
 };
 
 partial interface URL {
   [Throws]
   static DOMString? createObjectURL(Blob blob, optional objectURLOptions options);
   [Throws]
   static DOMString? createObjectURL(MediaStream stream, optional objectURLOptions options);
--- a/dom/webidl/WaveShaperNode.webidl
+++ b/dom/webidl/WaveShaperNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  *
  * The origin of this IDL file is
- * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
+ * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 enum OverSampleType {
   "none",
   "2x",
--- a/dom/workers/ServiceWorker.cpp
+++ b/dom/workers/ServiceWorker.cpp
@@ -31,18 +31,17 @@ namespace workers {
 bool
 ServiceWorkerVisible(JSContext* aCx, JSObject* aObj)
 {
   if (NS_IsMainThread()) {
     return Preferences::GetBool("dom.serviceWorkers.enabled", false);
   }
 
   ServiceWorkerGlobalScope* scope = nullptr;
-  nsresult rv = UnwrapObject<prototypes::id::ServiceWorkerGlobalScope_workers,
-                             mozilla::dom::ServiceWorkerGlobalScopeBinding_workers::NativeType>(aObj, scope);
+  nsresult rv = UNWRAP_OBJECT(ServiceWorkerGlobalScope, aObj, scope);
   return NS_SUCCEEDED(rv);
 }
 
 ServiceWorker::ServiceWorker(nsPIDOMWindowInner* aWindow,
                              ServiceWorkerInfo* aInfo)
   : DOMEventTargetHelper(aWindow),
     mInfo(aInfo)
 {
--- a/dom/workers/ServiceWorkerClients.cpp
+++ b/dom/workers/ServiceWorkerClients.cpp
@@ -68,17 +68,17 @@ class GetRunnable final : public Runnabl
     UniquePtr<ServiceWorkerClientInfo> mValue;
     nsresult mRv;
 
   public:
     ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
                                  PromiseWorkerProxy* aPromiseProxy,
                                  UniquePtr<ServiceWorkerClientInfo>&& aValue,
                                  nsresult aRv)
-      : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
+      : WorkerRunnable(aWorkerPrivate),
         mPromiseProxy(aPromiseProxy),
         mValue(Move(aValue)),
         mRv(Move(aRv))
     {
       AssertIsOnMainThread();
     }
 
     bool
@@ -148,17 +148,17 @@ class MatchAllRunnable final : public Ru
   {
     RefPtr<PromiseWorkerProxy> mPromiseProxy;
     nsTArray<ServiceWorkerClientInfo> mValue;
 
   public:
     ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
                                  PromiseWorkerProxy* aPromiseProxy,
                                  nsTArray<ServiceWorkerClientInfo>& aValue)
-      : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
+      : WorkerRunnable(aWorkerPrivate),
         mPromiseProxy(aPromiseProxy)
     {
       AssertIsOnMainThread();
       mValue.SwapElements(aValue);
     }
 
     bool
     WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
@@ -224,17 +224,17 @@ class ResolveClaimRunnable final : publi
 {
   RefPtr<PromiseWorkerProxy> mPromiseProxy;
   nsresult mResult;
 
 public:
   ResolveClaimRunnable(WorkerPrivate* aWorkerPrivate,
                        PromiseWorkerProxy* aPromiseProxy,
                        nsresult aResult)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
     , mPromiseProxy(aPromiseProxy)
     , mResult(aResult)
   {
     AssertIsOnMainThread();
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
@@ -299,17 +299,17 @@ public:
 };
 
 class ResolveOpenWindowRunnable final : public WorkerRunnable
 {
 public:
   ResolveOpenWindowRunnable(PromiseWorkerProxy* aPromiseProxy,
                             UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
                             const nsresult aStatus)
-  : WorkerRunnable(aPromiseProxy->GetWorkerPrivate(), WorkerThreadModifyBusyCount)
+  : WorkerRunnable(aPromiseProxy->GetWorkerPrivate())
   , mPromiseProxy(aPromiseProxy)
   , mClientInfo(Move(aClientInfo))
   , mStatus(aStatus)
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(aPromiseProxy);
   }
 
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -134,17 +134,17 @@ class CheckScriptEvaluationWithCallback 
 #ifdef DEBUG
   bool mDone;
 #endif
 
 public:
   CheckScriptEvaluationWithCallback(WorkerPrivate* aWorkerPrivate,
                                     KeepAliveToken* aKeepAliveToken,
                                     LifeCycleEventCallback* aCallback)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
     , mKeepAliveToken(new nsMainThreadPtrHolder<KeepAliveToken>(aKeepAliveToken))
     , mCallback(aCallback)
 #ifdef DEBUG
     , mDone(false)
 #endif
   {
     AssertIsOnMainThread();
   }
@@ -380,17 +380,17 @@ public:
 class ExtendableEventWorkerRunnable : public WorkerRunnable
 {
 protected:
   nsMainThreadPtrHandle<KeepAliveToken> mKeepAliveToken;
 
 public:
   ExtendableEventWorkerRunnable(WorkerPrivate* aWorkerPrivate,
                                 KeepAliveToken* aKeepAliveToken)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(aWorkerPrivate);
     MOZ_ASSERT(aKeepAliveToken);
 
     mKeepAliveToken =
       new nsMainThreadPtrHolder<KeepAliveToken>(aKeepAliveToken);
   }
--- a/dom/workers/ServiceWorkerRegistration.cpp
+++ b/dom/workers/ServiceWorkerRegistration.cpp
@@ -389,17 +389,17 @@ class UpdateResultRunnable final : publi
   RefPtr<PromiseWorkerProxy> mPromiseProxy;
   ErrorResult mStatus;
 
   ~UpdateResultRunnable()
   {}
 
 public:
   UpdateResultRunnable(PromiseWorkerProxy* aPromiseProxy, ErrorResult& aStatus)
-    : WorkerRunnable(aPromiseProxy->GetWorkerPrivate(), WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aPromiseProxy->GetWorkerPrivate())
     , mPromiseProxy(aPromiseProxy)
     , mStatus(Move(aStatus))
   { }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
     Promise* promise = mPromiseProxy->WorkerPromise();
@@ -551,17 +551,17 @@ NS_IMPL_ISUPPORTS(UnregisterCallback, ns
 
 class FulfillUnregisterPromiseRunnable final : public WorkerRunnable
 {
   RefPtr<PromiseWorkerProxy> mPromiseWorkerProxy;
   Maybe<bool> mState;
 public:
   FulfillUnregisterPromiseRunnable(PromiseWorkerProxy* aProxy,
                                    Maybe<bool> aState)
-    : WorkerRunnable(aProxy->GetWorkerPrivate(), WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aProxy->GetWorkerPrivate())
     , mPromiseWorkerProxy(aProxy)
     , mState(aState)
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(mPromiseWorkerProxy);
   }
 
   bool
@@ -1280,17 +1280,17 @@ ServiceWorkerRegistrationWorkerThread::N
 }
 
 class FireUpdateFoundRunnable final : public WorkerRunnable
 {
   RefPtr<WorkerListener> mListener;
 public:
   FireUpdateFoundRunnable(WorkerPrivate* aWorkerPrivate,
                           WorkerListener* aListener)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
     , mListener(aListener)
   {
     // Need this assertion for now since runnables which modify busy count can
     // only be dispatched from parent thread to worker thread and we don't deal
     // with nested workers. SW threads can't be nested.
     MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
   }
 
--- a/dom/workers/ServiceWorkerWindowClient.cpp
+++ b/dom/workers/ServiceWorkerWindowClient.cpp
@@ -36,17 +36,17 @@ class ResolveOrRejectPromiseRunnable fin
 {
   RefPtr<PromiseWorkerProxy> mPromiseProxy;
   UniquePtr<ServiceWorkerClientInfo> mClientInfo;
 
 public:
   ResolveOrRejectPromiseRunnable(WorkerPrivate* aWorkerPrivate,
                                  PromiseWorkerProxy* aPromiseProxy,
                                  UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
     , mPromiseProxy(aPromiseProxy)
     , mClientInfo(Move(aClientInfo))
   {
     AssertIsOnMainThread();
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
deleted file mode 100644
--- a/dom/workers/URL.cpp
+++ /dev/null
@@ -1,954 +0,0 @@
-/* -*- 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/. */
-
-#include "URL.h"
-
-#include "nsIIOService.h"
-#include "nsPIDOMWindow.h"
-
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/URL.h"
-#include "mozilla/dom/URLBinding.h"
-#include "mozilla/dom/URLSearchParams.h"
-#include "mozilla/dom/ipc/BlobChild.h"
-#include "mozilla/dom/ipc/nsIRemoteBlob.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "nsGlobalWindow.h"
-#include "nsHostObjectProtocolHandler.h"
-#include "nsNetCID.h"
-#include "nsServiceManagerUtils.h"
-#include "nsThreadUtils.h"
-
-#include "WorkerPrivate.h"
-#include "WorkerRunnable.h"
-#include "WorkerScope.h"
-
-BEGIN_WORKERS_NAMESPACE
-using mozilla::dom::GlobalObject;
-
-class URLProxy final
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
-
-  explicit URLProxy(already_AddRefed<mozilla::dom::URL> aURL)
-    : mURL(aURL)
-  {
-    AssertIsOnMainThread();
-  }
-
-  mozilla::dom::URL* URL()
-  {
-    return mURL;
-  }
-
-  nsIURI* URI()
-  {
-    return mURL->GetURI();
-  }
-
-  void ReleaseURI()
-  {
-    AssertIsOnMainThread();
-    mURL = nullptr;
-  }
-
-private:
-  // Private destructor, to discourage deletion outside of Release():
-  ~URLProxy()
-  {
-     MOZ_ASSERT(!mURL);
-  }
-
-  RefPtr<mozilla::dom::URL> mURL;
-};
-
-// This class creates an URL from a DOM Blob on the main thread.
-class CreateURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  BlobImpl* mBlobImpl;
-  nsAString& mURL;
-
-public:
-  CreateURLRunnable(WorkerPrivate* aWorkerPrivate, BlobImpl* aBlobImpl,
-                    const mozilla::dom::objectURLOptions& aOptions,
-                    nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: CreateURL"))
-  , mBlobImpl(aBlobImpl)
-  , mURL(aURL)
-  {
-    MOZ_ASSERT(aBlobImpl);
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-  }
-
-  bool
-  MainThreadRun()
-  {
-    using namespace mozilla::ipc;
-
-    AssertIsOnMainThread();
-
-    RefPtr<BlobImpl> newBlobImplHolder;
-
-    if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(mBlobImpl)) {
-      if (BlobChild* blobChild = remoteBlob->GetBlobChild()) {
-        if (PBackgroundChild* blobManager = blobChild->GetBackgroundManager()) {
-          PBackgroundChild* backgroundManager =
-            BackgroundChild::GetForCurrentThread();
-          MOZ_ASSERT(backgroundManager);
-
-          if (blobManager != backgroundManager) {
-            // Always make sure we have a blob from an actor we can use on this
-            // thread.
-            blobChild = BlobChild::GetOrCreate(backgroundManager, mBlobImpl);
-            MOZ_ASSERT(blobChild);
-
-            newBlobImplHolder = blobChild->GetBlobImpl();
-            MOZ_ASSERT(newBlobImplHolder);
-
-            mBlobImpl = newBlobImplHolder;
-          }
-        }
-      }
-    }
-
-    DebugOnly<bool> isMutable;
-    MOZ_ASSERT(NS_SUCCEEDED(mBlobImpl->GetMutable(&isMutable)));
-    MOZ_ASSERT(!isMutable);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    nsAutoCString url;
-    nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
-        NS_LITERAL_CSTRING(BLOBURI_SCHEME),
-        mBlobImpl, principal, url);
-
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Failed to add data entry for the blob!");
-      SetDOMStringToNull(mURL);
-      return false;
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->RegisterHostObjectURI(url);
-      }
-    }
-
-    mURL = NS_ConvertUTF8toUTF16(url);
-    return true;
-  }
-};
-
-// This class revokes an URL on the main thread.
-class RevokeURLRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-public:
-  RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
-                    const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: RevokeURL"))
-  , mURL(aURL)
-  {}
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    NS_ConvertUTF16toUTF8 url(mURL);
-
-    nsIPrincipal* urlPrincipal =
-      nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
-
-    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
-
-    bool subsumes;
-    if (urlPrincipal &&
-        NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
-        subsumes) {
-      nsHostObjectProtocolHandler::RemoveDataEntry(url);
-    }
-
-    if (!mWorkerPrivate->IsSharedWorker() &&
-        !mWorkerPrivate->IsServiceWorker()) {
-      // Walk up to top worker object.
-      WorkerPrivate* wp = mWorkerPrivate;
-      while (WorkerPrivate* parent = wp->GetParent()) {
-        wp = parent;
-      }
-
-      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
-      // We could not have a ScriptContext in JSM code. In this case, we leak.
-      if (sc) {
-        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
-        MOZ_ASSERT(global);
-
-        global->UnregisterHostObjectURI(url);
-      }
-    }
-
-    return true;
-  }
-};
-
-// This class creates a URL object on the main thread.
-class ConstructorRunnable : public WorkerMainThreadRunnable
-{
-private:
-  const nsString mURL;
-
-  nsString mBase; // IsVoid() if we have no base URI string.
-  RefPtr<URLProxy> mBaseProxy;
-  mozilla::ErrorResult& mRv;
-
-  RefPtr<URLProxy> mRetval;
-
-public:
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, const Optional<nsAString>& aBase,
-                      mozilla::ErrorResult& aRv)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor"))
-  , mURL(aURL)
-  , mRv(aRv)
-  {
-    if (aBase.WasPassed()) {
-      mBase = aBase.Value();
-    } else {
-      mBase.SetIsVoid(true);
-    }
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
-                      const nsAString& aURL, URLProxy* aBaseProxy,
-                      mozilla::ErrorResult& aRv)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             NS_LITERAL_CSTRING("URL :: Constructor with BaseURL"))
-  , mURL(aURL)
-  , mBaseProxy(aBaseProxy)
-  , mRv(aRv)
-  {
-    mBase.SetIsVoid(true);
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    RefPtr<mozilla::dom::URL> url;
-    if (mBaseProxy) {
-      url = mozilla::dom::URL::Constructor(nullptr, mURL, mBaseProxy->URI(),
-                                           mRv);
-    } else if (!mBase.IsVoid()) {
-      url = mozilla::dom::URL::Constructor(nullptr, mURL, mBase, mRv);
-    } else {
-      url = mozilla::dom::URL::Constructor(nullptr, mURL, nullptr, mRv);
-    }
-
-    if (mRv.Failed()) {
-      return true;
-    }
-
-    mRetval = new URLProxy(url.forget());
-    return true;
-  }
-
-  URLProxy*
-  GetURLProxy()
-  {
-    return mRetval;
-  }
-};
-
-class TeardownURLRunnable : public Runnable
-{
-public:
-  explicit TeardownURLRunnable(URLProxy* aURLProxy)
-    : mURLProxy(aURLProxy)
-  {
-  }
-
-  NS_IMETHOD Run()
-  {
-    AssertIsOnMainThread();
-
-    mURLProxy->ReleaseURI();
-    mURLProxy = nullptr;
-
-    return NS_OK;
-  }
-
-private:
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic getter for any URL property.
-class GetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum GetterType {
-    GetterHref,
-    GetterOrigin,
-    GetterProtocol,
-    GetterUsername,
-    GetterPassword,
-    GetterHost,
-    GetterHostname,
-    GetterPort,
-    GetterPathname,
-    GetterSearch,
-    GetterHash,
-  };
-
-  GetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 GetterType aType, nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each getter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: getter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    switch (mType) {
-      case GetterHref:
-        mURLProxy->URL()->GetHref(mValue);
-        break;
-
-      case GetterOrigin:
-        mURLProxy->URL()->GetOrigin(mValue);
-        break;
-
-      case GetterProtocol:
-        mURLProxy->URL()->GetProtocol(mValue);
-        break;
-
-      case GetterUsername:
-        mURLProxy->URL()->GetUsername(mValue);
-        break;
-
-      case GetterPassword:
-        mURLProxy->URL()->GetPassword(mValue);
-        break;
-
-      case GetterHost:
-        mURLProxy->URL()->GetHost(mValue);
-        break;
-
-      case GetterHostname:
-        mURLProxy->URL()->GetHostname(mValue);
-        break;
-
-      case GetterPort:
-        mURLProxy->URL()->GetPort(mValue);
-        break;
-
-      case GetterPathname:
-        mURLProxy->URL()->GetPathname(mValue);
-        break;
-
-      case GetterSearch:
-        mURLProxy->URL()->GetSearch(mValue);
-        break;
-
-      case GetterHash:
-        mURLProxy->URL()->GetHash(mValue);
-        break;
-    }
-
-    return true;
-  }
-
-private:
-  nsAString& mValue;
-  GetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-};
-
-// This class is the generic setter for any URL property.
-class SetterRunnable : public WorkerMainThreadRunnable
-{
-public:
-  enum SetterType {
-    SetterHref,
-    SetterProtocol,
-    SetterUsername,
-    SetterPassword,
-    SetterHost,
-    SetterHostname,
-    SetterPort,
-    SetterPathname,
-    SetterSearch,
-    SetterHash,
-  };
-
-  SetterRunnable(WorkerPrivate* aWorkerPrivate,
-                 SetterType aType, const nsAString& aValue,
-                 URLProxy* aURLProxy)
-  : WorkerMainThreadRunnable(aWorkerPrivate,
-                             // We can have telemetry keys for each setter when
-                             // needed.
-                             NS_LITERAL_CSTRING("URL :: setter"))
-  , mValue(aValue)
-  , mType(aType)
-  , mURLProxy(aURLProxy)
-  , mFailed(false)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  MainThreadRun()
-  {
-    AssertIsOnMainThread();
-
-    switch (mType) {
-      case SetterHref: {
-        ErrorResult rv;
-        mURLProxy->URL()->SetHref(mValue, rv);
-        if (NS_WARN_IF(rv.Failed())) {
-          rv.SuppressException();
-          mFailed = true;
-        }
-
-        break;
-      }
-
-      case SetterProtocol:
-        mURLProxy->URL()->SetProtocol(mValue);
-        break;
-
-      case SetterUsername:
-        mURLProxy->URL()->SetUsername(mValue);
-        break;
-
-      case SetterPassword:
-        mURLProxy->URL()->SetPassword(mValue);
-        break;
-
-      case SetterHost:
-        mURLProxy->URL()->SetHost(mValue);
-        break;
-
-      case SetterHostname:
-        mURLProxy->URL()->SetHostname(mValue);
-        break;
-
-      case SetterPort:
-        mURLProxy->URL()->SetPort(mValue);
-        break;
-
-      case SetterPathname:
-        mURLProxy->URL()->SetPathname(mValue);
-        break;
-
-      case SetterSearch:
-        mURLProxy->URL()->SetSearch(mValue);
-        break;
-
-      case SetterHash:
-        mURLProxy->URL()->SetHash(mValue);
-        break;
-    }
-
-    return true;
-  }
-
-  bool Failed() const
-  {
-    return mFailed;
-  }
-
-private:
-  const nsString mValue;
-  SetterType mType;
-  RefPtr<URLProxy> mURLProxy;
-  bool mFailed;
-};
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mSearchParams)
-
-// The reason for using worker::URL is to have different refcnt logging than
-// for main thread URL.
-NS_IMPL_CYCLE_COLLECTING_ADDREF(workers::URL)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(workers::URL)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-// static
-already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-                 URL& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aUrl, aBase.GetURLProxy(), aRv);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-// static
-already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-                 const Optional<nsAString>& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aUrl, aBase, aRv);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-// static
-already_AddRefed<URL>
-URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-                 const nsAString& aBase, ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  Optional<nsAString> base;
-  base = &aBase;
-  RefPtr<ConstructorRunnable> runnable =
-    new ConstructorRunnable(workerPrivate, aUrl, base, aRv);
-
-  return FinishConstructor(cx, workerPrivate, runnable, aRv);
-}
-
-// static
-already_AddRefed<URL>
-URL::FinishConstructor(JSContext* aCx, WorkerPrivate* aPrivate,
-                       ConstructorRunnable* aRunnable, ErrorResult& aRv)
-{
-  aRunnable->Dispatch(aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<URLProxy> proxy = aRunnable->GetURLProxy();
-  if (!proxy) {
-    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return nullptr;
-  }
-
-  RefPtr<URL> url = new URL(aPrivate, proxy);
-  return url.forget();
-}
-
-URL::URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
-  : mWorkerPrivate(aWorkerPrivate)
-  , mURLProxy(aURLProxy)
-{
-  MOZ_COUNT_CTOR(workers::URL);
-}
-
-URL::~URL()
-{
-  MOZ_COUNT_DTOR(workers::URL);
-
-  if (mURLProxy) {
-    RefPtr<TeardownURLRunnable> runnable =
-      new TeardownURLRunnable(mURLProxy);
-    mURLProxy = nullptr;
-
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      NS_ERROR("Failed to dispatch teardown runnable!");
-    }
-  }
-}
-
-JSObject*
-URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return URLBinding_workers::Wrap(aCx, this, aGivenProto);
-}
-
-void
-URL::GetHref(nsAString& aHref, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetHref(const nsAString& aHref, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-  if (aRv.Failed()) {
-    return;
-  }
-
-  if (runnable->Failed()) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
-    return;
-  }
-
-  UpdateURLSearchParams();
-}
-
-void
-URL::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
-                       aProtocol, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URL::GetUsername(nsAString& aUsername, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetUsername(const nsAString& aUsername, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
-                       aUsername, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URL::GetPassword(nsAString& aPassword, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetPassword(const nsAString& aPassword, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
-                       aPassword, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URL::GetHost(nsAString& aHost, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetHost(const nsAString& aHost, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
-                       aHost, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URL::GetHostname(nsAString& aHostname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetHostname(const nsAString& aHostname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
-                       aHostname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URL::GetPort(nsAString& aPort, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetPort(const nsAString& aPort, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
-                       aPort, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URL::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname, aPathname,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
-                       aPathname, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-void
-URL::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv)
-{
-  SetSearchInternal(aSearch, aRv);
-  UpdateURLSearchParams();
-}
-
-void
-URL::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
-                       aSearch, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-mozilla::dom::URLSearchParams*
-URL::SearchParams()
-{
-  CreateSearchParamsIfNeeded();
-  return mSearchParams;
-}
-
-void
-URL::GetHash(nsAString& aHash, ErrorResult& aRv) const
-{
-  RefPtr<GetterRunnable> runnable =
-    new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
-                       mURLProxy);
-
-  runnable->Dispatch(aRv);
-}
-
-void
-URL::SetHash(const nsAString& aHash, ErrorResult& aRv)
-{
-  RefPtr<SetterRunnable> runnable =
-    new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
-                       aHash, mURLProxy);
-
-  runnable->Dispatch(aRv);
-
-  MOZ_ASSERT(!runnable->Failed());
-}
-
-// static
-void
-URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
-                     const mozilla::dom::objectURLOptions& aOptions,
-                     nsAString& aResult, mozilla::ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<BlobImpl> blobImpl = aBlob.Impl();
-  MOZ_ASSERT(blobImpl);
-
-  aRv = blobImpl->SetMutable(false);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
-
-  RefPtr<CreateURLRunnable> runnable =
-    new CreateURLRunnable(workerPrivate, blobImpl, aOptions, aResult);
-
-  runnable->Dispatch(aRv);
-  if (aRv.Failed()) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->RegisterHostObjectURI(NS_ConvertUTF16toUTF8(aResult));
-  }
-}
-
-// static
-void
-URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                     ErrorResult& aRv)
-{
-  JSContext* cx = aGlobal.Context();
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-
-  RefPtr<RevokeURLRunnable> runnable =
-    new RevokeURLRunnable(workerPrivate, aUrl);
-
-  runnable->Dispatch(aRv);
-  if (aRv.Failed()) {
-    return;
-  }
-
-  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
-    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
-    MOZ_ASSERT(scope);
-
-    scope->UnregisterHostObjectURI(NS_ConvertUTF16toUTF8(aUrl));
-  }
-}
-
-void
-URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
-{
-  MOZ_ASSERT(mSearchParams);
-  MOZ_ASSERT(mSearchParams == aSearchParams);
-
-  nsAutoString search;
-  mSearchParams->Serialize(search);
-  ErrorResult rv;
-  SetSearchInternal(search, rv);
-  // XXXbz and now what?  We're supposed to stop everything if rv failed!
-  rv.SuppressException();
-}
-
-void
-URL::UpdateURLSearchParams()
-{
-  if (mSearchParams) {
-    nsAutoString search;
-    ErrorResult rv;
-    GetSearch(search, rv);
-    // XXXbz and now what?  We're supposed to stop everything if rv failed!
-    rv.SuppressException();
-    mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)));
-  }
-}
-
-void
-URL::CreateSearchParamsIfNeeded()
-{
-  if (!mSearchParams) {
-    mSearchParams = new URLSearchParams(nullptr, this);
-    UpdateURLSearchParams();
-  }
-}
-
-END_WORKERS_NAMESPACE
deleted file mode 100644
--- a/dom/workers/URL.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- 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
- * url, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_workers_url_h__
-#define mozilla_dom_workers_url_h__
-
-#include "Workers.h"
-
-#include "mozilla/ErrorResult.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/URLSearchParams.h"
-#include "nsWrapperCache.h"
-
-namespace mozilla {
-namespace dom {
-class Blob;
-struct objectURLOptions;
-} // namespace dom
-} // namespace mozilla
-
-BEGIN_WORKERS_NAMESPACE
-
-class URLProxy;
-class ConstructorRunnable;
-
-class URL final : public mozilla::dom::URLSearchParamsObserver
-                , public nsWrapperCache
-{
-  typedef mozilla::dom::URLSearchParams URLSearchParams;
-
-  ~URL();
-
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(URL)
-
-  URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy);
-
-  nsISupports*
-  GetParentObject() const
-  {
-    // There's only one global on a worker, so we don't need to specify.
-    return nullptr;
-  }
-
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  // Methods for WebIDL
-
-  static already_AddRefed<URL>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-              URL& aBase, ErrorResult& aRv);
-  static already_AddRefed<URL>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-              const Optional<nsAString>& aBase, ErrorResult& aRv);
-  static already_AddRefed<URL>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
-              const nsAString& aBase, ErrorResult& aRv);
-
-  static void
-  CreateObjectURL(const GlobalObject& aGlobal,
-                  Blob& aArg, const objectURLOptions& aOptions,
-                  nsAString& aResult, ErrorResult& aRv);
-
-  static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
-                  ErrorResult& aRv);
-
-  void GetHref(nsAString& aHref, ErrorResult& aRv) const;
-
-  void SetHref(const nsAString& aHref, ErrorResult& aRv);
-
-  void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const;
-
-  void GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const;
-
-  void SetProtocol(const nsAString& aProtocol, ErrorResult& aRv);
-
-  void GetUsername(nsAString& aUsername, ErrorResult& aRv) const;
-
-  void SetUsername(const nsAString& aUsername, ErrorResult& aRv);
-
-  void GetPassword(nsAString& aPassword, ErrorResult& aRv) const;
-
-  void SetPassword(const nsAString& aPassword, ErrorResult& aRv);
-
-  void GetHost(nsAString& aHost, ErrorResult& aRv) const;
-
-  void SetHost(const nsAString& aHost, ErrorResult& aRv);
-
-  void GetHostname(nsAString& aHostname, ErrorResult& aRv) const;
-
-  void SetHostname(const nsAString& aHostname, ErrorResult& aRv);
-
-  void GetPort(nsAString& aPort, ErrorResult& aRv) const;
-
-  void SetPort(const nsAString& aPort, ErrorResult& aRv);
-
-  void GetPathname(nsAString& aPathname, ErrorResult& aRv) const;
-
-  void SetPathname(const nsAString& aPathname, ErrorResult& aRv);
-
-  void GetSearch(nsAString& aSearch, ErrorResult& aRv) const;
-
-  void SetSearch(const nsAString& aSearch, ErrorResult& aRv);
-
-  URLSearchParams* SearchParams();
-
-  void GetHash(nsAString& aHost, ErrorResult& aRv) const;
-
-  void SetHash(const nsAString& aHash, ErrorResult& aRv);
-
-  void Stringify(nsAString& aRetval, ErrorResult& aRv) const
-  {
-    GetHref(aRetval, aRv);
-  }
-
-  // IURLSearchParamsObserver
-  void URLSearchParamsUpdated(URLSearchParams* aSearchParams) override;
-
-private:
-  URLProxy* GetURLProxy() const
-  {
-    return mURLProxy;
-  }
-
-  static already_AddRefed<URL>
-  FinishConstructor(JSContext* aCx, WorkerPrivate* aPrivate,
-                    ConstructorRunnable* aRunnable, ErrorResult& aRv);
-
-  void CreateSearchParamsIfNeeded();
-
-  void SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv);
-
-  void UpdateURLSearchParams();
-
-  WorkerPrivate* mWorkerPrivate;
-  RefPtr<URLProxy> mURLProxy;
-  RefPtr<URLSearchParams> mSearchParams;
-};
-
-END_WORKERS_NAMESPACE
-
-#endif /* mozilla_dom_workers_url_h__ */
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -491,17 +491,17 @@ private:
 
 class CompileScriptRunnable final : public WorkerRunnable
 {
   nsString mScriptURL;
 
 public:
   explicit CompileScriptRunnable(WorkerPrivate* aWorkerPrivate,
                                  const nsAString& aScriptURL)
-  : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
+  : WorkerRunnable(aWorkerPrivate),
     mScriptURL(aScriptURL)
   { }
 
 private:
   // We can't implement PreRun effectively, because at the point when that would
   // run we have not yet done our load so don't know things like our final
   // principal and whatnot.
 
@@ -1082,17 +1082,17 @@ public:
         JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
         NS_ASSERTION(global, "This should never be null!");
 
         nsEventStatus status = nsEventStatus_eIgnore;
         nsIScriptGlobalObject* sgo;
 
         if (aWorkerPrivate) {
           WorkerGlobalScope* globalScope = nullptr;
-          UNWRAP_WORKER_OBJECT(WorkerGlobalScope, global, globalScope);
+          UNWRAP_OBJECT(WorkerGlobalScope, global, globalScope);
 
           if (!globalScope) {
             WorkerDebuggerGlobalScope* globalScope = nullptr;
             UNWRAP_OBJECT(WorkerDebuggerGlobalScope, global, globalScope);
 
             MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global);
             if (globalScope || IsDebuggerSandbox(global)) {
               aWorkerPrivate->ReportErrorToDebugger(aFilename, aLineNumber,
@@ -1487,17 +1487,17 @@ public:
 
 class UpdateLanguagesRunnable final : public WorkerRunnable
 {
   nsTArray<nsString> mLanguages;
 
 public:
   UpdateLanguagesRunnable(WorkerPrivate* aWorkerPrivate,
                           const nsTArray<nsString>& aLanguages)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
+    : WorkerRunnable(aWorkerPrivate),
       mLanguages(aLanguages)
   { }
 
   virtual bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
     aWorkerPrivate->UpdateLanguagesInternal(mLanguages);
     return true;
@@ -1604,17 +1604,17 @@ public:
     return true;
   }
 };
 
 class OfflineStatusChangeRunnable : public WorkerRunnable
 {
 public:
   OfflineStatusChangeRunnable(WorkerPrivate* aWorkerPrivate, bool aIsOffline)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
+    : WorkerRunnable(aWorkerPrivate),
       mIsOffline(aIsOffline)
   {
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     aWorkerPrivate->OfflineStatusChangeEventInternal(mIsOffline);
@@ -1718,19 +1718,18 @@ public:
   }
 };
 
 class MessagePortRunnable final : public WorkerRunnable
 {
   MessagePortIdentifier mPortIdentifier;
 
 public:
-  MessagePortRunnable(WorkerPrivate* aWorkerPrivate,
-                      MessagePort* aPort)
-  : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+  MessagePortRunnable(WorkerPrivate* aWorkerPrivate, MessagePort* aPort)
+  : WorkerRunnable(aWorkerPrivate)
   {
     MOZ_ASSERT(aPort);
     // In order to move the port from one thread to another one, we have to
     // close and disentangle it. The output will be a MessagePortIdentifier that
     // will be used to recreate a new MessagePort on the other thread.
     aPort->CloneAndDisentangle(mPortIdentifier);
   }
 
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -53,16 +53,18 @@ struct RuntimeStats;
 } // namespace JS
 
 namespace mozilla {
 namespace dom {
 class Function;
 class MessagePort;
 class MessagePortIdentifier;
 class StructuredCloneHolder;
+class WorkerDebuggerGlobalScope;
+class WorkerGlobalScope;
 } // namespace dom
 namespace ipc {
 class PrincipalInfo;
 } // namespace ipc
 } // namespace mozilla
 
 struct PRThread;
 
@@ -71,18 +73,16 @@ class PostDebuggerMessageRunnable;
 
 BEGIN_WORKERS_NAMESPACE
 
 class AutoSyncLoopHolder;
 class SharedWorker;
 class ServiceWorkerClientInfo;
 class WorkerControlRunnable;
 class WorkerDebugger;
-class WorkerDebuggerGlobalScope;
-class WorkerGlobalScope;
 class WorkerPrivate;
 class WorkerRunnable;
 class WorkerThread;
 
 // SharedMutex is a small wrapper around an (internal) reference-counted Mutex
 // object. It exists to avoid changing a lot of code to use Mutex* instead of
 // Mutex&.
 class SharedMutex
--- a/dom/workers/WorkerRunnable.h
+++ b/dom/workers/WorkerRunnable.h
@@ -86,17 +86,18 @@ public:
   {
     return mCanceled != 0;
   }
 
   static WorkerRunnable*
   FromRunnable(nsIRunnable* aRunnable);
 
 protected:
-  WorkerRunnable(WorkerPrivate* aWorkerPrivate, TargetAndBusyBehavior aBehavior)
+  WorkerRunnable(WorkerPrivate* aWorkerPrivate,
+                 TargetAndBusyBehavior aBehavior = WorkerThreadModifyBusyCount)
 #ifdef DEBUG
   ;
 #else
   : mWorkerPrivate(aWorkerPrivate), mBehavior(aBehavior), mCanceled(0),
     mCallingCancelWithinRun(false)
   { }
 #endif
 
@@ -270,17 +271,17 @@ private:
 // state of the JS runtime and should only twiddle state values. The busy count
 // is never modified.
 class WorkerControlRunnable : public WorkerRunnable
 {
   friend class WorkerPrivate;
 
 protected:
   WorkerControlRunnable(WorkerPrivate* aWorkerPrivate,
-                        TargetAndBusyBehavior aBehavior)
+                        TargetAndBusyBehavior aBehavior = WorkerThreadModifyBusyCount)
 #ifdef DEBUG
   ;
 #else
   : WorkerRunnable(aWorkerPrivate, aBehavior)
   { }
 #endif
 
   virtual ~WorkerControlRunnable()
@@ -295,17 +296,17 @@ public:
 private:
   virtual bool
   DispatchInternal() override;
 
   // Should only be called by WorkerPrivate::DoRunLoop.
   using WorkerRunnable::Cancel;
 };
 
-// A convenience class for WorkerRunnables that originate on the main
+// A convenience class for WorkerRunnables that are originated on the main
 // thread.
 class MainThreadWorkerRunnable : public WorkerRunnable
 {
 protected:
   explicit MainThreadWorkerRunnable(WorkerPrivate* aWorkerPrivate)
   : WorkerRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
   {
     AssertIsOnMainThread();
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -53,18 +53,16 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 USING_WORKERS_NAMESPACE
 
 using mozilla::dom::cache::CacheStorage;
 using mozilla::ipc::PrincipalInfo;
 
-BEGIN_WORKERS_NAMESPACE
-
 WorkerGlobalScope::WorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
 : mWindowInteractionsAllowed(0)
 , mWorkerPrivate(aWorkerPrivate)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
 }
 
 WorkerGlobalScope::~WorkerGlobalScope()
@@ -484,20 +482,20 @@ DedicatedWorkerGlobalScope::WrapGlobalOb
 
   const bool inCertifiedApp = mWorkerPrivate->IsInCertifiedApp();
   const bool sharedMemoryEnabled = xpc::SharedMemoryEnabled();
 
   JS::CompartmentCreationOptions& creationOptions = options.creationOptions();
   creationOptions.setSharedMemoryAndAtomicsEnabled(sharedMemoryEnabled)
                  .setExperimentalDateTimeFormatFormatToPartsEnabled(inCertifiedApp);
 
-  return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
-                                                         options,
-                                                         GetWorkerPrincipal(),
-                                                         true, aReflector);
+  return DedicatedWorkerGlobalScopeBinding::Wrap(aCx, this, this,
+                                                 options,
+                                                 GetWorkerPrincipal(),
+                                                 true, aReflector);
 }
 
 void
 DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
                                         JS::Handle<JS::Value> aMessage,
                                         const Optional<Sequence<JS::Value>>& aTransferable,
                                         ErrorResult& aRv)
 {
@@ -516,19 +514,19 @@ SharedWorkerGlobalScope::WrapGlobalObjec
                                           JS::MutableHandle<JSObject*> aReflector)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
-  return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
-                                                      GetWorkerPrincipal(),
-                                                      true, aReflector);
+  return SharedWorkerGlobalScopeBinding::Wrap(aCx, this, this, options,
+                                              GetWorkerPrincipal(),
+                                              true, aReflector);
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope,
                                    mClients, mRegistration)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope)
 NS_INTERFACE_MAP_END_INHERITING(WorkerGlobalScope)
 
 NS_IMPL_ADDREF_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope)
@@ -550,19 +548,19 @@ ServiceWorkerGlobalScope::WrapGlobalObje
                                            JS::MutableHandle<JSObject*> aReflector)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
-  return ServiceWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
-                                                       GetWorkerPrincipal(),
-                                                       true, aReflector);
+  return ServiceWorkerGlobalScopeBinding::Wrap(aCx, this, this, options,
+                                               GetWorkerPrincipal(),
+                                               true, aReflector);
 }
 
 ServiceWorkerClients*
 ServiceWorkerGlobalScope::Clients()
 {
   if (!mClients) {
     mClients = new ServiceWorkerClients(this);
   }
@@ -585,17 +583,17 @@ namespace {
 
 class SkipWaitingResultRunnable final : public WorkerRunnable
 {
   RefPtr<PromiseWorkerProxy> mPromiseProxy;
 
 public:
   SkipWaitingResultRunnable(WorkerPrivate* aWorkerPrivate,
                             PromiseWorkerProxy* aPromiseProxy)
-    : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
+    : WorkerRunnable(aWorkerPrivate)
     , mPromiseProxy(aPromiseProxy)
   {
     AssertIsOnMainThread();
   }
 
   virtual bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
@@ -901,22 +899,24 @@ WorkerDebuggerGlobalScope::Dump(JSContex
                                 const Optional<nsAString>& aString) const
 {
   WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
   if (scope) {
     scope->Dump(aString);
   }
 }
 
+BEGIN_WORKERS_NAMESPACE
+
 bool
 IsWorkerGlobal(JSObject* object)
 {
   nsIGlobalObject* globalObject = nullptr;
-  return NS_SUCCEEDED(UNWRAP_WORKER_OBJECT(WorkerGlobalScope, object,
-                                           globalObject)) && !!globalObject;
+  return NS_SUCCEEDED(UNWRAP_OBJECT(WorkerGlobalScope, object,
+                                    globalObject)) && !!globalObject;
 }
 
 bool
 IsDebuggerGlobal(JSObject* object)
 {
   nsIGlobalObject* globalObject = nullptr;
   return NS_SUCCEEDED(UNWRAP_OBJECT(WorkerDebuggerGlobalScope, object,
                                     globalObject)) && !!globalObject;
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -31,24 +31,24 @@ class ServiceWorkerRegistration;
 class WorkerLocation;
 class WorkerNavigator;
 
 namespace cache {
 
 class CacheStorage;
 
 } // namespace cache
-} // namespace dom
-} // namespace mozilla
 
-BEGIN_WORKERS_NAMESPACE
+namespace workers {
 
 class ServiceWorkerClients;
 class WorkerPrivate;
 
+} // namespace workers
+
 class WorkerGlobalScope : public DOMEventTargetHelper,
                           public nsIGlobalObject,
                           public nsSupportsWeakReference
 {
   typedef mozilla::dom::IDBFactory IDBFactory;
 
   RefPtr<Console> mConsole;
   RefPtr<Crypto> mCrypto;
@@ -56,16 +56,17 @@ class WorkerGlobalScope : public DOMEven
   RefPtr<WorkerNavigator> mNavigator;
   RefPtr<Performance> mPerformance;
   RefPtr<IDBFactory> mIndexedDB;
   RefPtr<cache::CacheStorage> mCacheStorage;
 
   uint32_t mWindowInteractionsAllowed;
 
 protected:
+  typedef mozilla::dom::workers::WorkerPrivate WorkerPrivate;
   WorkerPrivate* mWorkerPrivate;
 
   explicit WorkerGlobalScope(WorkerPrivate* aWorkerPrivate);
   virtual ~WorkerGlobalScope();
 
 public:
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -237,17 +238,17 @@ public:
   }
 
   IMPL_EVENT_HANDLER(connect)
 };
 
 class ServiceWorkerGlobalScope final : public WorkerGlobalScope
 {
   const nsString mScope;
-  RefPtr<ServiceWorkerClients> mClients;
+  RefPtr<workers::ServiceWorkerClients> mClients;
   RefPtr<ServiceWorkerRegistration> mRegistration;
 
   ~ServiceWorkerGlobalScope();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
                                            WorkerGlobalScope)
@@ -264,17 +265,17 @@ public:
   OpenWindowEnabled(JSContext* aCx, JSObject* aObj);
 
   void
   GetScope(nsString& aScope) const
   {
     aScope = mScope;
   }
 
-  ServiceWorkerClients*
+  workers::ServiceWorkerClients*
   Clients();
 
   ServiceWorkerRegistration*
   Registration();
 
   already_AddRefed<Promise>
   SkipWaiting(ErrorResult& aRv);
 
@@ -286,16 +287,18 @@ public:
   IMPL_EVENT_HANDLER(push)
   IMPL_EVENT_HANDLER(pushsubscriptionchange)
 
 };
 
 class WorkerDebuggerGlobalScope final : public DOMEventTargetHelper,
                                         public nsIGlobalObject
 {
+  typedef mozilla::dom::workers::WorkerPrivate WorkerPrivate;
+
   WorkerPrivate* mWorkerPrivate;
   RefPtr<Console> mConsole;
 
 public:
   explicit WorkerDebuggerGlobalScope(WorkerPrivate* aWorkerPrivate);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerDebuggerGlobalScope,
@@ -368,17 +371,18 @@ public:
 
   void
   Dump(JSContext* aCx, const Optional<nsAString>& aString) const;
 
 private:
   virtual ~WorkerDebuggerGlobalScope();
 };
 
-END_WORKERS_NAMESPACE
+} // namespace dom
+} // namespace mozilla
 
 inline nsISupports*
-ToSupports(mozilla::dom::workers::WorkerGlobalScope* aScope)
+ToSupports(mozilla::dom::WorkerGlobalScope* aScope)
 {
   return static_cast<nsIDOMEventTarget*>(aScope);
 }
 
 #endif /* mozilla_dom_workerscope_h__ */
--- a/dom/workers/moz.build
+++ b/dom/workers/moz.build
@@ -32,17 +32,16 @@ EXPORTS.mozilla.dom.workers += [
 
 # Stuff needed for the bindings, not really public though.
 EXPORTS.mozilla.dom.workers.bindings += [
     'ServiceWorker.h',
     'ServiceWorkerClient.h',
     'ServiceWorkerClients.h',
     'ServiceWorkerWindowClient.h',
     'SharedWorker.h',
-    'URL.h',
     'WorkerHolder.h',
 ]
 
 XPIDL_MODULE = 'dom_workers'
 
 XPIDL_SOURCES += [
     'nsIWorkerDebugger.idl',
     'nsIWorkerDebuggerManager.idl',
@@ -73,17 +72,16 @@ UNIFIED_SOURCES += [
     'ServiceWorkerRegistrar.cpp',
     'ServiceWorkerRegistration.cpp',
     'ServiceWorkerRegistrationInfo.cpp',
     'ServiceWorkerScriptCache.cpp',
     'ServiceWorkerUnregisterJob.cpp',
     'ServiceWorkerUpdateJob.cpp',
     'ServiceWorkerWindowClient.cpp',
     'SharedWorker.cpp',
-    'URL.cpp',
     'WorkerDebuggerManager.cpp',
     'WorkerHolder.cpp',
     'WorkerLocation.cpp',
     'WorkerNavigator.cpp',
     'WorkerPrivate.cpp',
     'WorkerRunnable.cpp',
     'WorkerScope.cpp',
     'WorkerThread.cpp',
--- a/dom/workers/test/chrome.ini
+++ b/dom/workers/test/chrome.ini
@@ -45,45 +45,40 @@ support-files =
   fileBlobSubWorker_worker.js
   fileBlob_worker.js
   filePosting_worker.js
   fileReadSlice_worker.js
   fileReaderSyncErrors_worker.js
   fileReaderSync_worker.js
   fileSlice_worker.js
   fileSubWorker_worker.js
-  file_url.jsm
   file_worker.js
-  jsm_url_worker.js
   sharedWorker_privateBrowsing.js
-  test_bug883784.jsm
   workersDisabled_worker.js
 
 [test_WorkerDebugger.initialize.xul]
 [test_WorkerDebugger.postMessage.xul]
 [test_WorkerDebugger.xul]
 [test_WorkerDebuggerGlobalScope.createSandbox.xul]
 [test_WorkerDebuggerGlobalScope.enterEventLoop.xul]
 [test_WorkerDebuggerGlobalScope.reportError.xul]
 [test_WorkerDebuggerGlobalScope.setImmediate.xul]
 [test_WorkerDebuggerManager.xul]
 [test_WorkerDebugger_console.xul]
 [test_WorkerDebugger_frozen.xul]
 [test_WorkerDebugger_promise.xul]
 [test_WorkerDebugger_suspended.xul]
-[test_bug883784.xul]
 [test_chromeWorker.xul]
 [test_chromeWorkerJSM.xul]
 [test_extension.xul]
 [test_extensionBootstrap.xul]
 [test_file.xul]
 [test_fileBlobPosting.xul]
 [test_fileBlobSubWorker.xul]
 [test_filePosting.xul]
 [test_fileReadSlice.xul]
 [test_fileReaderSync.xul]
 [test_fileReaderSyncErrors.xul]
 [test_fileSlice.xul]
 [test_fileSubWorker.xul]
 [test_workersDisabled.xul]
-[test_url.xul]
 [test_bug1062920.xul]
 [test_sharedWorker_privateBrowsing.html]
--- a/dom/workers/test/mochitest.ini
+++ b/dom/workers/test/mochitest.ini
@@ -67,29 +67,25 @@ support-files =
   threadErrors_worker1.js
   threadErrors_worker2.js
   threadErrors_worker3.js
   threadErrors_worker4.js
   threadTimeouts_worker.js
   throwingOnerror_worker.js
   timeoutTracing_worker.js
   transferable_worker.js
-  urlApi_worker.js
-  url_worker.js
   websocket_basic_worker.js
   websocket_loadgroup_worker.js
   websocket_worker1.js
   websocket_worker2.js
   websocket_worker3.js
   websocket_worker4.js
   websocket_worker5.js
   websocket_helpers.js
   workersDisabled_worker.js
-  url_exceptions_worker.js
-  urlSearchParams_worker.js
   test_worker_interfaces.js
   worker_driver.js
   worker_wrapper.js
   bug1060621_worker.js
   bug1062920_worker.js
   webSocket_sharedWorker.js
   bug1104064_worker.js
   worker_consoleAndBlobs.js
@@ -198,20 +194,16 @@ skip-if = (toolkit == 'gonk' && debug) #
 [test_simpleThread.html]
 [test_suspend.html]
 [test_terminate.html]
 [test_threadErrors.html]
 [test_threadTimeouts.html]
 [test_throwingOnerror.html]
 [test_timeoutTracing.html]
 [test_transferable.html]
-[test_url.html]
-[test_url_exceptions.html]
-[test_urlApi.html]
-[test_urlSearchParams.html]
 [test_websocket1.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
 [test_websocket2.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
 [test_websocket3.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
 [test_websocket4.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -923,17 +923,17 @@ nsXMLContentSink::HandleStartElement(con
 
   nsresult result = NS_OK;
   bool appendContent = true;
   nsCOMPtr<nsIContent> content;
 
   // XXX Hopefully the parser will flag this before we get
   // here. If we're in the epilog, there should be no
   // new elements
-  PR_ASSERT(eXMLContentSinkState_InEpilog != mState);
+  MOZ_ASSERT(eXMLContentSinkState_InEpilog != mState);
 
   FlushText();
   DidAddContent();
 
   mState = eXMLContentSinkState_InDocumentElement;
 
   int32_t nameSpaceID;
   nsCOMPtr<nsIAtom> prefix, localName;
@@ -1016,17 +1016,17 @@ nsresult
 nsXMLContentSink::HandleEndElement(const char16_t *aName,
                                    bool aInterruptable)
 {
   nsresult result = NS_OK;
 
   // XXX Hopefully the parser will flag this before we get
   // here. If we're in the prolog or epilog, there should be
   // no close tags for elements.
-  PR_ASSERT(eXMLContentSinkState_InDocumentElement == mState);
+  MOZ_ASSERT(eXMLContentSinkState_InDocumentElement == mState);
 
   FlushText();
 
   StackNode* sn = GetCurrentStackNode();
   if (!sn) {
     return NS_ERROR_UNEXPECTED;
   }
 
--- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -1466,43 +1466,31 @@ nsresult nsWebBrowserPersist::SaveChanne
     // The default behaviour of SaveChannelInternal is to download the source
     // into a storage stream and upload that to the target. MakeOutputStream
     // special-cases a file target and creates a file output stream directly.
     // We want to special-case a file source and create a file input stream,
     // but we don't need to do this in the case of a file target.
     nsCOMPtr<nsIFileChannel> fc(do_QueryInterface(aChannel));
     nsCOMPtr<nsIFileURL> fu(do_QueryInterface(aFile));
 
-    nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
     if (fc && !fu) {
         nsCOMPtr<nsIInputStream> fileInputStream, bufferedInputStream;
-        nsresult rv;
-        if (loadInfo && loadInfo->GetSecurityMode()) {
-          rv = aChannel->Open2(getter_AddRefs(fileInputStream));
-        }
-        else {
-          rv = aChannel->Open(getter_AddRefs(fileInputStream));
-        }
+        nsresult rv = NS_MaybeOpenChannelUsingOpen2(aChannel,
+                        getter_AddRefs(fileInputStream));
         NS_ENSURE_SUCCESS(rv, rv);
         rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedInputStream),
                                        fileInputStream, BUFFERED_OUTPUT_SIZE);
         NS_ENSURE_SUCCESS(rv, rv);
         nsAutoCString contentType;
         aChannel->GetContentType(contentType);
         return StartUpload(bufferedInputStream, aFile, contentType);
     }
 
     // Read from the input channel
-    nsresult rv;
-    if (loadInfo && loadInfo->GetSecurityMode()) {
-        rv = aChannel->AsyncOpen2(this);
-    }
-    else {
-        rv = aChannel->AsyncOpen(this, nullptr);
-    }
+    nsresult rv = NS_MaybeOpenChannelUsingAsyncOpen2(aChannel, this);
     if (rv == NS_ERROR_NO_CONTENT)
     {
         // Assume this is a protocol such as mailto: which does not feed out
         // data and just ignore it.
         return NS_SUCCESS_DONT_FIXUP;
     }
 
     if (NS_FAILED(rv))
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -3578,16 +3578,17 @@ DiffuseLightingSoftware::LightPixel(cons
     umin(uint32_t(diffuseNL * color.components[B8G8R8A8_COMPONENT_BYTEOFFSET_R]), 255U);
   color.components[B8G8R8A8_COMPONENT_BYTEOFFSET_A] = 255;
   return color.bgra;
 }
 
 SpecularLightingSoftware::SpecularLightingSoftware()
  : mSpecularConstant(0)
  , mSpecularExponent(0)
+ , mSpecularConstantInt(0)
 {
 }
 
 bool
 SpecularLightingSoftware::SetAttribute(uint32_t aIndex, Float aValue)
 {
   switch (aIndex) {
     case ATT_SPECULAR_LIGHTING_SPECULAR_CONSTANT:
--- a/gfx/cairo/libpixman/src/moz.build
+++ b/gfx/cairo/libpixman/src/moz.build
@@ -19,16 +19,20 @@ if CONFIG['OS_ARCH'] != 'Darwin' and CON
             'pixman-arm-neon-asm-bilinear.S',
             'pixman-arm-neon-asm.S',
         ]
     if CONFIG['HAVE_ARM_SIMD']:
         SOURCES += [
             'pixman-arm-simd-asm-scaled.S',
             'pixman-arm-simd-asm.S',
         ]
+    if CONFIG['CLANG_CXX']:
+        ASFLAGS += [
+            '-no-integrated-as',
+        ]
 
 SOURCES += [
     'pixman-access-accessors.c',
     'pixman-access.c',
     'pixman-arm.c',
     'pixman-bits-image.c',
     'pixman-combine-float.c',
     'pixman-combine16.c',
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -170,16 +170,21 @@ GLXLibrary::EnsureInitialized()
     };
 
     GLLibraryLoader::SymLoadStruct symbols_videosync[] = {
       { (PRFuncPtr*) &xGetVideoSyncInternal, { "glXGetVideoSyncSGI", nullptr } },
       { (PRFuncPtr*) &xWaitVideoSyncInternal, { "glXWaitVideoSyncSGI", nullptr } },
       { nullptr, { nullptr } }
     };
 
+    GLLibraryLoader::SymLoadStruct symbols_swapcontrol[] = {
+      { (PRFuncPtr*) &xSwapIntervalInternal, { "glXSwapIntervalEXT", nullptr } },
+      { nullptr, { nullptr } }
+    };
+
     if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return false;
     }
 
     Display* display = DefaultXDisplay();
     int screen = DefaultScreen(display);
 
@@ -254,16 +259,22 @@ GLXLibrary::EnsureInitialized()
 
     if (HasExtension(extensionsStr, "GLX_SGI_video_sync") &&
         GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_videosync,
                                      (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
     {
         mHasVideoSync = true;
     }
 
+    if (!(HasExtension(extensionsStr, "GLX_EXT_swap_control") &&
+          GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_swapcontrol)))
+    {
+        NS_WARNING("GLX_swap_control unsupported, ASAP mode may still block on buffer swaps.");
+    }
+
     mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
     mIsNVIDIA = serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation");
     mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa");
 
     mInitialized = true;
 
     return true;
 }
@@ -773,16 +784,24 @@ int
 GLXLibrary::xWaitVideoSync(int divisor, int remainder, unsigned int* count)
 {
     BEFORE_GLX_CALL;
     int result = xWaitVideoSyncInternal(divisor, remainder, count);
     AFTER_GLX_CALL;
     return result;
 }
 
+void
+GLXLibrary::xSwapInterval(Display* display, GLXDrawable drawable, int interval)
+{
+    BEFORE_GLX_CALL;
+    xSwapIntervalInternal(display, drawable, interval);
+    AFTER_GLX_CALL;
+}
+
 already_AddRefed<GLContextGLX>
 GLContextGLX::CreateGLContext(CreateContextFlags flags, const SurfaceCaps& caps,
                               GLContextGLX* shareContext, bool isOffscreen,
                               Display* display, GLXDrawable drawable, GLXFBConfig cfg,
                               bool deleteDrawable, gfxXlibSurface* pixmap,
                               ContextProfile profile)
 {
     GLXLibrary& glx = sGLXLibrary;
@@ -918,16 +937,24 @@ GLContextGLX::MakeCurrentImpl(bool aForc
     // (This is not the case with other drivers such as NVIDIA).
     // So avoid calling it more than necessary. Since GLX documentation says that:
     //     "glXGetCurrentContext returns client-side information.
     //      It does not make a round trip to the server."
     // I assume that it's not worth using our own TLS slot here.
     if (aForce || mGLX->xGetCurrentContext() != mContext) {
         succeeded = mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
         NS_ASSERTION(succeeded, "Failed to make GL context current!");
+
+        if (!IsOffscreen() && mGLX->SupportsSwapControl()) {
+            // Many GLX implementations default to blocking until the next
+            // VBlank when calling glXSwapBuffers. We want to run unthrottled
+            // in ASAP mode. See bug 1280744.
+            int interval = gfxPlatform::IsInLayoutAsapMode() ? 0 : 1;
+            mGLX->xSwapInterval(mDisplay, mDrawable, interval);
+        }
     }
 
     return succeeded;
 }
 
 bool
 GLContextGLX::IsCurrent() {
     return mGLX->xGetCurrentContext() == mContext;
--- a/gfx/gl/GLXLibrary.h
+++ b/gfx/gl/GLXLibrary.h
@@ -51,16 +51,17 @@ public:
     , xQueryVersionInternal(nullptr)
     , xBindTexImageInternal(nullptr)
     , xReleaseTexImageInternal(nullptr)
     , xWaitGLInternal(nullptr)
     , xWaitXInternal(nullptr)
     , xCreateContextAttribsInternal(nullptr)
     , xGetVideoSyncInternal(nullptr)
     , xWaitVideoSyncInternal(nullptr)
+    , xSwapIntervalInternal(nullptr)
     , mInitialized(false), mTriedInitializing(false)
     , mUseTextureFromPixmap(false), mDebug(false)
     , mHasRobustness(false), mHasCreateContextAttribs(false)
     , mHasVideoSync(false)
     , mIsATI(false), mIsNVIDIA(false)
     , mClientIsMesa(false), mGLXMajorVersion(0)
     , mGLXMinorVersion(0)
     , mOGLLibrary(nullptr)
@@ -120,30 +121,32 @@ public:
     GLXContext xCreateContextAttribs(Display* display,
                                      GLXFBConfig config,
                                      GLXContext share_list,
                                      Bool direct,
                                      const int* attrib_list);
 
     int xGetVideoSync(unsigned int* count);
     int xWaitVideoSync(int divisor, int remainder, unsigned int* count);
+    void xSwapInterval(Display* dpy, GLXDrawable drawable, int interval);
 
     bool EnsureInitialized();
 
     GLXPixmap CreatePixmap(gfxASurface* aSurface);
     void DestroyPixmap(Display* aDisplay, GLXPixmap aPixmap);
     void BindTexImage(Display* aDisplay, GLXPixmap aPixmap);
     void ReleaseTexImage(Display* aDisplay, GLXPixmap aPixmap);
     void UpdateTexImage(Display* aDisplay, GLXPixmap aPixmap);
 
     bool UseTextureFromPixmap() { return mUseTextureFromPixmap; }
     bool HasRobustness() { return mHasRobustness; }
     bool HasCreateContextAttribs() { return mHasCreateContextAttribs; }
     bool SupportsTextureFromPixmap(gfxASurface* aSurface);
     bool SupportsVideoSync();
+    bool SupportsSwapControl() const { return bool(xSwapIntervalInternal); }
     bool IsATI() { return mIsATI; }
     bool GLXVersionCheck(int aMajor, int aMinor);
 
 private:
 
     typedef void (GLAPIENTRY * PFNGLXDESTROYCONTEXTPROC) (Display*,
                                                           GLXContext);
     PFNGLXDESTROYCONTEXTPROC xDestroyContextInternal;
@@ -233,16 +236,19 @@ private:
     PFNGLXCREATECONTEXTATTRIBS xCreateContextAttribsInternal;
 
     typedef int (GLAPIENTRY * PFNGLXGETVIDEOSYNCSGI) (unsigned int* count);
     PFNGLXGETVIDEOSYNCSGI xGetVideoSyncInternal;
 
     typedef int (GLAPIENTRY * PFNGLXWAITVIDEOSYNCSGI) (int divisor, int remainder, unsigned int* count);
     PFNGLXWAITVIDEOSYNCSGI xWaitVideoSyncInternal;
 
+    typedef void (GLAPIENTRY * PFNGLXSWAPINTERVALEXT) (Display* dpy, GLXDrawable drawable, int interval);
+    PFNGLXSWAPINTERVALEXT xSwapIntervalInternal;
+
 #ifdef DEBUG
     void BeforeGLXCall();
     void AfterGLXCall();
 #endif
 
     bool mInitialized;
     bool mTriedInitializing;
     bool mUseTextureFromPixmap;
--- a/gfx/ipc/CompositorSession.cpp
+++ b/gfx/ipc/CompositorSession.cpp
@@ -104,18 +104,19 @@ already_AddRefed<APZCTreeManager>
 InProcessCompositorSession::GetAPZCTreeManager() const
 {
   return mCompositorBridgeParent->GetAPZCTreeManager(RootLayerTreeId());
 }
 
 void
 InProcessCompositorSession::Shutdown()
 {
-  // XXX CompositorBridgeChild and CompositorBridgeParent might be re-created in
-  // ClientLayerManager destructor. See bug 1133426.
-  RefPtr<CompositorBridgeChild> compositorChild = mCompositorBridgeChild;
-  RefPtr<CompositorBridgeParent> compositorParent = mCompositorBridgeParent;
+  // Destroy will synchronously wait for the parent to acknowledge shutdown,
+  // at which point CBP will defer a Release on the compositor thread. We
+  // can safely release our reference now, and let the destructor run on either
+  // thread.
   mCompositorBridgeChild->Destroy();
   mCompositorBridgeChild = nullptr;
+  mCompositorBridgeParent = nullptr;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/D3D11ShareHandleImage.h
+++ b/gfx/layers/D3D11ShareHandleImage.h
@@ -14,17 +14,17 @@
 #include "mozilla/layers/TextureClientRecycleAllocator.h"
 
 namespace mozilla {
 namespace layers {
 
 class D3D11RecycleAllocator : public TextureClientRecycleAllocator
 {
 public:
-  explicit D3D11RecycleAllocator(TextureForwarder* aAllocator,
+  explicit D3D11RecycleAllocator(CompositableForwarder* aAllocator,
                                  ID3D11Device* aDevice)
     : TextureClientRecycleAllocator(aAllocator)
     , mDevice(aDevice)
   {}
 
   already_AddRefed<TextureClient>
   CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                         const gfx::IntSize& aSize);
--- a/gfx/layers/D3D9SurfaceImage.h
+++ b/gfx/layers/D3D9SurfaceImage.h
@@ -14,17 +14,17 @@
 namespace mozilla {
 namespace layers {
 
 class TextureClient;
 
 class D3D9RecycleAllocator : public TextureClientRecycleAllocator
 {
 public:
-  explicit D3D9RecycleAllocator(TextureForwarder* aAllocator,
+  explicit D3D9RecycleAllocator(CompositableForwarder* aAllocator,
                                 IDirect3DDevice9* aDevice)
     : TextureClientRecycleAllocator(aAllocator)
     , mDevice(aDevice)
   {}
 
   already_AddRefed<TextureClient>
   CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                         const gfx::IntSize& aSize);
--- a/gfx/layers/TextureDIB.cpp
+++ b/gfx/layers/TextureDIB.cpp
@@ -276,17 +276,17 @@ ShmemDIBTextureData::Serialize(SurfaceDe
   aOutDescriptor = SurfaceDescriptorFileMapping((WindowsHandle)mHostHandle, mFormat, mSize);
   return true;
 }
 
 DIBTextureData*
 ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                             ClientIPCAllocator* aAllocator)
 {
-  MOZ_ASSERT(aAllocator->AsLayerForwarder()->GetParentPid() != base::ProcessId());
+  MOZ_ASSERT(aAllocator->GetParentPid() != base::ProcessId());
 
   DWORD mapSize = aSize.width * aSize.height * BytesPerPixel(aFormat);
   HANDLE fileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, NULL);
 
   if (!fileMapping) {
     gfxCriticalError() << "Failed to create memory file mapping for " << mapSize << " bytes.";
     return nullptr;
   }
@@ -338,17 +338,17 @@ ShmemDIBTextureData::Create(gfx::IntSize
     ::CloseHandle(fileMapping);
     gfxCriticalError() << "Could not create surface, status: "
                        << surface->CairoStatus();
     return nullptr;
   }
 
   HANDLE hostHandle = NULL;
 
-  if (!ipc::DuplicateHandle(fileMapping, aAllocator->AsLayerForwarder()->GetParentPid(),
+  if (!ipc::DuplicateHandle(fileMapping, aAllocator->GetParentPid(),
                             &hostHandle, 0, DUPLICATE_SAME_ACCESS)) {
     gfxCriticalError() << "Failed to duplicate handle to parent process for surface.";
     ::DeleteObject(bitmap);
     ::DeleteDC(dc);
     ::CloseHandle(fileMapping);
     return nullptr;
   }
 
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -6,16 +6,17 @@
 #include "mozilla/layers/CompositableClient.h"
 #include <stdint.h>                     // for uint64_t, uint32_t
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
 #include "mozilla/layers/TextureClientOGL.h"
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "mozilla/layers/PCompositableChild.h"
+#include "mozilla/layers/TextureClientRecycleAllocator.h"
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"         // for gfxWindowsPlatform
 #include "mozilla/layers/TextureD3D11.h"
 #include "mozilla/layers/TextureD3D9.h"
 #endif
 #include "gfxUtils.h"
 #include "IPDLActor.h"
 
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -11,28 +11,28 @@
 #include <map>                          // for map
 #include "mozilla/Assertions.h"         // for MOZ_CRASH
 #include "mozilla/RefPtr.h"             // for already_AddRefed, RefCounted
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
 #include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend, TextureDumpMode
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
-#include "mozilla/layers/TextureClientRecycleAllocator.h" // for TextureClientRecycleAllocator
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 
 namespace mozilla {
 namespace layers {
 
 class CompositableClient;
 class ImageBridgeChild;
 class ImageContainer;
 class CompositableForwarder;
 class CompositableChild;
 class PCompositableChild;
+class TextureClientRecycleAllocator;
 
 /**
  * Handle RemoveTextureFromCompositableAsync() transaction.
  */
 class RemoveTextureFromCompositableTracker : public AsyncTransactionTracker {
 public:
   explicit RemoveTextureFromCompositableTracker(AsyncTransactionWaiter* aWaiter = nullptr)
     : AsyncTransactionTracker(aWaiter)
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -98,40 +98,37 @@ class TextureChild final : public ChildA
   {
     // We should have deallocated mTextureData in ActorDestroy
     MOZ_ASSERT(!mTextureData);
   }
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureChild)
 
   TextureChild()
-  : mForwarder(nullptr)
+  : mCompositableForwarder(nullptr)
   , mTextureForwarder(nullptr)
   , mTextureClient(nullptr)
   , mTextureData(nullptr)
   , mDestroyed(false)
   , mMainThreadOnly(false)
   , mIPCOpen(false)
   , mOwnsTextureData(false)
   {}
 
   bool Recv__delete__() override { return true; }
 
-  CompositableForwarder* GetForwarder() { return mForwarder; }
-  TextureForwarder* GetTextureForwarder() { return mTextureForwarder; }
-
   ClientIPCAllocator* GetAllocator() { return mTextureForwarder; }
 
   void ActorDestroy(ActorDestroyReason why) override;
 
   bool IPCOpen() const { return mIPCOpen; }
 
-  void Lock() const { if (mForwarder->UsesImageBridge()) { mLock.Enter(); } }
+  void Lock() const { if (mCompositableForwarder->UsesImageBridge()) { mLock.Enter(); } }
 
-  void Unlock() const { if (mForwarder->UsesImageBridge()) { mLock.Leave(); } }
+  void Unlock() const { if (mCompositableForwarder->UsesImageBridge()) { mLock.Leave(); } }
 
 private:
 
   // AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor
   // and DestroyIPDLActor, respectively. We intentionally make them private to prevent misuse.
   // The purpose of these methods is to be aware of when the IPC system around this
   // actor goes down: mIPCOpen is then set to false.
   void AddIPDLReference() {
@@ -205,17 +202,17 @@ private:
   // B into A. For example A and B can be the Front and Back buffers, alternating
   // roles and the copy is needed to avoid the cost of re-drawing the valid
   // region.
   //
   // The important rule is that all of the dependent locking must occur only
   // in the texture's producer thread to avoid deadlocks.
   mutable gfx::CriticalSection mLock;
 
-  RefPtr<CompositableForwarder> mForwarder;
+  RefPtr<CompositableForwarder> mCompositableForwarder;
   RefPtr<TextureForwarder> mTextureForwarder;
 
   TextureClient* mTextureClient;
   TextureData* mTextureData;
   Atomic<bool> mDestroyed;
   bool mMainThreadOnly;
   bool mIPCOpen;
   bool mOwnsTextureData;
@@ -345,23 +342,23 @@ DeallocateTextureClient(TextureDeallocPa
     // race causing this function to be called concurrently which is bad!
     gfxCriticalError() << "Racy texture deallocation";
     return;
   }
 
   if (params.syncDeallocation) {
     MOZ_PERFORMANCE_WARNING("gfx",
       "TextureClient/Host pair requires synchronous deallocation");
-    actor->DestroySynchronously(actor->GetForwarder());
+    actor->DestroySynchronously(actor->mCompositableForwarder);
     DestroyTextureData(params.data, params.allocator, params.clientDeallocation,
                        actor->mMainThreadOnly);
   } else {
     actor->mTextureData = params.data;
     actor->mOwnsTextureData = params.clientDeallocation;
-    actor->Destroy(actor->GetForwarder());
+    actor->Destroy(actor->mCompositableForwarder);
     // DestroyTextureData will be called by TextureChild::ActorDestroy
   }
 }
 
 void TextureClient::Destroy(bool aForceSync)
 {
   if (mActor) {
     mActor->Lock();
@@ -864,34 +861,50 @@ TextureClient::SetRecycleAllocator(IText
   }
 }
 
 bool
 TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
 {
   MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->AsClientAllocator()->GetMessageLoop());
   if (mActor && !mActor->mDestroyed) {
-    if (mActor->GetForwarder() != aForwarder) {
-      mActor->mForwarder = aForwarder;
+    CompositableForwarder* currentFwd = mActor->mCompositableForwarder;
+    TextureForwarder* currentTexFwd = mActor->mTextureForwarder;
+    if (currentFwd != aForwarder) {
+      // It's a bit iffy but right now ShadowLayerForwarder inherits TextureForwarder
+      // even though it should not. ShadowLayerForwarder::AsTextureForwarder actually
+      // returns a pointer to the CompositorBridgeChild.
+      // It's Ok for a texture to move from a ShadowLayerForwarder to another, but
+      // not form a CompositorBridgeChild to another (they use different channels).
+      if (currentTexFwd && currentTexFwd != aForwarder->AsTextureForwarder()) {
+        gfxCriticalError() << "Attempt to move a texture to a different channel.";
+        return false;
+      }
+      if (currentFwd && currentFwd->GetCompositorBackendType() != aForwarder->GetCompositorBackendType()) {
+        gfxCriticalError() << "Attempt to move a texture to different compositor backend.";
+        return false;
+      }
+      mActor->mCompositableForwarder = aForwarder;
     }
     return true;
   }
   MOZ_ASSERT(!mActor || mActor->mDestroyed, "Cannot use a texture on several IPC channels.");
 
   SurfaceDescriptor desc;
   if (!ToSurfaceDescriptor(desc)) {
     return false;
   }
 
   mActor = static_cast<TextureChild*>(aForwarder->CreateTexture(desc,
                                                                 aForwarder->GetCompositorBackendType(),
                                                                 GetFlags(),
                                                                 mSerial));
   MOZ_ASSERT(mActor);
-  mActor->mForwarder = aForwarder;
+  mActor->mCompositableForwarder = aForwarder;
+  mActor->mTextureForwarder = aForwarder->AsTextureForwarder();
   mActor->mTextureClient = this;
   mActor->mMainThreadOnly = !!(mFlags & TextureFlags::DEALLOCATE_MAIN_THREAD);
 
   // If the TextureClient is already locked, we have to lock TextureChild's mutex
   // since it will be unlocked in TextureClient::Unlock.
   if (mIsLocked) {
     LockActor();
   }
@@ -916,54 +929,80 @@ BackendTypeForBackendSelector(LayersBack
     default:
       MOZ_ASSERT_UNREACHABLE("Unknown backend selector");
       return gfx::BackendType::NONE;
   }
 };
 
 // static
 already_AddRefed<TextureClient>
-TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
+TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
                                 gfx::SurfaceFormat aFormat,
                                 gfx::IntSize aSize,
                                 BackendSelector aSelector,
                                 TextureFlags aTextureFlags,
                                 TextureAllocationFlags aAllocFlags)
 {
+  LayersBackend layersBackend = aAllocator->GetCompositorBackendType();
+  return TextureClient::CreateForDrawing(aAllocator->AsTextureForwarder(),
+                                         aFormat, aSize,
+                                         layersBackend,
+                                         aSelector,
+                                         aTextureFlags,
+                                         aAllocFlags);
+}
+
+// static
+already_AddRefed<TextureClient>
+TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
+                                gfx::SurfaceFormat aFormat,
+                                gfx::IntSize aSize,
+                                LayersBackend aLayersBackend,
+                                BackendSelector aSelector,
+                                TextureFlags aTextureFlags,
+                                TextureAllocationFlags aAllocFlags)
+{
+  // What we want here is the "real" TextureForwarder. ShadowLayerForwarder,
+  // while inheriting TextureForwarder, actually forwards all of its TF methods
+  // to CompositorBridgeChild. In order to avoid odd situations where some
+  // textures point to a ShadowLayerForwarder and some point directly to the
+  // CompositorBridgeChild, we just get the actual TextureForwarder which is
+  // returned by AsTextureForwarder...
+  aAllocator = aAllocator->AsTextureForwarder();
+
+  gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(aLayersBackend, aSelector);
+
   // also test the validity of aAllocator
   MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
   if (!aAllocator || !aAllocator->IPCOpen()) {
     return nullptr;
   }
 
   if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
     return nullptr;
   }
 
-  LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
-  gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(parentBackend, aSelector);
-
   TextureData* data = nullptr;
 
 #if defined(XP_WIN)
   int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
 #endif
 
 #ifdef XP_WIN
-  if (parentBackend == LayersBackend::LAYERS_D3D11 &&
+  if (aLayersBackend == LayersBackend::LAYERS_D3D11 &&
       (moz2DBackend == gfx::BackendType::DIRECT2D ||
        moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
        (!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
         gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice())) &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize)
   {
     data = DXGITextureData::Create(aSize, aFormat, aAllocFlags);
   }
-  if (parentBackend == LayersBackend::LAYERS_D3D9 &&
+  if (aLayersBackend == LayersBackend::LAYERS_D3D9 &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       aAllocator->IsSameProcess() &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize &&
       NS_IsMainThread() &&
       gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
     data = D3D9TextureData::Create(aSize, aFormat, aAllocFlags);
   }
@@ -974,24 +1013,24 @@ TextureClient::CreateForDrawing(TextureF
     data = DIBTextureData::Create(aSize, aFormat, aAllocator);
   }
 #endif
 
 #ifdef MOZ_X11
   gfxSurfaceType type =
     gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
 
-  if (!data && parentBackend == LayersBackend::LAYERS_BASIC &&
+  if (!data && aLayersBackend == LayersBackend::LAYERS_BASIC &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       type == gfxSurfaceType::Xlib)
   {
     data = X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
   }
 #ifdef GL_PROVIDER_GLX
-  if (!data && parentBackend == LayersBackend::LAYERS_OPENGL &&
+  if (!data && aLayersBackend == LayersBackend::LAYERS_OPENGL &&
       type == gfxSurfaceType::Xlib &&
       aFormat != SurfaceFormat::A8 &&
       gl::sGLXLibrary.UseTextureFromPixmap())
   {
     data = X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
   }
 #endif
 #endif
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -335,16 +335,26 @@ public:
   static already_AddRefed<TextureClient>
   CreateWithData(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator);
 
   // Creates and allocates a TextureClient usable with Moz2D.
   static already_AddRefed<TextureClient>
   CreateForDrawing(TextureForwarder* aAllocator,
                    gfx::SurfaceFormat aFormat,
                    gfx::IntSize aSize,
+                   LayersBackend aLayersBackend,
+                   BackendSelector aSelector,
+                   TextureFlags aTextureFlags,
+                   TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
+
+  // TODO: remove this one and use the one above instead.
+  static already_AddRefed<TextureClient>
+  CreateForDrawing(CompositableForwarder* aAllocator,
+                   gfx::SurfaceFormat aFormat,
+                   gfx::IntSize aSize,
                    BackendSelector aSelector,
                    TextureFlags aTextureFlags,
                    TextureAllocationFlags flags = ALLOC_DEFAULT);
 
   // Creates and allocates a TextureClient supporting the YCbCr format.
   static already_AddRefed<TextureClient>
   CreateForYCbCr(ClientIPCAllocator* aAllocator,
                  gfx::IntSize aYSize,
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -20,25 +20,27 @@ namespace mozilla {
 namespace layers {
 
 static void
 ShrinkCallback(nsITimer *aTimer, void *aClosure)
 {
   static_cast<TextureClientPool*>(aClosure)->ShrinkToMinimumSize();
 }
 
-TextureClientPool::TextureClientPool(gfx::SurfaceFormat aFormat,
+TextureClientPool::TextureClientPool(LayersBackend aLayersBackend,
+                                     gfx::SurfaceFormat aFormat,
+                                     gfx::IntSize aSize,
                                      TextureFlags aFlags,
-                                     gfx::IntSize aSize,
                                      uint32_t aMaxTextureClients,
                                      uint32_t aShrinkTimeoutMsec,
                                      TextureForwarder* aAllocator)
-  : mFormat(aFormat)
+  : mBackend(aLayersBackend)
+  , mFormat(aFormat)
+  , mSize(aSize)
   , mFlags(aFlags)
-  , mSize(aSize)
   , mMaxTextureClients(aMaxTextureClients)
   , mShrinkTimeoutMsec(aShrinkTimeoutMsec)
   , mOutstandingClients(0)
   , mSurfaceAllocator(aAllocator)
 {
   TCP_LOG("TexturePool %p created with max size %u and timeout %u\n",
       this, mMaxTextureClients, aShrinkTimeoutMsec);
   mTimer = do_CreateInstance("@mozilla.org/timer;1");
@@ -110,17 +112,17 @@ TextureClientPool::GetTextureClient()
   // No unused clients in the pool, create one
   if (gfxPrefs::ForceShmemTiles()) {
     // gfx::BackendType::NONE means use the content backend
     textureClient = TextureClient::CreateForRawBufferAccess(mSurfaceAllocator,
       mFormat, mSize, gfx::BackendType::NONE,
       mFlags, ALLOC_DEFAULT);
   } else {
     textureClient = TextureClient::CreateForDrawing(mSurfaceAllocator,
-      mFormat, mSize, BackendSelector::Content, mFlags);
+      mFormat, mSize, mBackend, BackendSelector::Content, mFlags);
   }
 
   mOutstandingClients++;
 #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
   if (textureClient) {
     textureClient->mPoolTracker = this;
   }
 #endif
--- a/gfx/layers/client/TextureClientPool.h
+++ b/gfx/layers/client/TextureClientPool.h
@@ -39,19 +39,20 @@ public:
   virtual void ReportClientLost() = 0;
 };
 
 class TextureClientPool final : public TextureClientAllocator
 {
   ~TextureClientPool();
 
 public:
-  TextureClientPool(gfx::SurfaceFormat aFormat,
+  TextureClientPool(LayersBackend aBackend,
+                    gfx::SurfaceFormat aFormat,
+                    gfx::IntSize aSize,
                     TextureFlags aFlags,
-                    gfx::IntSize aSize,
                     uint32_t aMaxTextureClients,
                     uint32_t aShrinkTimeoutMsec,
                     TextureForwarder* aAllocator);
 
   /**
    * Gets an allocated TextureClient of size and format that are determined
    * by the initialisation parameters given to the pool. This will either be
    * a cached client that was returned to the pool, or a newly allocated
@@ -99,40 +100,44 @@ public:
   virtual void ReportClientLost() override;
 
   /**
    * Calling this will cause the pool to attempt to relinquish any unused
    * clients.
    */
   void Clear();
 
+  LayersBackend GetBackend() const { return mBackend; }
   gfx::SurfaceFormat GetFormat() { return mFormat; }
   TextureFlags GetFlags() const { return mFlags; }
 
   /**
    * Clear the pool and put it in a state where it won't recycle any new texture.
    */
   void Destroy();
 
 private:
   void ReturnUnlockedClients();
 
   // The minimum size of the pool (the number of tiles that will be kept after
   // shrinking).
   static const uint32_t sMinCacheSize = 0;
 
+  /// Backend passed to the TextureClient for buffer creation.
+  LayersBackend mBackend;
+
   /// Format is passed to the TextureClient for buffer creation.
   gfx::SurfaceFormat mFormat;
 
+  /// The width and height of the tiles to be used.
+  gfx::IntSize mSize;
+
   /// Flags passed to the TextureClient for buffer creation.
   const TextureFlags mFlags;
 
-  /// The width and height of the tiles to be used.
-  gfx::IntSize mSize;
-
   // The maximum number of texture clients managed by this pool that we want
   // to remain active.
   uint32_t mMaxTextureClients;
 
   // The time in milliseconds before the pool will be shrunk to the minimum
   // size after returning a client.
   uint32_t mShrinkTimeoutMsec;
 
--- a/gfx/layers/client/TextureClientRecycleAllocator.cpp
+++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxPlatform.h"
 #include "mozilla/layers/ISurfaceAllocator.h"
-#include "mozilla/layers/TextureForwarder.h"
+#include "mozilla/layers/CompositableForwarder.h"
 #include "TextureClientRecycleAllocator.h"
 
 namespace mozilla {
 namespace layers {
 
 // Used to keep TextureClient's reference count stable as not to disrupt recycling.
 class TextureClientHolder
 {
@@ -53,30 +53,30 @@ public:
   {
     if (aTextureClient->GetFormat() != mFormat ||
         aTextureClient->GetSize() != mSize) {
       return false;
     }
     return true;
   }
 
-  already_AddRefed<TextureClient> Allocate(TextureForwarder* aAllocator) override
+  already_AddRefed<TextureClient> Allocate(CompositableForwarder* aAllocator) override
   {
     return mAllocator->Allocate(mFormat,
                                 mSize,
                                 mSelector,
                                 mTextureFlags,
                                 mAllocationFlags);
   }
 
 protected:
   TextureClientRecycleAllocator* mAllocator;
 };
 
-TextureClientRecycleAllocator::TextureClientRecycleAllocator(TextureForwarder* aAllocator)
+TextureClientRecycleAllocator::TextureClientRecycleAllocator(CompositableForwarder* aAllocator)
   : mSurfaceAllocator(aAllocator)
   , mMaxPooledSize(kMaxPooledSized)
   , mLock("TextureClientRecycleAllocatorImp.mLock")
 {
 }
 
 TextureClientRecycleAllocator::~TextureClientRecycleAllocator()
 {
--- a/gfx/layers/client/TextureClientRecycleAllocator.h
+++ b/gfx/layers/client/TextureClientRecycleAllocator.h
@@ -4,17 +4,17 @@
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
 #define MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
 
 #include <map>
 #include <stack>
 #include "mozilla/gfx/Types.h"
-#include "mozilla/layers/TextureForwarder.h"
+#include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/RefPtr.h"
 #include "TextureClient.h"
 #include "mozilla/Mutex.h"
 
 namespace mozilla {
 namespace layers {
 
 class TextureClientHolder;
@@ -42,17 +42,17 @@ public:
                                  TextureAllocationFlags aAllocationFlags)
     : mFormat(aFormat)
     , mSize(aSize)
     , mSelector(aSelector)
     , mTextureFlags(aTextureFlags | TextureFlags::RECYCLE) // Set recycle flag
     , mAllocationFlags(aAllocationFlags)
   {}
 
-  virtual already_AddRefed<TextureClient> Allocate(TextureForwarder* aAllocator) = 0;
+  virtual already_AddRefed<TextureClient> Allocate(CompositableForwarder* aAllocator) = 0;
   virtual bool IsCompatible(TextureClient* aTextureClient) = 0;
 
   const gfx::SurfaceFormat mFormat;
   const gfx::IntSize mSize;
   const BackendSelector mSelector;
   const TextureFlags mTextureFlags;
   const TextureAllocationFlags mAllocationFlags;
 };
@@ -67,17 +67,17 @@ public:
  * clients.
  */
 class TextureClientRecycleAllocator : public ITextureClientRecycleAllocator
 {
 protected:
   virtual ~TextureClientRecycleAllocator();
 
 public:
-  explicit TextureClientRecycleAllocator(TextureForwarder* aAllocator);
+  explicit TextureClientRecycleAllocator(CompositableForwarder* aAllocator);
 
   void SetMaxPoolSize(uint32_t aMax);
 
   // Creates and allocates a TextureClient.
   already_AddRefed<TextureClient>
   CreateOrRecycle(gfx::SurfaceFormat aFormat,
                   gfx::IntSize aSize,
                   BackendSelector aSelector,
@@ -92,17 +92,17 @@ public:
 protected:
   virtual already_AddRefed<TextureClient>
   Allocate(gfx::SurfaceFormat aFormat,
            gfx::IntSize aSize,
            BackendSelector aSelector,
            TextureFlags aTextureFlags,
            TextureAllocationFlags aAllocFlags);
 
-  RefPtr<TextureForwarder> mSurfaceAllocator;
+  RefPtr<CompositableForwarder> mSurfaceAllocator;
 
   friend class DefaultTextureClientAllocationHelper;
   void RecycleTextureClient(TextureClient* aClient) override;
 
   static const uint32_t kMaxPooledSized = 2;
   uint32_t mMaxPooledSize;
 
   std::map<TextureClient*, RefPtr<TextureClientHolder> > mInUseClients;
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -1095,16 +1095,17 @@ ClientMultiTiledLayerBuffer::ValidateTil
 #endif
 
   SurfaceMode mode;
   gfxContentType content = GetContentType(&mode);
 
   if (aTile.IsPlaceholderTile()) {
     aTile.SetLayerManager(mManager);
     aTile.SetTextureAllocator(mManager->GetCompositorBridgeChild()->GetTexturePool(
+      mManager->GetCompositorBackendType(),
       gfxPlatform::GetPlatform()->Optimal2DFormatForContent(content),
       TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD));
   }
   aTile.SetCompositableClient(mCompositableClient);
 
   nsIntRegion offsetScaledDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
   offsetScaledDirtyRegion.ScaleRoundOut(mResolution, mResolution);
 
--- a/gfx/layers/ipc/CompositableForwarder.h
+++ b/gfx/layers/ipc/CompositableForwarder.h
@@ -134,17 +134,49 @@ public:
   virtual uint64_t GetFwdTransactionId() = 0;
 
   int32_t GetSerial() { return mSerial; }
 
   SyncObject* GetSyncObject() { return mSyncObject; }
 
   virtual CompositableForwarder* AsCompositableForwarder() override { return this; }
 
+  virtual int32_t GetMaxTextureSize() const override
+  {
+    return mTextureFactoryIdentifier.mMaxTextureSize;
+  }
+
+  /**
+   * Returns the type of backend that is used off the main thread.
+   * We only don't allow changing the backend type at runtime so this value can
+   * be queried once and will not change until Gecko is restarted.
+   */
+  LayersBackend GetCompositorBackendType() const
+  {
+    return mTextureFactoryIdentifier.mParentBackend;
+  }
+
+  bool SupportsTextureBlitting() const
+  {
+    return mTextureFactoryIdentifier.mSupportsTextureBlitting;
+  }
+
+  bool SupportsPartialUploads() const
+  {
+    return mTextureFactoryIdentifier.mSupportsPartialUploads;
+  }
+
+  const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const
+  {
+    return mTextureFactoryIdentifier;
+  }
+
 protected:
+  TextureFactoryIdentifier mTextureFactoryIdentifier;
+
   nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
   nsTArray<RefPtr<CompositableClient>> mCompositableClientsToRemove;
   RefPtr<SyncObject> mSyncObject;
 
   const int32_t mSerial;
   static mozilla::Atomic<int32_t> sSerialCounter;
 };
 
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -877,29 +877,33 @@ CompositorBridgeChild::CancelWaitForRecy
   RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
   if (!client) {
     return;
   }
   mTexturesWaitingRecycled.Remove(aTextureId);
 }
 
 TextureClientPool*
-CompositorBridgeChild::GetTexturePool(SurfaceFormat aFormat, TextureFlags aFlags)
+CompositorBridgeChild::GetTexturePool(LayersBackend aBackend,
+                                      SurfaceFormat aFormat,
+                                      TextureFlags aFlags)
 {
   for (size_t i = 0; i < mTexturePools.Length(); i++) {
-    if (mTexturePools[i]->GetFormat() == aFormat &&
+    if (mTexturePools[i]->GetBackend() == aBackend &&
+        mTexturePools[i]->GetFormat() == aFormat &&
         mTexturePools[i]->GetFlags() == aFlags) {
       return mTexturePools[i];
     }
   }
 
   mTexturePools.AppendElement(
-      new TextureClientPool(aFormat, aFlags,
+      new TextureClientPool(aBackend, aFormat,
                             IntSize(gfxPlatform::GetPlatform()->GetTileWidth(),
                                     gfxPlatform::GetPlatform()->GetTileHeight()),
+                            aFlags,
                             gfxPrefs::LayersTileMaxPoolSize(),
                             gfxPrefs::LayersTileShrinkPoolTimeout(),
                             this));
 
   return mTexturePools.LastElement();
 }
 
 void
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -169,23 +169,27 @@ public:
    * make sure if there is no newer usage.
    */
   void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
 
   void DeliverFence(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle);
 
   virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
 
-  TextureClientPool* GetTexturePool(gfx::SurfaceFormat aFormat, TextureFlags aFlags);
+  TextureClientPool* GetTexturePool(LayersBackend aBackend,
+                                    gfx::SurfaceFormat aFormat,
+                                    TextureFlags aFlags);
   void ClearTexturePool();
 
   void HandleMemoryPressure();
 
   virtual MessageLoop* GetMessageLoop() const override { return mMessageLoop; }
 
+  virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
+
   virtual bool AllocUnsafeShmem(size_t aSize,
                                 mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
                                 mozilla::ipc::Shmem* aShmem) override;
   virtual bool AllocShmem(size_t aSize,
                           mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
                           mozilla::ipc::Shmem* aShmem) override;
   virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
 
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -692,16 +692,19 @@ CompositorBridgeParent::StopAndClearReso
     mCompositionManager = nullptr;
   }
 
   if (mCompositor) {
     mCompositor->DetachWidget();
     mCompositor->Destroy();
     mCompositor = nullptr;
   }
+
+  // After this point, it is no longer legal to access the widget.
+  mWidgetProxy = nullptr;
 }
 
 bool
 CompositorBridgeParent::RecvWillClose()
 {
   StopAndClearResources();
   return true;
 }
--- a/gfx/layers/ipc/ISurfaceAllocator.h
+++ b/gfx/layers/ipc/ISurfaceAllocator.h
@@ -122,16 +122,18 @@ protected:
 /// Methods that are specific to the client/child side.
 class ClientIPCAllocator : public ISurfaceAllocator
 {
 public:
   ClientIPCAllocator(const char* aName) : ISurfaceAllocator(aName) {}
 
   virtual ClientIPCAllocator* AsClientAllocator() override { return this; }
 
+  virtual base::ProcessId GetParentPid() const = 0;
+
   virtual MessageLoop * GetMessageLoop() const = 0;
 
   virtual int32_t GetMaxTextureSize() const { return gfxPrefs::MaxTextureSize(); }
 
   virtual void CancelWaitForRecycle(uint64_t aTextureId) = 0;
 };
 
 /// Methods that are specific to the host/parent side.
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -184,16 +184,18 @@ public:
 
   /**
    * Returns the ImageBridgeChild's message loop.
    *
    * Can be called from any thread.
    */
   virtual MessageLoop * GetMessageLoop() const override;
 
+  virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
+
   PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo,