Bug 1561435 - Format image/, a=automatic-formatting
authorVictor Porof <vporof@mozilla.com>
Fri, 05 Jul 2019 10:47:38 +0200
changeset 541052 bcb509a14173f2e859626bc4eeaeb63b13d5dc73
parent 541051 c822e46e3c168fed3aa8df3b064abedfc22aec2e
child 541053 62a5aeaf0dffe36b7157d4efe10afd0ff8369026
push id11533
push userarchaeopteryx@coole-files.de
push dateMon, 08 Jul 2019 18:18:03 +0000
treeherdermozilla-beta@f4452e031aed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersautomatic-formatting
bugs1561435
milestone69.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
Bug 1561435 - Format image/, a=automatic-formatting # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35906
.eslintrc.js
.prettierignore
image/test/browser/browser_bug666317.js
image/test/browser/browser_docshell_type_editor.js
image/test/browser/browser_image.js
image/test/browser/head.js
image/test/mochitest/animationPolling.js
image/test/mochitest/imgutils.js
image/test/unit/async_load_tests.js
image/test/unit/image_load_helpers.js
image/test/unit/test_async_notification.js
image/test/unit/test_async_notification_404.js
image/test/unit/test_async_notification_animated.js
image/test/unit/test_encoder_apng.js
image/test/unit/test_encoder_png.js
image/test/unit/test_imgtools.js
image/test/unit/test_moz_icon_uri.js
image/test/unit/test_private_channel.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -40,17 +40,16 @@ module.exports = {
     "plugin:mozilla/recommended"
   ],
   "plugins": [
     "mozilla"
   ],
   "overrides": [{
       "files": [
         "devtools/**",
-        "image/**",
         "intl/**",
         "ipc/**",
         "js/**",
         "layout/**",
         "media/**",
         "memory/**",
         "mfbt/**",
         "mobile/**",
--- a/.prettierignore
+++ b/.prettierignore
@@ -35,17 +35,16 @@ security/manager/ssl/security-prefs.js
 services/common/services-common.js
 services/sync/services-sync.js
 services/sync/tests/unit/prefs_test_prefs_store.js
 testing/marionette/prefs/marionette.js
 toolkit/components/telemetry/datareporting-prefs.js
 toolkit/components/telemetry/healthreport-prefs.js
 
 # Ignore all top-level directories for now.
-image/**
 intl/**
 ipc/**
 js/**
 layout/**
 media/**
 memory/**
 mfbt/**
 mobile/**
--- a/image/test/browser/browser_bug666317.js
+++ b/image/test/browser/browser_bug666317.js
@@ -1,139 +1,144 @@
 waitForExplicitFinish();
 
 var pageSource =
-  '<html><body>' +
-    '<img id="testImg" src="' + TESTROOT + 'big.png">' +
-  '</body></html>';
+  "<html><body>" +
+  '<img id="testImg" src="' +
+  TESTROOT +
+  'big.png">' +
+  "</body></html>";
 
 var oldDiscardingPref, oldTab, newTab;
 var prefBranch = Cc["@mozilla.org/preferences-service;1"]
-                   .getService(Ci.nsIPrefService)
-                   .getBranch('image.mem.');
+  .getService(Ci.nsIPrefService)
+  .getBranch("image.mem.");
 
 var gWaitingForDiscard = false;
 var gScriptedObserver;
 var gClonedRequest;
 
 function ImageObserver(decodeCallback, discardCallback) {
   this.decodeComplete = function onDecodeComplete(aRequest) {
     decodeCallback();
-  }
+  };
 
-  this.discard = function onDiscard(request)
-  {
+  this.discard = function onDiscard(request) {
     if (!gWaitingForDiscard) {
       return;
     }
 
     this.synchronous = false;
     discardCallback();
-  }
+  };
 
   this.synchronous = true;
 }
 
 function currentRequest() {
-  let img = gBrowser.getBrowserForTab(newTab).contentWindow
-            .document.getElementById('testImg');
+  let img = gBrowser
+    .getBrowserForTab(newTab)
+    .contentWindow.document.getElementById("testImg");
   return img.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
 }
 
 function isImgDecoded() {
   let request = currentRequest();
-  return request.imageStatus & Ci.imgIRequest.STATUS_DECODE_COMPLETE ? true : false;
+  return request.imageStatus & Ci.imgIRequest.STATUS_DECODE_COMPLETE
+    ? true
+    : false;
 }
 
 // Ensure that the image is decoded by drawing it to a canvas.
 function forceDecodeImg() {
   let doc = gBrowser.getBrowserForTab(newTab).contentWindow.document;
-  let img = doc.getElementById('testImg');
-  let canvas = doc.createElement('canvas');
-  let ctx = canvas.getContext('2d');
+  let img = doc.getElementById("testImg");
+  let canvas = doc.createElement("canvas");
+  let ctx = canvas.getContext("2d");
   ctx.drawImage(img, 0, 0);
 }
 
 function runAfterAsyncEvents(aCallback) {
   function handlePostMessage(aEvent) {
-    if (aEvent.data == 'next') {
-      window.removeEventListener('message', handlePostMessage);
+    if (aEvent.data == "next") {
+      window.removeEventListener("message", handlePostMessage);
       aCallback();
     }
   }
 
-  window.addEventListener('message', handlePostMessage);
+  window.addEventListener("message", handlePostMessage);
 
   // We'll receive the 'message' event after everything else that's currently in
   // the event queue (which is a stronger guarantee than setTimeout, because
   // setTimeout events may be coalesced). This lets us ensure that we run
   // aCallback *after* any asynchronous events are delivered.
-  window.postMessage('next', '*');
+  window.postMessage("next", "*");
 }
 
 function test() {
   // Enable the discarding pref.
-  oldDiscardingPref = prefBranch.getBoolPref('discardable');
-  prefBranch.setBoolPref('discardable', true);
+  oldDiscardingPref = prefBranch.getBoolPref("discardable");
+  prefBranch.setBoolPref("discardable", true);
 
   // Create and focus a new tab.
   oldTab = gBrowser.selectedTab;
-  newTab = BrowserTestUtils.addTab(gBrowser, 'data:text/html,' + pageSource);
+  newTab = BrowserTestUtils.addTab(gBrowser, "data:text/html," + pageSource);
   gBrowser.selectedTab = newTab;
 
   // Run step2 after the tab loads.
-  gBrowser.getBrowserForTab(newTab)
-          .addEventListener("pageshow", step2);
+  gBrowser.getBrowserForTab(newTab).addEventListener("pageshow", step2);
 }
 
 function step2() {
   // Create the image observer.
-  var observer =
-    new ImageObserver(() => runAfterAsyncEvents(step3),   // DECODE_COMPLETE
-                      () => runAfterAsyncEvents(step5));  // DISCARD
+  var observer = new ImageObserver(
+    () => runAfterAsyncEvents(step3), // DECODE_COMPLETE
+    () => runAfterAsyncEvents(step5)
+  ); // DISCARD
   gScriptedObserver = Cc["@mozilla.org/image/tools;1"]
-                        .getService(Ci.imgITools)
-                        .createScriptedObserver(observer);
+    .getService(Ci.imgITools)
+    .createScriptedObserver(observer);
 
   // Clone the current imgIRequest with our new observer.
   var request = currentRequest();
   gClonedRequest = request.clone(gScriptedObserver);
 
   // Check that the image is decoded.
   forceDecodeImg();
 
   // The DECODE_COMPLETE notification is delivered asynchronously. ImageObserver will
   // eventually call step3.
 }
 
 function step3() {
-  ok(isImgDecoded(), 'Image should initially be decoded.');
+  ok(isImgDecoded(), "Image should initially be decoded.");
 
   // Focus the old tab, then fire a memory-pressure notification.  This should
   // cause the decoded image in the new tab to be discarded.
   gBrowser.selectedTab = oldTab;
 
   // Allow time to process the tab change.
   runAfterAsyncEvents(step4);
 }
 
 function step4() {
   gWaitingForDiscard = true;
 
-  var os = Cc["@mozilla.org/observer-service;1"]
-             .getService(Ci.nsIObserverService);
-  os.notifyObservers(null, 'memory-pressure', 'heap-minimize');
+  var os = Cc["@mozilla.org/observer-service;1"].getService(
+    Ci.nsIObserverService
+  );
+  os.notifyObservers(null, "memory-pressure", "heap-minimize");
 
   // The DISCARD notification is delivered asynchronously. ImageObserver will
   // eventually call step5. (Or else, sadly, the test will time out.)
 }
 
 function step5() {
-  ok(true, 'Image should be discarded.');
+  ok(true, "Image should be discarded.");
 
   // And we're done.
   gBrowser.removeTab(newTab);
-  prefBranch.setBoolPref('discardable', oldDiscardingPref);
+  prefBranch.setBoolPref("discardable", oldDiscardingPref);
 
   gClonedRequest.cancelAndForgetObserver(0);
 
   finish();
 }
--- a/image/test/browser/browser_docshell_type_editor.js
+++ b/image/test/browser/browser_docshell_type_editor.js
@@ -1,119 +1,136 @@
-
 "use strict";
 
 const SIMPLE_HTML = "data:text/html,<html><head></head><body></body></html>";
 
 /**
  * Returns the directory where the chrome.manifest file for the test can be found.
  *
  * @return nsIFile of the manifest directory
  */
 function getManifestDir() {
   let path = getTestFilePath("browser_docshell_type_editor");
-  let file = Cc["@mozilla.org/file/local;1"]
-               .createInstance(Ci.nsIFile);
+  let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
   file.initWithPath(path);
   return file;
 }
 
 // The following URI is *not* accessible to content, hence loading that URI
 // from an unprivileged site should be blocked. If docshell is of appType
 // APP_TYPE_EDITOR however the load should be allowed.
 // >> chrome://test1/skin/privileged.png
 
 add_task(async function() {
   info("docshell of appType APP_TYPE_EDITOR can access privileged images.");
 
   // Load a temporary manifest adding a route to a privileged image
   let manifestDir = getManifestDir();
   Components.manager.addBootstrappedManifestLocation(manifestDir);
 
-  await BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: SIMPLE_HTML
-  }, async function(browser) {
-    await ContentTask.spawn(browser, null, async function() {
-      let rootDocShell = docShell.QueryInterface(Ci.nsIDocShellTreeItem)
-                                 .rootTreeItem
-                                 .QueryInterface(Ci.nsIInterfaceRequestor)
-                                 .getInterface(Ci.nsIDocShell);
-      let defaultAppType = rootDocShell.appType;
+  await BrowserTestUtils.withNewTab(
+    {
+      gBrowser,
+      url: SIMPLE_HTML,
+    },
+    async function(browser) {
+      await ContentTask.spawn(browser, null, async function() {
+        let rootDocShell = docShell
+          .QueryInterface(Ci.nsIDocShellTreeItem)
+          .rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIDocShell);
+        let defaultAppType = rootDocShell.appType;
 
-      rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_EDITOR;
+        rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_EDITOR;
 
-      is(rootDocShell.appType, Ci.nsIDocShell.APP_TYPE_EDITOR,
-        "sanity check: appType after update should be type editor");
-
+        is(
+          rootDocShell.appType,
+          Ci.nsIDocShell.APP_TYPE_EDITOR,
+          "sanity check: appType after update should be type editor"
+        );
 
-      return new Promise(resolve => {
-        let doc = content.document;
-        let image = doc.createElement("img");
-        image.onload = function() {
-          ok(true, "APP_TYPE_EDITOR is allowed to load privileged image");
-          // restore appType of rootDocShell before moving on to the next test
-          rootDocShell.appType = defaultAppType;
-          resolve();
-        }
-        image.onerror = function() {
-          ok(false, "APP_TYPE_EDITOR is allowed to load privileged image");
-          // restore appType of rootDocShell before moving on to the next test
-          rootDocShell.appType = defaultAppType;
-          resolve();
-        }
-        doc.body.appendChild(image);
-        image.src = "chrome://test1/skin/privileged.png";
+        return new Promise(resolve => {
+          let doc = content.document;
+          let image = doc.createElement("img");
+          image.onload = function() {
+            ok(true, "APP_TYPE_EDITOR is allowed to load privileged image");
+            // restore appType of rootDocShell before moving on to the next test
+            rootDocShell.appType = defaultAppType;
+            resolve();
+          };
+          image.onerror = function() {
+            ok(false, "APP_TYPE_EDITOR is allowed to load privileged image");
+            // restore appType of rootDocShell before moving on to the next test
+            rootDocShell.appType = defaultAppType;
+            resolve();
+          };
+          doc.body.appendChild(image);
+          image.src = "chrome://test1/skin/privileged.png";
+        });
       });
-    });
-  });
+    }
+  );
 
   Components.manager.removeBootstrappedManifestLocation(manifestDir);
 });
 
 add_task(async function() {
-  info("docshell of appType APP_TYPE_UNKNOWN can *not* access privileged images.");
+  info(
+    "docshell of appType APP_TYPE_UNKNOWN can *not* access privileged images."
+  );
 
   // Load a temporary manifest adding a route to a privileged image
   let manifestDir = getManifestDir();
   Components.manager.addBootstrappedManifestLocation(manifestDir);
 
-  await BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: SIMPLE_HTML
-  }, async function(browser) {
-    await ContentTask.spawn(browser, null, async function() {
-      let rootDocShell = docShell.QueryInterface(Ci.nsIDocShellTreeItem)
-                                 .rootTreeItem
-                                 .QueryInterface(Ci.nsIInterfaceRequestor)
-                                 .getInterface(Ci.nsIDocShell);
-      let defaultAppType = rootDocShell.appType;
+  await BrowserTestUtils.withNewTab(
+    {
+      gBrowser,
+      url: SIMPLE_HTML,
+    },
+    async function(browser) {
+      await ContentTask.spawn(browser, null, async function() {
+        let rootDocShell = docShell
+          .QueryInterface(Ci.nsIDocShellTreeItem)
+          .rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIDocShell);
+        let defaultAppType = rootDocShell.appType;
 
-      rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_UNKNOWN;
+        rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_UNKNOWN;
 
-      is(rootDocShell.appType, Ci.nsIDocShell.APP_TYPE_UNKNOWN,
-        "sanity check: appType of docshell should be unknown");
+        is(
+          rootDocShell.appType,
+          Ci.nsIDocShell.APP_TYPE_UNKNOWN,
+          "sanity check: appType of docshell should be unknown"
+        );
 
-      return new Promise(resolve => {
-        let doc = content.document;
-        let image = doc.createElement("img");
-        image.onload = function() {
-          ok(false, "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image");
-          // restore appType of rootDocShell before moving on to the next test
-          rootDocShell.appType = defaultAppType;
-          resolve();
-        }
-        image.onerror = function() {
-          ok(true, "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image");
-          // restore appType of rootDocShell before moving on to the next test
-          rootDocShell.appType = defaultAppType;
-          resolve();
-        }
-        doc.body.appendChild(image);
-        // Set the src via wrappedJSObject so the load is triggered with
-        // the content page's principal rather than ours.
-        image.wrappedJSObject.src = "chrome://test1/skin/privileged.png";
+        return new Promise(resolve => {
+          let doc = content.document;
+          let image = doc.createElement("img");
+          image.onload = function() {
+            ok(
+              false,
+              "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image"
+            );
+            // restore appType of rootDocShell before moving on to the next test
+            rootDocShell.appType = defaultAppType;
+            resolve();
+          };
+          image.onerror = function() {
+            ok(
+              true,
+              "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image"
+            );
+            // restore appType of rootDocShell before moving on to the next test
+            rootDocShell.appType = defaultAppType;
+            resolve();
+          };
+          doc.body.appendChild(image);
+          // Set the src via wrappedJSObject so the load is triggered with
+          // the content page's principal rather than ours.
+          image.wrappedJSObject.src = "chrome://test1/skin/privileged.png";
+        });
       });
-    });
-  });
+    }
+  );
 
   Components.manager.removeBootstrappedManifestLocation(manifestDir);
 });
--- a/image/test/browser/browser_image.js
+++ b/image/test/browser/browser_image.js
@@ -6,98 +6,137 @@ requestLongerTimeout(2); // see bug 6601
 var gTimer;
 
 // Browsing to a new URL - pushing us into the bfcache - should cause
 // animations to stop, and resume when we return
 function testBFCache() {
   function theTest() {
     var abort = false;
     var chances, gImage, gFrames;
-    gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT + "image.html");
-    gBrowser.selectedBrowser.addEventListener("pageshow", function () {
-      var window = gBrowser.contentWindow;
-      // If false, we are in an optimized build, and we abort this and
-      // all further tests
-      if (!actOnMozImage(window.document, "img1", function(image) {
-        gImage = image;
-        gFrames = gImage.framesNotified;
-      })) {
-        gBrowser.removeCurrentTab();
-        abort = true;
-      }
-      goer.next();
-    }, {capture: true, once: true});
+    gBrowser.selectedTab = BrowserTestUtils.addTab(
+      gBrowser,
+      TESTROOT + "image.html"
+    );
+    gBrowser.selectedBrowser.addEventListener(
+      "pageshow",
+      function() {
+        var window = gBrowser.contentWindow;
+        // If false, we are in an optimized build, and we abort this and
+        // all further tests
+        if (
+          !actOnMozImage(window.document, "img1", function(image) {
+            gImage = image;
+            gFrames = gImage.framesNotified;
+          })
+        ) {
+          gBrowser.removeCurrentTab();
+          abort = true;
+        }
+        goer.next();
+      },
+      { capture: true, once: true }
+    );
     yield;
     if (abort) {
       finish();
       yield; // optimized build
     }
 
     // Let animation run for a bit
     chances = 120;
     do {
       gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      gTimer.initWithCallback(function() {
-        if (gImage.framesNotified >= 20) {
-          goer.send(true);
-        } else {
-          chances--;
-          goer.send(chances == 0); // maybe if we wait a bit, it will happen
-        }
-      }, 500, Ci.nsITimer.TYPE_ONE_SHOT);
-    } while (!(yield));
+      gTimer.initWithCallback(
+        function() {
+          if (gImage.framesNotified >= 20) {
+            goer.send(true);
+          } else {
+            chances--;
+            goer.send(chances == 0); // maybe if we wait a bit, it will happen
+          }
+        },
+        500,
+        Ci.nsITimer.TYPE_ONE_SHOT
+      );
+    } while (!yield);
     is(chances > 0, true, "Must have animated a few frames so far");
 
     // Browse elsewhere; push our animating page into the bfcache
     gBrowser.loadURI("about:blank");
 
     // Wait a bit for page to fully load, then wait a while and
     // see that no animation occurs.
     gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    gTimer.initWithCallback(function() {
-      gFrames = gImage.framesNotified;
-      gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      gTimer.initWithCallback(function() {
-        // Might have a few stray frames, until other page totally loads
-        var additionalFrames = gImage.framesNotified  - gFrames;
-        is(additionalFrames == 0, true, "Must have not animated in bfcache! Got " + additionalFrames + " additional frames");
-        goer.next();
-      }, 4000, Ci.nsITimer.TYPE_ONE_SHOT); // 4 seconds - expect 40 frames
-    }, 0, Ci.nsITimer.TYPE_ONE_SHOT); // delay of 0 - wait for next event loop
+    gTimer.initWithCallback(
+      function() {
+        gFrames = gImage.framesNotified;
+        gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+        gTimer.initWithCallback(
+          function() {
+            // Might have a few stray frames, until other page totally loads
+            var additionalFrames = gImage.framesNotified - gFrames;
+            is(
+              additionalFrames == 0,
+              true,
+              "Must have not animated in bfcache! Got " +
+                additionalFrames +
+                " additional frames"
+            );
+            goer.next();
+          },
+          4000,
+          Ci.nsITimer.TYPE_ONE_SHOT
+        ); // 4 seconds - expect 40 frames
+      },
+      0,
+      Ci.nsITimer.TYPE_ONE_SHOT
+    ); // delay of 0 - wait for next event loop
     yield;
 
     // Go back
     gBrowser.goBack();
 
     chances = 120;
     do {
       gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      gTimer.initWithCallback(function() {
-        if (gImage.framesNotified - gFrames >= 20) {
-          goer.send(true);
-        } else {
-          chances--;
-          goer.send(chances == 0); // maybe if we wait a bit, it will happen
-        }
-      }, 500, Ci.nsITimer.TYPE_ONE_SHOT);
-    } while (!(yield));
+      gTimer.initWithCallback(
+        function() {
+          if (gImage.framesNotified - gFrames >= 20) {
+            goer.send(true);
+          } else {
+            chances--;
+            goer.send(chances == 0); // maybe if we wait a bit, it will happen
+          }
+        },
+        500,
+        Ci.nsITimer.TYPE_ONE_SHOT
+      );
+    } while (!yield);
     is(chances > 0, true, "Must have animated once out of bfcache!");
 
     // Finally, check that the css background image has essentially the same
     // # of frames, implying that it animated at the same times as the regular
     // image. We can easily retrieve regular images through their HTML image
     // elements, which is what we did before. For the background image, we
     // create a regular image now, and read the current frame count.
     var doc = gBrowser.selectedBrowser.contentWindow.document;
     var div = doc.getElementById("background_div");
     div.innerHTML += '<img src="animated2.gif" id="img3">';
     actOnMozImage(doc, "img3", function(image) {
-      is(Math.abs(image.framesNotified - gImage.framesNotified)/gImage.framesNotified < 0.5, true,
-         "Must have also animated the background image, and essentially the same # of frames. " +
-         "Regular image got " + gImage.framesNotified + " frames but background image got " + image.framesNotified);
+      is(
+        Math.abs(image.framesNotified - gImage.framesNotified) /
+          gImage.framesNotified <
+          0.5,
+        true,
+        "Must have also animated the background image, and essentially the same # of frames. " +
+          "Regular image got " +
+          gImage.framesNotified +
+          " frames but background image got " +
+          image.framesNotified
+      );
     });
 
     gBrowser.removeCurrentTab();
 
     nextTest();
   }
 
   var goer = theTest();
@@ -106,67 +145,97 @@ function testBFCache() {
 
 // Check that imgContainers are shared on the same page and
 // between tabs
 function testSharedContainers() {
   function theTest() {
     var gImages = [];
     var gFrames;
 
-    gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT + "image.html");
-    gBrowser.selectedBrowser.addEventListener("pageshow", function () {
-      actOnMozImage(gBrowser.contentDocument, "img1", function(image) {
-        gImages[0] = image;
-        gFrames = image.framesNotified; // May in theory have frames from last test
-                                        // in this counter - so subtract them out
-      });
-      goer.next();
-    }, {capture: true, once: true});
+    gBrowser.selectedTab = BrowserTestUtils.addTab(
+      gBrowser,
+      TESTROOT + "image.html"
+    );
+    gBrowser.selectedBrowser.addEventListener(
+      "pageshow",
+      function() {
+        actOnMozImage(gBrowser.contentDocument, "img1", function(image) {
+          gImages[0] = image;
+          gFrames = image.framesNotified; // May in theory have frames from last test
+          // in this counter - so subtract them out
+        });
+        goer.next();
+      },
+      { capture: true, once: true }
+    );
     yield;
 
     // Load next tab somewhat later
     gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    gTimer.initWithCallback(function() {
-      goer.next();
-    }, 1500, Ci.nsITimer.TYPE_ONE_SHOT);
+    gTimer.initWithCallback(
+      function() {
+        goer.next();
+      },
+      1500,
+      Ci.nsITimer.TYPE_ONE_SHOT
+    );
     yield;
 
-    gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT + "imageX2.html");
-    gBrowser.selectedBrowser.addEventListener("pageshow", function () {
-      [1,2].forEach(function(i) {
-        actOnMozImage(gBrowser.contentDocument, "img"+i, function(image) {
-          gImages[i] = image;
+    gBrowser.selectedTab = BrowserTestUtils.addTab(
+      gBrowser,
+      TESTROOT + "imageX2.html"
+    );
+    gBrowser.selectedBrowser.addEventListener(
+      "pageshow",
+      function() {
+        [1, 2].forEach(function(i) {
+          actOnMozImage(gBrowser.contentDocument, "img" + i, function(image) {
+            gImages[i] = image;
+          });
         });
-      });
-      goer.next();
-    }, {capture: true, once: true});
+        goer.next();
+      },
+      { capture: true, once: true }
+    );
     yield;
 
     var chances = 120;
     do {
       gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      gTimer.initWithCallback(function() {
-        if (gImages[0].framesNotified - gFrames >= 10) {
-          goer.send(true);
-        } else {
-          chances--;
-          goer.send(chances == 0); // maybe if we wait a bit, it will happen
-        }
-      }, 500, Ci.nsITimer.TYPE_ONE_SHOT);
-    } while (!(yield));
-    is(chances > 0, true, "Must have been animating while showing several images");
+      gTimer.initWithCallback(
+        function() {
+          if (gImages[0].framesNotified - gFrames >= 10) {
+            goer.send(true);
+          } else {
+            chances--;
+            goer.send(chances == 0); // maybe if we wait a bit, it will happen
+          }
+        },
+        500,
+        Ci.nsITimer.TYPE_ONE_SHOT
+      );
+    } while (!yield);
+    is(
+      chances > 0,
+      true,
+      "Must have been animating while showing several images"
+    );
 
     // Check they all have the same frame counts
     var theFrames = null;
-    [0,1,2].forEach(function(i) {
+    [0, 1, 2].forEach(function(i) {
       var frames = gImages[i].framesNotified;
       if (theFrames == null) {
         theFrames = frames;
       } else {
-        is(theFrames, frames, "Sharing the same imgContainer means *exactly* the same frame counts!");
+        is(
+          theFrames,
+          frames,
+          "Sharing the same imgContainer means *exactly* the same frame counts!"
+        );
       }
     });
 
     gBrowser.removeCurrentTab();
     gBrowser.removeCurrentTab();
 
     nextTest();
   }
@@ -184,9 +253,8 @@ function nextTest() {
   }
   tests.shift()();
 }
 
 function test() {
   ignoreAllUncaughtExceptions();
   nextTest();
 }
-
--- a/image/test/browser/head.js
+++ b/image/test/browser/head.js
@@ -7,19 +7,20 @@ const CHROMEROOT = chrome_root;
 
 function getImageLoading(doc, id) {
   return doc.getElementById(id);
 }
 
 // Tries to get the Moz debug image, imgIContainerDebug. Only works
 // in a debug build. If we succeed, we call func().
 function actOnMozImage(doc, id, func) {
-  var imgContainer = getImageLoading(doc, id).getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST).image;
+  var imgContainer = getImageLoading(doc, id).getRequest(
+    Ci.nsIImageLoadingContent.CURRENT_REQUEST
+  ).image;
   var mozImage;
   try {
     mozImage = imgContainer.QueryInterface(Ci.imgIContainerDebug);
-  }
-  catch (e) {
+  } catch (e) {
     return false;
   }
   func(mozImage);
   return true;
 }
--- a/image/test/mochitest/animationPolling.js
+++ b/image/test/mochitest/animationPolling.js
@@ -1,56 +1,63 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 var currentTest;
 var gIsRefImageLoaded = false;
 const gShouldOutputDebugInfo = false;
 
-function pollForSuccess()
-{
+function pollForSuccess() {
   if (!currentTest.isTestFinished) {
-    if (!currentTest.reusingReferenceImage || (currentTest.reusingReferenceImage
-        && gRefImageLoaded)) {
+    if (
+      !currentTest.reusingReferenceImage ||
+      (currentTest.reusingReferenceImage && gRefImageLoaded)
+    ) {
       currentTest.checkImage();
     }
 
     setTimeout(pollForSuccess, currentTest.pollFreq);
   }
-};
+}
 
-function referencePoller()
-{
+function referencePoller() {
   currentTest.takeReferenceSnapshot();
 }
 
-function reuseImageCallback()
-{
+function reuseImageCallback() {
   gIsRefImageLoaded = true;
 }
 
-function failTest()
-{
+function failTest() {
   if (currentTest.isTestFinished || currentTest.closeFunc) {
     return;
   }
 
-  ok(false, "timing out after " + currentTest.timeout + "ms.  "
-     + "Animated image still doesn't look correct, after poll #"
-     + currentTest.pollCounter);
+  ok(
+    false,
+    "timing out after " +
+      currentTest.timeout +
+      "ms.  " +
+      "Animated image still doesn't look correct, after poll #" +
+      currentTest.pollCounter
+  );
   currentTest.wereFailures = true;
 
   if (currentTest.currentSnapshotDataURI) {
-    currentTest.outputDebugInfo("Snapshot #" + currentTest.pollCounter,
-                                "snapNum" + currentTest.pollCounter,
-                                currentTest.currentSnapshotDataURI);
+    currentTest.outputDebugInfo(
+      "Snapshot #" + currentTest.pollCounter,
+      "snapNum" + currentTest.pollCounter,
+      currentTest.currentSnapshotDataURI
+    );
   }
 
-  currentTest.enableDisplay(document.getElementById(currentTest.debugElementId));
+  currentTest.enableDisplay(
+    document.getElementById(currentTest.debugElementId)
+  );
 
   currentTest.cleanUpAndFinish();
-};
+}
 
 /**
  * Create a new AnimationTest object.
  *
  * @param pollFreq The amount of time (in ms) to wait between consecutive
  *        snapshots if the reference image and the test image don't match.
  * @param timeout The total amount of time (in ms) to wait before declaring the
  *        test as failed.
@@ -70,19 +77,27 @@ function failTest()
  * @param xulTest A boolean value indicating whether or not this is a XUL test
  *        (uses hidden=true/false rather than display: none to hide/show
  *        elements).
  * @param closeFunc A function that should be called when this test is finished.
  *        If null, then cleanUpAndFinish() will be called. This can be used to
  *        chain tests together, so they are all finished exactly once.
  * @returns {AnimationTest}
  */
-function AnimationTest(pollFreq, timeout, referenceElementId, imageElementId,
-                       debugElementId, cleanId, srcAttr, xulTest, closeFunc)
-{
+function AnimationTest(
+  pollFreq,
+  timeout,
+  referenceElementId,
+  imageElementId,
+  debugElementId,
+  cleanId,
+  srcAttr,
+  xulTest,
+  closeFunc
+) {
   // We want to test the cold loading behavior, so clear cache in case an
   // earlier test got our image in there already.
   clearAllImageCaches();
 
   this.wereFailures = false;
   this.pollFreq = pollFreq;
   this.timeout = timeout;
   this.imageElementId = imageElementId;
@@ -98,55 +113,53 @@ function AnimationTest(pollFreq, timeout
   this.srcAttr = srcAttr;
   this.debugElementId = debugElementId;
   this.referenceSnapshot = ""; // value will be set in takeReferenceSnapshot()
   this.pollCounter = 0;
   this.isTestFinished = false;
   this.numRefsTaken = 0;
   this.blankWaitTime = 0;
 
-  this.cleanId = cleanId ? cleanId : '';
-  this.xulTest = xulTest ? xulTest : '';
-  this.closeFunc = closeFunc ? closeFunc : '';
-};
+  this.cleanId = cleanId ? cleanId : "";
+  this.xulTest = xulTest ? xulTest : "";
+  this.closeFunc = closeFunc ? closeFunc : "";
+}
 
-AnimationTest.prototype.preloadImage = function()
-{
+AnimationTest.prototype.preloadImage = function() {
   if (this.srcAttr) {
     this.myImage = new Image();
-    this.myImage.onload = function() { currentTest.continueTest(); };
+    this.myImage.onload = function() {
+      currentTest.continueTest();
+    };
     this.myImage.src = this.srcAttr;
   } else {
     this.continueTest();
   }
 };
 
-AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri)
-{
+AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri) {
   if (!gShouldOutputDebugInfo) {
     return;
   }
   var debugElement = document.getElementById(this.debugElementId);
   var newDataUriElement = document.createElement("a");
   newDataUriElement.setAttribute("id", id);
   newDataUriElement.setAttribute("href", dataUri);
   newDataUriElement.appendChild(document.createTextNode(message));
   debugElement.appendChild(newDataUriElement);
   var brElement = document.createElement("br");
   debugElement.appendChild(brElement);
   todo(false, "Debug (" + id + "): " + message + " " + dataUri);
 };
 
-AnimationTest.prototype.isFinished = function()
-{
+AnimationTest.prototype.isFinished = function() {
   return this.isTestFinished;
 };
 
-AnimationTest.prototype.takeCleanSnapshot = function()
-{
+AnimationTest.prototype.takeCleanSnapshot = function() {
   var cleanElement;
   if (this.cleanId) {
     cleanElement = document.getElementById(this.cleanId);
   }
 
   // Enable clean page comparison element
   if (cleanElement) {
     this.enableDisplay(cleanElement);
@@ -156,94 +169,98 @@ AnimationTest.prototype.takeCleanSnapsho
   this.cleanSnapshot = snapshotWindow(window, false);
 
   // Disable the clean page comparison element
   if (cleanElement) {
     this.disableDisplay(cleanElement);
   }
 
   var dataString1 = "Clean Snapshot";
-  this.outputDebugInfo(dataString1, 'cleanSnap',
-                       this.cleanSnapshot.toDataURL());
+  this.outputDebugInfo(
+    dataString1,
+    "cleanSnap",
+    this.cleanSnapshot.toDataURL()
+  );
 };
 
-AnimationTest.prototype.takeBlankSnapshot = function()
-{
+AnimationTest.prototype.takeBlankSnapshot = function() {
   // Take a snapshot of the initial (essentially blank) page
   this.blankSnapshot = snapshotWindow(window, false);
 
   var dataString1 = "Initial Blank Snapshot";
-  this.outputDebugInfo(dataString1, 'blank1Snap',
-                       this.blankSnapshot.toDataURL());
+  this.outputDebugInfo(
+    dataString1,
+    "blank1Snap",
+    this.blankSnapshot.toDataURL()
+  );
 };
 
 /**
  * Begin the AnimationTest. This will utilize the information provided in the
  * constructor to invoke a mochitest on animated images. It will automatically
  * fail if allowed to run past the timeout. This will attempt to preload an
  * image, if applicable, and then asynchronously call continueTest(), or if not
  * applicable, synchronously trigger a call to continueTest().
  */
-AnimationTest.prototype.beginTest = function()
-{
+AnimationTest.prototype.beginTest = function() {
   SimpleTest.waitForExplicitFinish();
   SimpleTest.requestFlakyTimeout("untriaged");
 
   currentTest = this;
   this.preloadImage();
 };
 
 /**
  * This is the second part of the test. It is triggered (eventually) from
  * beginTest() either synchronously or asynchronously, as an image load
  * callback.
  */
-AnimationTest.prototype.continueTest = function()
-{
+AnimationTest.prototype.continueTest = function() {
   // In case something goes wrong, fail earlier than mochitest timeout,
   // and with more information.
   setTimeout(failTest, this.timeout);
 
   if (!this.reusingImageAsReference) {
     this.disableDisplay(document.getElementById(this.imageElementId));
   }
 
   this.takeReferenceSnapshot();
   this.setupPolledImage();
   SimpleTest.executeSoon(pollForSuccess);
 };
 
-AnimationTest.prototype.setupPolledImage = function ()
-{
+AnimationTest.prototype.setupPolledImage = function() {
   // Make sure the image is visible
   if (!this.reusingImageAsReference) {
     this.enableDisplay(document.getElementById(this.imageElementId));
     var currentSnapshot = snapshotWindow(window, false);
-    var result = compareSnapshots(currentSnapshot,
-                                  this.referenceSnapshot, true);
+    var result = compareSnapshots(
+      currentSnapshot,
+      this.referenceSnapshot,
+      true
+    );
 
     this.currentSnapshotDataURI = currentSnapshot.toDataURL();
 
     if (result[0]) {
       // SUCCESS!
-      ok(true, "Animated image looks correct, at poll #"
-         + this.pollCounter);
+      ok(true, "Animated image looks correct, at poll #" + this.pollCounter);
 
       this.cleanUpAndFinish();
     }
   } else if (!gIsRefImageLoaded) {
-      this.myImage = new Image();
-      this.myImage.onload = reuseImageCallback;
-      document.getElementById(this.imageElementId).setAttribute('src',
-        this.referenceElementId);
-    }
-}
+    this.myImage = new Image();
+    this.myImage.onload = reuseImageCallback;
+    document
+      .getElementById(this.imageElementId)
+      .setAttribute("src", this.referenceElementId);
+  }
+};
 
-AnimationTest.prototype.checkImage = function ()
-{
+AnimationTest.prototype.checkImage = function() {
   if (this.isTestFinished) {
     return;
   }
 
   this.pollCounter++;
 
   // We need this for some tests, because we need to force the
   // test image to be visible.
@@ -253,25 +270,23 @@ AnimationTest.prototype.checkImage = fun
 
   var currentSnapshot = snapshotWindow(window, false);
   var result = compareSnapshots(currentSnapshot, this.referenceSnapshot, true);
 
   this.currentSnapshotDataURI = currentSnapshot.toDataURL();
 
   if (result[0]) {
     // SUCCESS!
-    ok(true, "Animated image looks correct, at poll #"
-       + this.pollCounter);
+    ok(true, "Animated image looks correct, at poll #" + this.pollCounter);
 
     this.cleanUpAndFinish();
   }
 };
 
-AnimationTest.prototype.takeReferenceSnapshot = function ()
-{
+AnimationTest.prototype.takeReferenceSnapshot = function() {
   this.numRefsTaken++;
 
   // Test to make sure the reference image doesn't match a clean snapshot
   if (!this.cleanSnapshot) {
     this.takeCleanSnapshot();
   }
 
   // Used later to verify that the reference div disappeared
@@ -281,132 +296,151 @@ AnimationTest.prototype.takeReferenceSna
 
   if (this.reusingImageAsReference) {
     // Show reference elem (which is actually our image), & take a snapshot
     var referenceElem = document.getElementById(this.imageElementId);
     this.enableDisplay(referenceElem);
 
     this.referenceSnapshot = snapshotWindow(window, false);
 
-    var snapResult = compareSnapshots(this.cleanSnapshot,
-                                      this.referenceSnapshot, false);
+    var snapResult = compareSnapshots(
+      this.cleanSnapshot,
+      this.referenceSnapshot,
+      false
+    );
     if (!snapResult[0]) {
       if (this.blankWaitTime > 2000) {
         // if it took longer than two seconds to load the image, we probably
         // have a problem.
         this.wereFailures = true;
-        ok(snapResult[0],
-           "Reference snapshot shouldn't match clean (non-image) snapshot");
+        ok(
+          snapResult[0],
+          "Reference snapshot shouldn't match clean (non-image) snapshot"
+        );
       } else {
         this.blankWaitTime += currentTest.pollFreq;
         // let's wait a bit and see if it clears up
         setTimeout(referencePoller, currentTest.pollFreq);
         return;
       }
     }
 
-    ok(snapResult[0],
-       "Reference snapshot shouldn't match clean (non-image) snapshot");
+    ok(
+      snapResult[0],
+      "Reference snapshot shouldn't match clean (non-image) snapshot"
+    );
 
     var dataString = "Reference Snapshot #" + this.numRefsTaken;
-    this.outputDebugInfo(dataString, 'refSnapId',
-                         this.referenceSnapshot.toDataURL());
+    this.outputDebugInfo(
+      dataString,
+      "refSnapId",
+      this.referenceSnapshot.toDataURL()
+    );
   } else {
     // Make sure the animation section is hidden
     this.disableDisplay(document.getElementById(this.imageElementId));
 
     // Show reference div, & take a snapshot
     var referenceDiv = document.getElementById(this.referenceElementId);
     this.enableDisplay(referenceDiv);
 
     this.referenceSnapshot = snapshotWindow(window, false);
-    var snapResult = compareSnapshots(this.cleanSnapshot,
-                                      this.referenceSnapshot, false);
+    var snapResult = compareSnapshots(
+      this.cleanSnapshot,
+      this.referenceSnapshot,
+      false
+    );
     if (!snapResult[0]) {
       if (this.blankWaitTime > 2000) {
         // if it took longer than two seconds to load the image, we probably
         // have a problem.
         this.wereFailures = true;
-        ok(snapResult[0],
-           "Reference snapshot shouldn't match clean (non-image) snapshot");
+        ok(
+          snapResult[0],
+          "Reference snapshot shouldn't match clean (non-image) snapshot"
+        );
       } else {
         this.blankWaitTime += 20;
         // let's wait a bit and see if it clears up
         setTimeout(referencePoller, 20);
         return;
       }
     }
 
-    ok(snapResult[0],
-       "Reference snapshot shouldn't match clean (non-image) snapshot");
+    ok(
+      snapResult[0],
+      "Reference snapshot shouldn't match clean (non-image) snapshot"
+    );
 
     var dataString = "Reference Snapshot #" + this.numRefsTaken;
-    this.outputDebugInfo(dataString, 'refSnapId',
-                         this.referenceSnapshot.toDataURL());
+    this.outputDebugInfo(
+      dataString,
+      "refSnapId",
+      this.referenceSnapshot.toDataURL()
+    );
 
     // Re-hide reference div, and take another snapshot to be sure it's gone
     this.disableDisplay(referenceDiv);
     this.testBlankCameBack();
   }
 };
 
-AnimationTest.prototype.enableDisplay = function(element)
-{
+AnimationTest.prototype.enableDisplay = function(element) {
   if (!element) {
     return;
   }
 
   if (!this.xulTest) {
-    element.style.display = '';
+    element.style.display = "";
   } else {
-    element.setAttribute('hidden', 'false');
+    element.setAttribute("hidden", "false");
   }
 };
 
-AnimationTest.prototype.disableDisplay = function(element)
-{
+AnimationTest.prototype.disableDisplay = function(element) {
   if (!element) {
     return;
   }
 
   if (!this.xulTest) {
-    element.style.display = 'none';
+    element.style.display = "none";
   } else {
-    element.setAttribute('hidden', 'true');
+    element.setAttribute("hidden", "true");
   }
 };
 
-AnimationTest.prototype.testBlankCameBack = function()
-{
+AnimationTest.prototype.testBlankCameBack = function() {
   var blankSnapshot2 = snapshotWindow(window, false);
   var result = compareSnapshots(this.blankSnapshot, blankSnapshot2, true);
-  ok(result[0], "Reference image should disappear when it becomes display:none");
+  ok(
+    result[0],
+    "Reference image should disappear when it becomes display:none"
+  );
 
   if (!result[0]) {
     this.wereFailures = true;
     var dataString = "Second Blank Snapshot";
-    this.outputDebugInfo(dataString, 'blank2SnapId', result[2]);
+    this.outputDebugInfo(dataString, "blank2SnapId", result[2]);
   }
 };
 
-AnimationTest.prototype.cleanUpAndFinish = function ()
-{
+AnimationTest.prototype.cleanUpAndFinish = function() {
   // On the off chance that failTest and checkImage are triggered
   // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
   if (this.isTestFinished) {
     return;
   }
 
   this.isTestFinished = true;
 
   // Call our closing function, if one exists
   if (this.closeFunc) {
     this.closeFunc();
     return;
   }
 
   if (this.wereFailures) {
-    document.getElementById(this.debugElementId).style.display = 'block';
+    document.getElementById(this.debugElementId).style.display = "block";
   }
 
   SimpleTest.finish();
   document.getElementById(this.debugElementId).style.display = "";
 };
--- a/image/test/mochitest/imgutils.js
+++ b/image/test/mochitest/imgutils.js
@@ -1,135 +1,141 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 // Helper file for shared image functionality
-// 
+//
 // Note that this is use by tests elsewhere in the source tree. When in doubt,
 // check mxr before removing or changing functionality.
 
 // Helper function to clear both the content and chrome image caches
-function clearAllImageCaches()
-{
-  var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
-                             .getService(SpecialPowers.Ci.imgITools);
+function clearAllImageCaches() {
+  var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService(
+    SpecialPowers.Ci.imgITools
+  );
   var imageCache = tools.getImgCacheForDocument(window.document);
-  imageCache.clearCache(true);  // true=chrome
+  imageCache.clearCache(true); // true=chrome
   imageCache.clearCache(false); // false=content
 }
 
 // Helper function to clear the image cache of content images
-function clearImageCache()
-{
-  var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
-                             .getService(SpecialPowers.Ci.imgITools);
+function clearImageCache() {
+  var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService(
+    SpecialPowers.Ci.imgITools
+  );
   var imageCache = tools.getImgCacheForDocument(window.document);
   imageCache.clearCache(false); // true=chrome, false=content
 }
 
 // Helper function to determine if the frame is decoded for a given image id
-function isFrameDecoded(id)
-{
-  return (getImageStatus(id) &
-          SpecialPowers.Ci.imgIRequest.STATUS_FRAME_COMPLETE)
-         ? true : false;
+function isFrameDecoded(id) {
+  return getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_FRAME_COMPLETE
+    ? true
+    : false;
 }
 
 // Helper function to determine if the image is loaded for a given image id
-function isImageLoaded(id)
-{
-  return (getImageStatus(id) &
-          SpecialPowers.Ci.imgIRequest.STATUS_LOAD_COMPLETE)
-         ? true : false;
+function isImageLoaded(id) {
+  return getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_LOAD_COMPLETE
+    ? true
+    : false;
 }
 
 // Helper function to get the status flags of an image
-function getImageStatus(id)
-{
+function getImageStatus(id) {
   // Get the image
   var img = SpecialPowers.wrap(document.getElementById(id));
 
   // Get the request
-  var request = img.getRequest(SpecialPowers.Ci
-                                         .nsIImageLoadingContent
-                                         .CURRENT_REQUEST);
+  var request = img.getRequest(
+    SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST
+  );
 
   // Return the status
   return request.imageStatus;
 }
 
 // Forces a synchronous decode of an image by drawing it to a canvas. Only
 // really meaningful if the image is fully loaded first
-function forceDecode(id)
-{
+function forceDecode(id) {
   // Get the image
   var img = document.getElementById(id);
 
   // Make a new canvas
   var canvas = document.createElement("canvas");
 
   // Draw the image to the canvas. This forces a synchronous decode
   var ctx = canvas.getContext("2d");
   ctx.drawImage(img, 0, 0);
 }
 
-
 // Functions to facilitate getting/setting various image-related prefs
 //
-// If you change a pref in a mochitest, Don't forget to reset it to its 
+// If you change a pref in a mochitest, Don't forget to reset it to its
 // original value!
 //
 // Null indicates no pref set
 
-const DISCARD_ENABLED_PREF = {name: "discardable", branch: "image.mem.", type: "bool"};
-const DECODEONDRAW_ENABLED_PREF = {name: "decodeondraw", branch: "image.mem.", type: "bool"};
-const DISCARD_TIMEOUT_PREF = {name: "min_discard_timeout_ms", branch: "image.mem.", type: "int"};
+const DISCARD_ENABLED_PREF = {
+  name: "discardable",
+  branch: "image.mem.",
+  type: "bool",
+};
+const DECODEONDRAW_ENABLED_PREF = {
+  name: "decodeondraw",
+  branch: "image.mem.",
+  type: "bool",
+};
+const DISCARD_TIMEOUT_PREF = {
+  name: "min_discard_timeout_ms",
+  branch: "image.mem.",
+  type: "int",
+};
 
-function setImagePref(pref, val)
-{
-  var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
-                                 .getService(SpecialPowers.Ci.nsIPrefService);
+function setImagePref(pref, val) {
+  var prefService = SpecialPowers.Cc[
+    "@mozilla.org/preferences-service;1"
+  ].getService(SpecialPowers.Ci.nsIPrefService);
   var branch = prefService.getBranch(pref.branch);
   if (val != null) {
-    switch(pref.type) {
+    switch (pref.type) {
       case "bool":
         branch.setBoolPref(pref.name, val);
         break;
       case "int":
         branch.setIntPref(pref.name, val);
         break;
       default:
         throw new Error("Unknown pref type");
     }
+  } else if (branch.prefHasUserValue(pref.name)) {
+    branch.clearUserPref(pref.name);
   }
-  else if (branch.prefHasUserValue(pref.name))
-    branch.clearUserPref(pref.name);
 }
 
-function getImagePref(pref)
-{
-  var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
-                                 .getService(SpecialPowers.Ci.nsIPrefService);
+function getImagePref(pref) {
+  var prefService = SpecialPowers.Cc[
+    "@mozilla.org/preferences-service;1"
+  ].getService(SpecialPowers.Ci.nsIPrefService);
   var branch = prefService.getBranch(pref.branch);
   if (branch.prefHasUserValue(pref.name)) {
     switch (pref.type) {
       case "bool":
         return branch.getBoolPref(pref.name);
       case "int":
         return branch.getIntPref(pref.name);
       default:
         throw new Error("Unknown pref type");
     }
+  } else {
+    return null;
   }
-  else
-    return null;
 }
 
 // JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods.
-function ImageDecoderObserverStub()
-{
-  this.sizeAvailable = function sizeAvailable(aRequest)     {}
-  this.frameComplete = function frameComplete(aRequest)     {}
-  this.decodeComplete = function decodeComplete(aRequest)   {}
-  this.loadComplete = function loadComplete(aRequest)       {}
-  this.frameUpdate = function frameUpdate(aRequest)         {}
-  this.discard = function discard(aRequest)                 {}
-  this.isAnimated = function isAnimated(aRequest)           {}
-  this.hasTransparency = function hasTransparency(aRequest) {}
+function ImageDecoderObserverStub() {
+  this.sizeAvailable = function sizeAvailable(aRequest) {};
+  this.frameComplete = function frameComplete(aRequest) {};
+  this.decodeComplete = function decodeComplete(aRequest) {};
+  this.loadComplete = function loadComplete(aRequest) {};
+  this.frameUpdate = function frameUpdate(aRequest) {};
+  this.discard = function discard(aRequest) {};
+  this.isAnimated = function isAnimated(aRequest) {};
+  this.hasTransparency = function hasTransparency(aRequest) {};
 }
--- a/image/test/unit/async_load_tests.js
+++ b/image/test/unit/async_load_tests.js
@@ -1,225 +1,279 @@
 /*
  * Test to ensure that image loading/decoding notifications are always
  * delivered async, and in the order we expect.
  *
  * Must be included from a file that has a uri of the image to test defined in
  * var uri.
  */
 
-const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
-const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 
 var server = new HttpServer();
-server.registerDirectory("/", do_get_file(''));
+server.registerDirectory("/", do_get_file(""));
 server.registerContentType("sjs", "sjs");
 server.start(-1);
 
-
-load('image_load_helpers.js');
+load("image_load_helpers.js");
 
 var requests = [];
 
 // Return a closure that holds on to the listener from the original
 // imgIRequest, and compares its results to the cloned one.
-function getCloneStopCallback(original_listener)
-{
+function getCloneStopCallback(original_listener) {
   return function cloneStop(listener) {
     Assert.equal(original_listener.state, listener.state);
 
     // Sanity check to make sure we didn't accidentally use the same listener
     // twice.
     Assert.notEqual(original_listener, listener);
     do_test_finished();
-  }
+  };
 }
 
 // Make sure that cloned requests get all the same callbacks as the original,
 // but they aren't synchronous right now.
-function checkClone(other_listener, aRequest)
-{
+function checkClone(other_listener, aRequest) {
   do_test_pending();
 
   // For as long as clone notification is synchronous, we can't test the clone state reliably.
-  var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /* getCloneStopCallback(other_listener)*/);
+  var listener = new ImageListener(
+    null,
+    function(foo, bar) {
+      do_test_finished();
+    } /* getCloneStopCallback(other_listener)*/
+  );
   listener.synchronous = false;
-  var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                .createScriptedObserver(listener);
+  var outer = Cc["@mozilla.org/image/tools;1"]
+    .getService(Ci.imgITools)
+    .createScriptedObserver(listener);
   var clone = aRequest.clone(outer);
   requests.push({ request: clone, locked: false });
 }
 
 // Ensure that all the callbacks were called on aRequest.
-function checkSizeAndLoad(listener, aRequest)
-{
+function checkSizeAndLoad(listener, aRequest) {
   Assert.notEqual(listener.state & SIZE_AVAILABLE, 0);
   Assert.notEqual(listener.state & LOAD_COMPLETE, 0);
 
   do_test_finished();
 }
 
-function secondLoadDone(oldlistener, aRequest)
-{
+function secondLoadDone(oldlistener, aRequest) {
   do_test_pending();
 
   try {
     var staticrequest = aRequest.getStaticRequest();
 
     // For as long as clone notification is synchronous, we can't test the
     // clone state reliably.
     var listener = new ImageListener(null, checkSizeAndLoad);
     listener.synchronous = false;
-    var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                  .createScriptedObserver(listener);
+    var outer = Cc["@mozilla.org/image/tools;1"]
+      .getService(Ci.imgITools)
+      .createScriptedObserver(listener);
     var staticrequestclone = staticrequest.clone(outer);
     requests.push({ request: staticrequestclone, locked: false });
-  } catch(e) {
+  } catch (e) {
     // We can't create a static request. Most likely the request we started
     // with didn't load successfully.
     do_test_finished();
   }
 
   run_loadImageWithChannel_tests();
 
   do_test_finished();
 }
 
 // Load the request a second time. This should come from the image cache, and
 // therefore would be at most risk of being served synchronously.
-function checkSecondLoad()
-{
+function checkSecondLoad() {
   do_test_pending();
 
   var listener = new ImageListener(checkClone, secondLoadDone);
-  var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                .createScriptedObserver(listener);
+  var outer = Cc["@mozilla.org/image/tools;1"]
+    .getService(Ci.imgITools)
+    .createScriptedObserver(listener);
   requests.push({
-    request: gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null),
+    request: gCurrentLoader.loadImageXPCOM(
+      uri,
+      null,
+      null,
+      "default",
+      null,
+      null,
+      outer,
+      null,
+      0,
+      null
+    ),
     locked: false,
   });
   listener.synchronous = false;
 }
 
-function firstLoadDone(oldlistener, aRequest)
-{
+function firstLoadDone(oldlistener, aRequest) {
   checkSecondLoad(uri);
 
   do_test_finished();
 }
 
 // Return a closure that allows us to check the stream listener's status when the
 // image finishes loading.
-function getChannelLoadImageStopCallback(streamlistener, next)
-{
+function getChannelLoadImageStopCallback(streamlistener, next) {
   return function channelLoadStop(imglistener, aRequest) {
-
     next();
 
     do_test_finished();
-  }
+  };
 }
 
 // Load the request a second time. This should come from the image cache, and
 // therefore would be at most risk of being served synchronously.
-function checkSecondChannelLoad()
-{
+function checkSecondChannelLoad() {
   do_test_pending();
-  var channel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true});
+  var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true });
   var channellistener = new ChannelListener();
   channel.asyncOpen(channellistener);
 
-  var listener = new ImageListener(null,
-                                   getChannelLoadImageStopCallback(channellistener,
-                                                                   all_done_callback));
-  var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                .createScriptedObserver(listener);
+  var listener = new ImageListener(
+    null,
+    getChannelLoadImageStopCallback(channellistener, all_done_callback)
+  );
+  var outer = Cc["@mozilla.org/image/tools;1"]
+    .getService(Ci.imgITools)
+    .createScriptedObserver(listener);
   var outlistener = {};
   requests.push({
-    request: gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener),
+    request: gCurrentLoader.loadImageWithChannelXPCOM(
+      channel,
+      outer,
+      null,
+      outlistener
+    ),
     locked: false,
   });
   channellistener.outputListener = outlistener.value;
 
   listener.synchronous = false;
 }
 
-function run_loadImageWithChannel_tests()
-{
+function run_loadImageWithChannel_tests() {
   // To ensure we're testing what we expect to, create a new loader and cache.
-  gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
+  gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+    Ci.imgILoader
+  );
 
   do_test_pending();
-  var channel =  NetUtil.newChannel({uri, loadUsingSystemPrincipal: true});
+  var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true });
   var channellistener = new ChannelListener();
   channel.asyncOpen(channellistener);
 
-  var listener = new ImageListener(null,
-                                   getChannelLoadImageStopCallback(channellistener,
-                                                                   checkSecondChannelLoad));
-  var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                .createScriptedObserver(listener);
+  var listener = new ImageListener(
+    null,
+    getChannelLoadImageStopCallback(channellistener, checkSecondChannelLoad)
+  );
+  var outer = Cc["@mozilla.org/image/tools;1"]
+    .getService(Ci.imgITools)
+    .createScriptedObserver(listener);
   var outlistener = {};
   requests.push({
-    request: gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener),
+    request: gCurrentLoader.loadImageWithChannelXPCOM(
+      channel,
+      outer,
+      null,
+      outlistener
+    ),
     locked: false,
   });
   channellistener.outputListener = outlistener.value;
 
   listener.synchronous = false;
 }
 
-function all_done_callback()
-{
-  server.stop(function() { do_test_finished(); });
+function all_done_callback() {
+  server.stop(function() {
+    do_test_finished();
+  });
 }
 
-function startImageCallback(otherCb)
-{
-  return function(listener, request)
-  {
+function startImageCallback(otherCb) {
+  return function(listener, request) {
     // Make sure we can load the same image immediately out of the cache.
     do_test_pending();
-    var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
-    var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                  .createScriptedObserver(listener2);
+    var listener2 = new ImageListener(null, function(foo, bar) {
+      do_test_finished();
+    });
+    var outer = Cc["@mozilla.org/image/tools;1"]
+      .getService(Ci.imgITools)
+      .createScriptedObserver(listener2);
     requests.push({
-      request: gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null),
+      request: gCurrentLoader.loadImageXPCOM(
+        uri,
+        null,
+        null,
+        "default",
+        null,
+        null,
+        outer,
+        null,
+        0,
+        null
+      ),
       locked: false,
     });
     listener2.synchronous = false;
 
     // Now that we've started another load, chain to the callback.
     otherCb(listener, request);
-  }
+  };
 }
 
 var gCurrentLoader;
 
-function cleanup()
-{
-  for (let {request, locked} of requests) {
+function cleanup() {
+  for (let { request, locked } of requests) {
     if (locked) {
-      try { request.unlockImage() } catch (e) {}
+      try {
+        request.unlockImage();
+      } catch (e) {}
     }
     request.cancelAndForgetObserver(0);
   }
 }
 
-function run_test()
-{
+function run_test() {
   registerCleanupFunction(cleanup);
 
-  gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
+  gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+    Ci.imgILoader
+  );
 
   do_test_pending();
-  var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone);
-  var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                .createScriptedObserver(listener);
-  var req = gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null);
+  var listener = new ImageListener(
+    startImageCallback(checkClone),
+    firstLoadDone
+  );
+  var outer = Cc["@mozilla.org/image/tools;1"]
+    .getService(Ci.imgITools)
+    .createScriptedObserver(listener);
+  var req = gCurrentLoader.loadImageXPCOM(
+    uri,
+    null,
+    null,
+    "default",
+    null,
+    null,
+    outer,
+    null,
+    0,
+    null
+  );
 
   // Ensure that we don't cause any mayhem when we lock an image.
   req.lockImage();
 
   requests.push({ request: req, locked: true });
 
   listener.synchronous = false;
 }
--- a/image/test/unit/image_load_helpers.js
+++ b/image/test/unit/image_load_helpers.js
@@ -16,54 +16,47 @@ const FRAME_COMPLETE = 0x04;
 const LOAD_COMPLETE = 0x08;
 const DECODE_COMPLETE = 0x10;
 
 // Safebrowsing requires that the profile dir is set.
 do_get_profile();
 
 // An implementation of imgIScriptedNotificationObserver with the ability to
 // call specified functions on onStartRequest and onStopRequest.
-function ImageListener(start_callback, stop_callback)
-{
-  this.sizeAvailable = function onSizeAvailable(aRequest)
-  {
+function ImageListener(start_callback, stop_callback) {
+  this.sizeAvailable = function onSizeAvailable(aRequest) {
     Assert.ok(!this.synchronous);
 
     this.state |= SIZE_AVAILABLE;
 
-    if (this.start_callback)
+    if (this.start_callback) {
       this.start_callback(this, aRequest);
-  }
-  this.frameComplete = function onFrameComplete(aRequest)
-  {
+    }
+  };
+  this.frameComplete = function onFrameComplete(aRequest) {
     Assert.ok(!this.synchronous);
 
     this.state |= FRAME_COMPLETE;
-  }
-  this.decodeComplete = function onDecodeComplete(aRequest)
-  {
+  };
+  this.decodeComplete = function onDecodeComplete(aRequest) {
     Assert.ok(!this.synchronous);
 
     this.state |= DECODE_COMPLETE;
-  }
-  this.loadComplete = function onLoadcomplete(aRequest)
-  {
+  };
+  this.loadComplete = function onLoadcomplete(aRequest) {
     Assert.ok(!this.synchronous);
 
     this.state |= LOAD_COMPLETE;
 
-    if (this.stop_callback)
+    if (this.stop_callback) {
       this.stop_callback(this, aRequest);
-  }
-  this.frameUpdate = function onFrameUpdate(aRequest)
-  {
-  }
-  this.isAnimated = function onIsAnimated()
-  {
-  }
+    }
+  };
+  this.frameUpdate = function onFrameUpdate(aRequest) {};
+  this.isAnimated = function onIsAnimated() {};
 
   // Initialize the synchronous flag to true to start. This must be set to
   // false before exiting to the event loop!
   this.synchronous = true;
 
   // A function to call when onStartRequest is called.
   this.start_callback = start_callback;
 
@@ -71,51 +64,60 @@ function ImageListener(start_callback, s
   this.stop_callback = stop_callback;
 
   // The image load/decode state.
   // A bitfield that tracks which callbacks have been called. Takes the bits
   // defined above.
   this.state = 0;
 }
 
-function NS_FAILED(val)
-{
+function NS_FAILED(val) {
   return !!(val & 0x80000000);
 }
 
-function ChannelListener()
-{
-  this.onStartRequest = function onStartRequest(aRequest)
-  {
-    if (this.outputListener)
+function ChannelListener() {
+  this.onStartRequest = function onStartRequest(aRequest) {
+    if (this.outputListener) {
       this.outputListener.onStartRequest(aRequest);
+    }
 
     this.requestStatus |= START_REQUEST;
-  }
+  };
 
-  this.onDataAvailable = function onDataAvailable(aRequest, aInputStream, aOffset, aCount)
-  {
-    if (this.outputListener)
-      this.outputListener.onDataAvailable(aRequest, aInputStream, aOffset, aCount);
+  this.onDataAvailable = function onDataAvailable(
+    aRequest,
+    aInputStream,
+    aOffset,
+    aCount
+  ) {
+    if (this.outputListener) {
+      this.outputListener.onDataAvailable(
+        aRequest,
+        aInputStream,
+        aOffset,
+        aCount
+      );
+    }
 
     this.requestStatus |= DATA_AVAILABLE;
-  }
+  };
 
-  this.onStopRequest = function onStopRequest(aRequest, aStatusCode)
-  {
-    if (this.outputListener)
+  this.onStopRequest = function onStopRequest(aRequest, aStatusCode) {
+    if (this.outputListener) {
       this.outputListener.onStopRequest(aRequest, aStatusCode);
+    }
 
     // If we failed (or were canceled - failure is implied if canceled),
     // there's no use tracking our state, since it's meaningless.
-    if (NS_FAILED(aStatusCode))
+    if (NS_FAILED(aStatusCode)) {
       this.requestStatus = 0;
-    else
+    } else {
       this.requestStatus |= STOP_REQUEST;
-  }
+    }
+  };
 
   // A listener to pass the notifications we get to.
   this.outputListener = null;
 
   // The request's status. A bitfield that holds one or both of START_REQUEST
   // and STOP_REQUEST, according to which callbacks have been called on the
   // associated request.
   this.requestStatus = 0;
--- a/image/test/unit/test_async_notification.js
+++ b/image/test/unit/test_async_notification.js
@@ -1,10 +1,13 @@
 /*
  * Test for asynchronous image load/decode notifications in the case that the image load works.
  */
 
 // A simple 3x3 png; rows go red, green, blue. Stolen from the PNG encoder test.
-var pngspec = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
-var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+var pngspec =
+  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
+var ioService = Cc["@mozilla.org/network/io-service;1"].getService(
+  Ci.nsIIOService
+);
 var uri = ioService.newURI(pngspec);
 
-load('async_load_tests.js');
+load("async_load_tests.js");
--- a/image/test/unit/test_async_notification_404.js
+++ b/image/test/unit/test_async_notification_404.js
@@ -1,16 +1,21 @@
 /*
  * Test to ensure that load/decode notifications are delivered completely and
  * asynchronously when dealing with a file that's a 404.
  */
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
 
-var ioService = Cc["@mozilla.org/network/io-service;1"]
-                  .getService(Ci.nsIIOService);
+var ioService = Cc["@mozilla.org/network/io-service;1"].getService(
+  Ci.nsIIOService
+);
 
 XPCOMUtils.defineLazyGetter(this, "uri", function() {
-    return ioService.newURI("http://localhost:" +
-                            server.identity.primaryPort +
-                            "/async-notification-never-here.jpg");
+  return ioService.newURI(
+    "http://localhost:" +
+      server.identity.primaryPort +
+      "/async-notification-never-here.jpg"
+  );
 });
 
-load('async_load_tests.js');
+load("async_load_tests.js");
--- a/image/test/unit/test_async_notification_animated.js
+++ b/image/test/unit/test_async_notification_animated.js
@@ -2,13 +2,16 @@
  * Test for asynchronous image load/decode notifications in the case that the
  * image load works, but for an animated image.
  *
  * If this fails because a request wasn't cancelled, it's possible that
  * imgContainer::ExtractFrame didn't set the new image's status correctly.
  */
 
 // transparent-animation.gif from the gif reftests.
-var spec = "data:image/gif;base64,R0lGODlhZABkAIABAP8AAP///yH5BAkBAAEALAAAAABLAGQAAAK8jI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8YhMKpchgPMJjUqnVOipis1ir9qul+sNV8HistVkTj/JajG7/UXDy+95tm4fy/NdPF/q93dWIqgVWAhwWKgoyPjnyAeZJ2lHOWcJh9mmqcaZ5mkGSreHOCXqRloadRrGGkeoapoa6+TaN0tra4gbq3vHq+q7BVwqrMeEnKy8zNzs/AwdLT1NXW19jZ1tUgAAIfkECQEAAQAsAAAAADQAZAAAArCMj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/7vAAiHxKLxiCRCkswmc+mMSqHSapJqzSof2u4Q67WCw1MuOTs+N9Pqq7kdZcON8vk2aF+/88g6358HaCc4Rwhn2IaopnjGSOYYBukl2UWpZYm2x0enuXnX4NnXGQqAKTYaalqlWoZH+snwWsQah+pJ64Sr5ypbCvQLHCw8TFxsfIycrLzM3PxQAAAh+QQJAQABACwAAAAAGwBkAAACUIyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gTE8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvdrfYnH5LL5jE6r16sCADs=";
-var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+var spec =
+  "data:image/gif;base64,R0lGODlhZABkAIABAP8AAP///yH5BAkBAAEALAAAAABLAGQAAAK8jI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8YhMKpchgPMJjUqnVOipis1ir9qul+sNV8HistVkTj/JajG7/UXDy+95tm4fy/NdPF/q93dWIqgVWAhwWKgoyPjnyAeZJ2lHOWcJh9mmqcaZ5mkGSreHOCXqRloadRrGGkeoapoa6+TaN0tra4gbq3vHq+q7BVwqrMeEnKy8zNzs/AwdLT1NXW19jZ1tUgAAIfkECQEAAQAsAAAAADQAZAAAArCMj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/7vAAiHxKLxiCRCkswmc+mMSqHSapJqzSof2u4Q67WCw1MuOTs+N9Pqq7kdZcON8vk2aF+/88g6358HaCc4Rwhn2IaopnjGSOYYBukl2UWpZYm2x0enuXnX4NnXGQqAKTYaalqlWoZH+snwWsQah+pJ64Sr5ypbCvQLHCw8TFxsfIycrLzM3PxQAAAh+QQJAQABACwAAAAAGwBkAAACUIyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gTE8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvdrfYnH5LL5jE6r16sCADs=";
+var ioService = Cc["@mozilla.org/network/io-service;1"].getService(
+  Ci.nsIIOService
+);
 var uri = ioService.newURI(spec);
 
-load('async_load_tests.js');
+load("async_load_tests.js");
--- a/image/test/unit/test_encoder_apng.js
+++ b/image/test/unit/test_encoder_apng.js
@@ -1,467 +1,1096 @@
 /*
  * Test for APNG encoding in ImageLib
  *
  */
 
-
-  // dispose=[none|background|previous]
-  // blend=[source|over]
+// dispose=[none|background|previous]
+// blend=[source|over]
 
 var apng1A = {
-	// A 3x3 image with 3 frames, alternating red, green, blue. RGB format.
-	width  : 3, height : 3, skipFirstFrame : false,
-	format : Ci.imgIEncoder.INPUT_FORMAT_RGB,
-	transparency : null,
-	plays : 0,
+  // A 3x3 image with 3 frames, alternating red, green, blue. RGB format.
+  width: 3,
+  height: 3,
+  skipFirstFrame: false,
+  format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+  transparency: null,
+  plays: 0,
 
-	frames  : [
-		{ // frame #1
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+  frames: [
+    {
+      // frame #1
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+      stride: 9,
+      transparency: null,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9,
-			transparency : null,
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+      ],
+    },
 
-			pixels : [
-				255,0,0,  255,0,0,  255,0,0,
-				255,0,0,  255,0,0,  255,0,0,
-				255,0,0,  255,0,0,  255,0,0
-				]
-		},
+    {
+      // frame #2
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
 
-		{ // frame #2
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+      stride: 9,
+      transparency: null,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9,
-			transparency : null,
-
-			pixels : [
-				0,255,0,  0,255,0,  0,255,0,
-				0,255,0,  0,255,0,  0,255,0,
-				0,255,0,  0,255,0,  0,255,0
-				]
-		},
-
-		{ // frame #3
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+      pixels: [
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+      ],
+    },
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9,
-			transparency : null,
+    {
+      // frame #3
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+      stride: 9,
+      transparency: null,
 
-			pixels : [
-				0,0,255,  0,0,255,  0,0,255,
-				0,0,255,  0,0,255,  0,0,255,
-				0,0,255,  0,0,255,  0,0,255
-				]
-		}
-
-		],
-	expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABBJREFUCJlj+M/AAEEMWFgAj44I+H2CySsAAAAaZmNUTAAAAAEAAAADAAAAAwAAAAAAAAAAAfQD6AAA7mXKzAAAABNmZEFUAAAAAgiZY2D4zwBFWFgAhpcI+I731VcAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABNmZEFUAAAABAiZY2Bg+A9DmCwAfaAI+AGmQVoAAAAASUVORK5CYII="
+      pixels: [
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABBJREFUCJlj+M/AAEEMWFgAj44I+H2CySsAAAAaZmNUTAAAAAEAAAADAAAAAwAAAAAAAAAAAfQD6AAA7mXKzAAAABNmZEFUAAAAAgiZY2D4zwBFWFgAhpcI+I731VcAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABNmZEFUAAAABAiZY2Bg+A9DmCwAfaAI+AGmQVoAAAAASUVORK5CYII=",
 };
 
-
 var apng1B = {
-	// A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
-	width  : 3, height : 3, skipFirstFrame : false,
-	format : Ci.imgIEncoder.INPUT_FORMAT_RGBA,
-	transparency : null,
-	plays : 0,
+  // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+  width: 3,
+  height: 3,
+  skipFirstFrame: false,
+  format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+  transparency: null,
+  plays: 0,
 
-	frames  : [
-		{ // frame #1
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+  frames: [
+    {
+      // frame #1
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+      ],
+    },
 
-			pixels : [
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255
-				]
-		},
+    {
+      // frame #2
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
 
-		{ // frame #2
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
-
-			pixels : [
-				0,255,0,255,  0,255,0,255,  0,255,0,255,
-				0,255,0,255,  0,255,0,255,  0,255,0,255,
-				0,255,0,255,  0,255,0,255,  0,255,0,255
-				]
-		},
-
-		{ // frame #3
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+      pixels: [
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+      ],
+    },
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+    {
+      // frame #3
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			pixels : [
-				0,0,255,255,  0,0,255,255,  0,0,255,255,
-				0,0,255,255,  0,0,255,255,  0,0,255,255,
-				0,0,255,255,  0,0,255,255,  0,0,255,255
-				]
-		}
-
-		],
-	expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAO5lyswAAAASZmRBVAAAAAIImWNg+I8EcXIAVOAR77Vyl9QAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABRmZEFUAAAABAiZY2Bg+P8fgXFxAEvpEe8rClxSAAAAAElFTkSuQmCC"
+      pixels: [
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAO5lyswAAAASZmRBVAAAAAIImWNg+I8EcXIAVOAR77Vyl9QAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABRmZEFUAAAABAiZY2Bg+P8fgXFxAEvpEe8rClxSAAAAAElFTkSuQmCC",
 };
 
-
 var apng1C = {
-	// A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
-	// The first frame is skipped, so it will only flash green/blue (or static red in an APNG-unaware viewer)
-	width  : 3, height : 3, skipFirstFrame : true,
-	format : Ci.imgIEncoder.INPUT_FORMAT_RGBA,
-	transparency : null,
-	plays : 0,
+  // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+  // The first frame is skipped, so it will only flash green/blue (or static red in an APNG-unaware viewer)
+  width: 3,
+  height: 3,
+  skipFirstFrame: true,
+  format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+  transparency: null,
+  plays: 0,
 
-	frames  : [
-		{ // frame #1
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+  frames: [
+    {
+      // frame #1
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+      ],
+    },
 
-			pixels : [
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255
-				]
-		},
+    {
+      // frame #2
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
 
-		{ // frame #2
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
-
-			pixels : [
-				0,255,0,255,  0,255,0,255,  0,255,0,255,
-				0,255,0,255,  0,255,0,255,  0,255,0,255,
-				0,255,0,255,  0,255,0,255,  0,255,0,255
-				]
-		},
-
-		{ // frame #3
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+      pixels: [
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+      ],
+    },
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+    {
+      // frame #3
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			pixels : [
-				0,0,255,255,  0,0,255,255,  0,0,255,255,
-				0,0,255,255,  0,0,255,255,  0,0,255,255,
-				0,0,255,255,  0,0,255,255,  0,0,255,255
-				]
-		}
-
-		],
-	expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAACAAAAAPONk3AAAAARSURBVAiZY/jPwPAfhhlwcgBd1xHvwqIidQAAABpmY1RMAAAAAAAAAAMAAAADAAAAAAAAAAAB9APoAAB1FiAYAAAAEmZkQVQAAAABCJljYPiPBHFyAFTgEe+kD/2tAAAAGmZjVEwAAAACAAAAAwAAAAMAAAAAAAAAAAH0A+gAAJiA8/EAAAAUZmRBVAAAAAMImWNgYPj/H4FxcQBL6RHvC5ggGQAAAABJRU5ErkJggg=="
+      pixels: [
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAACAAAAAPONk3AAAAARSURBVAiZY/jPwPAfhhlwcgBd1xHvwqIidQAAABpmY1RMAAAAAAAAAAMAAAADAAAAAAAAAAAB9APoAAB1FiAYAAAAEmZkQVQAAAABCJljYPiPBHFyAFTgEe+kD/2tAAAAGmZjVEwAAAACAAAAAwAAAAMAAAAAAAAAAAH0A+gAAJiA8/EAAAAUZmRBVAAAAAMImWNgYPj/H4FxcQBL6RHvC5ggGQAAAABJRU5ErkJggg==",
 };
 
-
 var apng2A = {
-	// A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
-	// blend = over mode
-    // (The green frame is a horizontal gradient, and the blue frame is a
-    // vertical gradient. They stack as they animate.)
-	width  : 3, height : 3, skipFirstFrame : false,
-	format : Ci.imgIEncoder.INPUT_FORMAT_RGBA,
-	transparency : null,
-	plays : 0,
+  // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+  // blend = over mode
+  // (The green frame is a horizontal gradient, and the blue frame is a
+  // vertical gradient. They stack as they animate.)
+  width: 3,
+  height: 3,
+  skipFirstFrame: false,
+  format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+  transparency: null,
+  plays: 0,
+
+  frames: [
+    {
+      // frame #1
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-	frames  : [
-		{ // frame #1
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+      ],
+    },
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+    {
+      // frame #2
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "over",
+      delay: 500,
 
-			pixels : [
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255
-				]
-		},
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-		{ // frame #2
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "over", delay : 500,
-
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
-
-			pixels : [
-				0,255,0,255,  0,255,0,180,  0,255,0,75,
-				0,255,0,255,  0,255,0,180,  0,255,0,75,
-				0,255,0,255,  0,255,0,180,  0,255,0,75
-				]
-		},
+      pixels: [
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        180,
+        0,
+        255,
+        0,
+        75,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        180,
+        0,
+        255,
+        0,
+        75,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        180,
+        0,
+        255,
+        0,
+        75,
+      ],
+    },
 
-		{ // frame #3
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "over", delay : 500,
+    {
+      // frame #3
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "over",
+      delay: 500,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			pixels : [
-				0,0,255,75,   0,0,255,75,   0,0,255,75,
-				0,0,255,180,  0,0,255,180,  0,0,255,180,
-				0,0,255,255,  0,0,255,255,  0,0,255,255
-				]
-		}
-
-		],
-	expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAZli+loAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gAAXT0KbMAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC"
+      pixels: [
+        0,
+        0,
+        255,
+        75,
+        0,
+        0,
+        255,
+        75,
+        0,
+        0,
+        255,
+        75,
+        0,
+        0,
+        255,
+        180,
+        0,
+        0,
+        255,
+        180,
+        0,
+        0,
+        255,
+        180,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAZli+loAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gAAXT0KbMAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC",
 };
 
-
 var apng2B = {
-	// A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
-	// blend = over, dispose = background
-    // (The green frame is a horizontal gradient, and the blue frame is a
-    // vertical gradient. Each frame is displayed individually, blended to
-    // whatever the background is.)
-	width  : 3, height : 3, skipFirstFrame : false,
-	format : Ci.imgIEncoder.INPUT_FORMAT_RGBA,
-	transparency : null,
-	plays : 0,
+  // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format.
+  // blend = over, dispose = background
+  // (The green frame is a horizontal gradient, and the blue frame is a
+  // vertical gradient. Each frame is displayed individually, blended to
+  // whatever the background is.)
+  width: 3,
+  height: 3,
+  skipFirstFrame: false,
+  format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+  transparency: null,
+  plays: 0,
+
+  frames: [
+    {
+      // frame #1
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "background",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-	frames  : [
-		{ // frame #1
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "background",   blend : "source", delay : 500,
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+      ],
+    },
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+    {
+      // frame #2
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "background",
+      blend: "over",
+      delay: 500,
 
-			pixels : [
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255,
-				255,0,0,255,  255,0,0,255,  255,0,0,255
-				]
-		},
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-		{ // frame #2
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "background",   blend : "over", delay : 500,
-
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
-
-			pixels : [
-				0,255,0,255,  0,255,0,180,  0,255,0,75,
-				0,255,0,255,  0,255,0,180,  0,255,0,75,
-				0,255,0,255,  0,255,0,180,  0,255,0,75
-				]
-		},
+      pixels: [
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        180,
+        0,
+        255,
+        0,
+        75,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        180,
+        0,
+        255,
+        0,
+        75,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        180,
+        0,
+        255,
+        0,
+        75,
+      ],
+    },
 
-		{ // frame #3
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "background",   blend : "over", delay : 500,
+    {
+      // frame #3
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "background",
+      blend: "over",
+      delay: 500,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			pixels : [
-				0,0,255,75,   0,0,255,75,   0,0,255,75,
-				0,0,255,180,  0,0,255,180,  0,0,255,180,
-				0,0,255,255,  0,0,255,255,  0,0,255,255
-				]
-		}
-
-		],
-	expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AEAbA0RWQAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gBAYB5yxsAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gBAW3vGPIAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC"
+      pixels: [
+        0,
+        0,
+        255,
+        75,
+        0,
+        0,
+        255,
+        75,
+        0,
+        0,
+        255,
+        75,
+        0,
+        0,
+        255,
+        180,
+        0,
+        0,
+        255,
+        180,
+        0,
+        0,
+        255,
+        180,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        255,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AEAbA0RWQAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gBAYB5yxsAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gBAW3vGPIAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC",
 };
 
-
 var apng3 = {
-	// A 3x3 image with 4 frames. First frame is white, then 1x1 frames draw a diagonal line
-	width  : 3, height : 3, skipFirstFrame : false,
-	format : Ci.imgIEncoder.INPUT_FORMAT_RGBA,
-	transparency : null,
-	plays : 0,
-
-	frames  : [
-		{ // frame #1
-			width  : 3,    height : 3,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
-
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+  // A 3x3 image with 4 frames. First frame is white, then 1x1 frames draw a diagonal line
+  width: 3,
+  height: 3,
+  skipFirstFrame: false,
+  format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+  transparency: null,
+  plays: 0,
 
-			pixels : [
+  frames: [
+    {
+      // frame #1
+      width: 3,
+      height: 3,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
 
-				255,255,255,255,  255,255,255,255,  255,255,255,255,
-				255,255,255,255,  255,255,255,255,  255,255,255,255,
-				255,255,255,255,  255,255,255,255,  255,255,255,255
-				]
-		},
-
-		{ // frame #2
-			width  : 1,    height : 1,
-			x_offset : 0,  y_offset : 0,
-			dispose : "none",   blend : "source", delay : 500,
-
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-			pixels : [
-				0,0,0,255
-				]
-		},
-
-		{ // frame #3
-			width  : 1,    height : 1,
-			x_offset : 1,  y_offset : 1,
-			dispose : "none",   blend : "source", delay : 500,
-
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      pixels: [
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+      ],
+    },
 
-			pixels : [
-				0,0,0,255
-				]
-		},
+    {
+      // frame #2
+      width: 1,
+      height: 1,
+      x_offset: 0,
+      y_offset: 0,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
+
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-		{ // frame #4
-			width  : 1,    height : 1,
-			x_offset : 2,  y_offset : 2,
-			dispose : "none",   blend : "source", delay : 500,
+      pixels: [0, 0, 0, 255],
+    },
+
+    {
+      // frame #3
+      width: 1,
+      height: 1,
+      x_offset: 1,
+      y_offset: 1,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
 
-			format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
+
+      pixels: [0, 0, 0, 255],
+    },
 
-			pixels : [
-				0,0,0,255
-				]
-		}
-		],
+    {
+      // frame #4
+      width: 1,
+      height: 1,
+      x_offset: 2,
+      y_offset: 2,
+      dispose: "none",
+      blend: "source",
+      delay: 500,
 
-	expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAAEAAAAAHzNZtAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAAA5JREFUCJlj+I8EGHByALuHI91kueRqAAAAGmZjVEwAAAABAAAAAQAAAAEAAAAAAAAAAAH0A+gAADJXfawAAAARZmRBVAAAAAIImWNgYGD4DwABBAEAbr5mpgAAABpmY1RMAAAAAwAAAAEAAAABAAAAAQAAAAEB9APoAAC4OHoxAAAAEWZkQVQAAAAECJljYGBg+A8AAQQBAJZ8LRAAAAAaZmNUTAAAAAUAAAABAAAAAQAAAAIAAAACAfQD6AAA/fh01wAAABFmZEFUAAAABgiZY2BgYPgPAAEEAQB3Eum9AAAAAElFTkSuQmCC"
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
+
+      pixels: [0, 0, 0, 255],
+    },
+  ],
+
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAAEAAAAAHzNZtAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAAA5JREFUCJlj+I8EGHByALuHI91kueRqAAAAGmZjVEwAAAABAAAAAQAAAAEAAAAAAAAAAAH0A+gAADJXfawAAAARZmRBVAAAAAIImWNgYGD4DwABBAEAbr5mpgAAABpmY1RMAAAAAwAAAAEAAAABAAAAAQAAAAEB9APoAAC4OHoxAAAAEWZkQVQAAAAECJljYGBg+A8AAQQBAJZ8LRAAAAAaZmNUTAAAAAUAAAABAAAAAQAAAAIAAAACAfQD6AAA/fh01wAAABFmZEFUAAAABgiZY2BgYPgPAAEEAQB3Eum9AAAAAElFTkSuQmCC",
 };
 
 // Main test entry point.
 function run_test() {
-	dump("Checking apng1A...\n");
-	run_test_for(apng1A);
-	dump("Checking apng1B...\n");
-	run_test_for(apng1B);
-	dump("Checking apng1C...\n");
-	run_test_for(apng1C);
+  dump("Checking apng1A...\n");
+  run_test_for(apng1A);
+  dump("Checking apng1B...\n");
+  run_test_for(apng1B);
+  dump("Checking apng1C...\n");
+  run_test_for(apng1C);
 
-	dump("Checking apng2A...\n");
-	run_test_for(apng2A);
-	dump("Checking apng2B...\n");
-	run_test_for(apng2B);
+  dump("Checking apng2A...\n");
+  run_test_for(apng2A);
+  dump("Checking apng2B...\n");
+  run_test_for(apng2B);
 
-	dump("Checking apng3...\n");
-	run_test_for(apng3);
-}; 
-
+  dump("Checking apng3...\n");
+  run_test_for(apng3);
+}
 
 function run_test_for(input) {
-	var encoder, dataURL;
+  var encoder, dataURL;
 
-	encoder = encodeImage(input);
-	dataURL = makeDataURL(encoder, "image/png");
-	Assert.equal(dataURL, input.expected);
-};
-
+  encoder = encodeImage(input);
+  dataURL = makeDataURL(encoder, "image/png");
+  Assert.equal(dataURL, input.expected);
+}
 
 function encodeImage(input) {
-	var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
-	encoder.QueryInterface(Ci.imgIEncoder);
+  var encoder = Cc[
+    "@mozilla.org/image/encoder;2?type=image/png"
+  ].createInstance();
+  encoder.QueryInterface(Ci.imgIEncoder);
 
-	var options = "";
-	if (input.transparency) { options += "transparency=" + input.transparency; }
-	options += ";frames=" + input.frames.length;
-	options += ";skipfirstframe=" + (input.skipFirstFrame ? "yes" : "no");
-	options += ";plays=" + input.plays;
-	encoder.startImageEncode(input.width, input.height, input.format, options);
+  var options = "";
+  if (input.transparency) {
+    options += "transparency=" + input.transparency;
+  }
+  options += ";frames=" + input.frames.length;
+  options += ";skipfirstframe=" + (input.skipFirstFrame ? "yes" : "no");
+  options += ";plays=" + input.plays;
+  encoder.startImageEncode(input.width, input.height, input.format, options);
 
-	for (var i = 0; i < input.frames.length; i++) {
-		var frame = input.frames[i];
+  for (var i = 0; i < input.frames.length; i++) {
+    var frame = input.frames[i];
 
-		options = "";
-		if (frame.transparency) { options += "transparency=" + input.transparency; }
-		options += ";delay=" + frame.delay;
-		options += ";dispose=" + frame.dispose;
-		options += ";blend="   + frame.blend;
-		if (frame.x_offset > 0) { options += ";xoffset=" + frame.x_offset; }
-		if (frame.y_offset > 0) { options += ";yoffset=" + frame.y_offset; }
+    options = "";
+    if (frame.transparency) {
+      options += "transparency=" + input.transparency;
+    }
+    options += ";delay=" + frame.delay;
+    options += ";dispose=" + frame.dispose;
+    options += ";blend=" + frame.blend;
+    if (frame.x_offset > 0) {
+      options += ";xoffset=" + frame.x_offset;
+    }
+    if (frame.y_offset > 0) {
+      options += ";yoffset=" + frame.y_offset;
+    }
 
-		encoder.addImageFrame(frame.pixels, frame.pixels.length,
-			frame.width, frame.height, frame.stride, frame.format, options);
-	}
+    encoder.addImageFrame(
+      frame.pixels,
+      frame.pixels.length,
+      frame.width,
+      frame.height,
+      frame.stride,
+      frame.format,
+      options
+    );
+  }
 
-	encoder.endImageEncode();
+  encoder.endImageEncode();
 
-	return encoder;
+  return encoder;
 }
 
+function makeDataURL(encoder, mimetype) {
+  var rawStream = encoder.QueryInterface(Ci.nsIInputStream);
 
-function makeDataURL(encoder, mimetype) {
-	var rawStream = encoder.QueryInterface(Ci.nsIInputStream);
-
-	var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
-	stream.QueryInterface(Ci.nsIBinaryInputStream);
+  var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
+  stream.QueryInterface(Ci.nsIBinaryInputStream);
 
-	stream.setInputStream(rawStream);
+  stream.setInputStream(rawStream);
 
-	var bytes = stream.readByteArray(stream.available()); // returns int[]
+  var bytes = stream.readByteArray(stream.available()); // returns int[]
 
-	var base64String = toBase64(bytes);
+  var base64String = toBase64(bytes);
 
-	return "data:" + mimetype + ";base64," + base64String;
+  return "data:" + mimetype + ";base64," + base64String;
 }
 
 /* toBase64 copied from extensions/xml-rpc/src/nsXmlRpcClient.js */
 
 /* Convert data (an array of integers) to a Base64 string. */
-const toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +
-    '0123456789+/';
-const base64Pad = '=';
+const toBase64Table =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/";
+const base64Pad = "=";
 function toBase64(data) {
-    var result = '';
-    var length = data.length;
-    var i;
-    // Convert every three bytes to 4 ascii characters.
-    for (i = 0; i < (length - 2); i += 3) {
-        result += toBase64Table[data[i] >> 2];
-        result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
-        result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
-        result += toBase64Table[data[i+2] & 0x3f];
-    }
+  var result = "";
+  var length = data.length;
+  var i;
+  // Convert every three bytes to 4 ascii characters.
+  for (i = 0; i < length - 2; i += 3) {
+    result += toBase64Table[data[i] >> 2];
+    result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+    result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
+    result += toBase64Table[data[i + 2] & 0x3f];
+  }
 
-    // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
-    if (length%3) {
-        i = length - (length%3);
-        result += toBase64Table[data[i] >> 2];
-        if ((length%3) == 2) {
-            result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
-            result += toBase64Table[(data[i+1] & 0x0f) << 2];
-            result += base64Pad;
-        } else {
-            result += toBase64Table[(data[i] & 0x03) << 4];
-            result += base64Pad + base64Pad;
-        }
+  // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
+  if (length % 3) {
+    i = length - (length % 3);
+    result += toBase64Table[data[i] >> 2];
+    if (length % 3 == 2) {
+      result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+      result += toBase64Table[(data[i + 1] & 0x0f) << 2];
+      result += base64Pad;
+    } else {
+      result += toBase64Table[(data[i] & 0x03) << 4];
+      result += base64Pad + base64Pad;
     }
+  }
 
-    return result;
+  return result;
 }
--- a/image/test/unit/test_encoder_png.js
+++ b/image/test/unit/test_encoder_png.js
@@ -1,253 +1,382 @@
 /*
  * Test for PNG encoding in ImageLib
  *
  */
 
 var png1A = {
-        // A 3x3 image, rows are red, green, blue.
-        // RGB format, transparency defaults.
+  // A 3x3 image, rows are red, green, blue.
+  // RGB format, transparency defaults.
+
+  transparency: null,
 
-        transparency : null,
+  frames: [
+    {
+      width: 3,
+      height: 3,
 
-        frames  : [
-                {
-                        width  : 3,    height : 3,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+      stride: 9,
 
-                        format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9,
-
-                        pixels : [
-                                255,0,0,  255,0,0, 255,0,0,
-                                0,255,0,  0,255,0, 0,255,0,
-                                0,0,255,  0,0,255, 0,0,255,
-                                ]
-                }
-
-                ],
-        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=",
 };
 
 var png1B = {
-        // A 3x3 image, rows are red, green, blue.
-        // RGB format, transparency=none.
+  // A 3x3 image, rows are red, green, blue.
+  // RGB format, transparency=none.
+
+  transparency: "none",
 
-        transparency : "none",
+  frames: [
+    {
+      width: 3,
+      height: 3,
 
-        frames  : [
-                {
-                        width  : 3,    height : 3,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGB,
+      stride: 9,
 
-                        format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9,
-
-                        pixels : [
-                                255,0,0,  255,0,0, 255,0,0,
-                                0,255,0,  0,255,0, 0,255,0,
-                                0,0,255,  0,0,255, 0,0,255,
-                                ]
-                }
-
-                ],
-        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+        0,
+        0,
+        255,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=",
 };
 
 var png2A = {
-        // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent.
+  // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent.
 
-        transparency : null,
+  transparency: null,
 
-        frames  : [
-                {
-                        width  : 3,    height : 3,
+  frames: [
+    {
+      width: 3,
+      height: 3,
 
-                        format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-                        pixels : [
-                                255,0,0,255,  255,0,0,170, 255,0,0,85,
-                                0,255,0,255,  0,255,0,170, 0,255,0,85,
-                                0,0,255,255,  0,0,255,170, 0,0,255,85
-                                ]
-                }
-
-                ],
-        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAIElEQVQImSXJMQEAMAwEIUy+yZi8DmVFFBcjycn86GgPJw4O8v9DkkEAAAAASUVORK5CYII="
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        170,
+        255,
+        0,
+        0,
+        85,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        170,
+        0,
+        255,
+        0,
+        85,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        170,
+        0,
+        0,
+        255,
+        85,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAIElEQVQImSXJMQEAMAwEIUy+yZi8DmVFFBcjycn86GgPJw4O8v9DkkEAAAAASUVORK5CYII=",
 };
 
 var png2B = {
-        // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent,
-        // but transparency will be ignored.
+  // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent,
+  // but transparency will be ignored.
+
+  transparency: "none",
 
-        transparency : "none",
+  frames: [
+    {
+      width: 3,
+      height: 3,
 
-        frames  : [
-                {
-                        width  : 3,    height : 3,
+      format: Ci.imgIEncoder.INPUT_FORMAT_RGBA,
+      stride: 12,
 
-                        format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
-
-                        pixels : [
-                                255,0,0,255,  255,0,0,170, 255,0,0,85,
-                                0,255,0,255,  0,255,0,170, 0,255,0,85,
-                                0,0,255,255,  0,0,255,170, 0,0,255,85
-                                ]
-                }
-
-                ],
-        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
+      pixels: [
+        255,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        170,
+        255,
+        0,
+        0,
+        85,
+        0,
+        255,
+        0,
+        255,
+        0,
+        255,
+        0,
+        170,
+        0,
+        255,
+        0,
+        85,
+        0,
+        0,
+        255,
+        255,
+        0,
+        0,
+        255,
+        170,
+        0,
+        0,
+        255,
+        85,
+      ],
+    },
+  ],
+  expected:
+    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=",
 };
 
 // Main test entry point.
 function run_test() {
-        dump("Checking png1A...\n")
-        run_test_for(png1A);
-        dump("Checking png1B...\n")
-        run_test_for(png1B);
-        dump("Checking png2A...\n")
-        run_test_for(png2A);
-        dump("Checking png2B...\n")
-        run_test_for(png2B);
-}; 
-
+  dump("Checking png1A...\n");
+  run_test_for(png1A);
+  dump("Checking png1B...\n");
+  run_test_for(png1B);
+  dump("Checking png2A...\n");
+  run_test_for(png2A);
+  dump("Checking png2B...\n");
+  run_test_for(png2B);
+}
 
 function run_test_for(input) {
-        var encoder, dataURL;
+  var encoder, dataURL;
 
-        encoder = encodeImage(input);
-        dataURL = makeDataURL(encoder, "image/png");
-        Assert.equal(dataURL, input.expected);
+  encoder = encodeImage(input);
+  dataURL = makeDataURL(encoder, "image/png");
+  Assert.equal(dataURL, input.expected);
 
-        encoder = encodeImageAsync(input);
-        dataURL = makeDataURLFromAsync(encoder, "image/png", input.expected);
-};
-
+  encoder = encodeImageAsync(input);
+  dataURL = makeDataURLFromAsync(encoder, "image/png", input.expected);
+}
 
 function encodeImage(input) {
-        var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
-        encoder.QueryInterface(Ci.imgIEncoder);
+  var encoder = Cc[
+    "@mozilla.org/image/encoder;2?type=image/png"
+  ].createInstance();
+  encoder.QueryInterface(Ci.imgIEncoder);
+
+  var options = "";
+  if (input.transparency) {
+    options += "transparency=" + input.transparency;
+  }
 
-        var options = "";
-        if (input.transparency) {
-                options += "transparency=" + input.transparency;
-        }
-
-        var frame = input.frames[0];
-        encoder.initFromData(frame.pixels, frame.pixels.length,
-                                frame.width, frame.height, frame.stride,
-                                frame.format, options);
-        return encoder;
+  var frame = input.frames[0];
+  encoder.initFromData(
+    frame.pixels,
+    frame.pixels.length,
+    frame.width,
+    frame.height,
+    frame.stride,
+    frame.format,
+    options
+  );
+  return encoder;
 }
 
-function _encodeImageAsyncFactory(frame, options, encoder)
-{
-        function finishEncode() {
-            encoder.addImageFrame(frame.pixels, frame.pixels.length,
-                                  frame.width, frame.height, frame.stride,
-                                  frame.format, options);
-            encoder.endImageEncode();
-        }
-        return finishEncode;
+function _encodeImageAsyncFactory(frame, options, encoder) {
+  function finishEncode() {
+    encoder.addImageFrame(
+      frame.pixels,
+      frame.pixels.length,
+      frame.width,
+      frame.height,
+      frame.stride,
+      frame.format,
+      options
+    );
+    encoder.endImageEncode();
+  }
+  return finishEncode;
 }
 
-function encodeImageAsync(input)
-{
-        var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
-        encoder.QueryInterface(Ci.imgIEncoder);
+function encodeImageAsync(input) {
+  var encoder = Cc[
+    "@mozilla.org/image/encoder;2?type=image/png"
+  ].createInstance();
+  encoder.QueryInterface(Ci.imgIEncoder);
 
-        var options = "";
-        if (input.transparency) {
-                options += "transparency=" + input.transparency;
-        }
+  var options = "";
+  if (input.transparency) {
+    options += "transparency=" + input.transparency;
+  }
 
-        var frame = input.frames[0];
-        encoder.startImageEncode(frame.width, frame.height,
-                                 frame.format, options);
+  var frame = input.frames[0];
+  encoder.startImageEncode(frame.width, frame.height, frame.format, options);
 
-        do_timeout(50, _encodeImageAsyncFactory(frame, options, encoder));
-        return encoder;
+  do_timeout(50, _encodeImageAsyncFactory(frame, options, encoder));
+  return encoder;
 }
 
+function makeDataURL(encoder, mimetype) {
+  var rawStream = encoder.QueryInterface(Ci.nsIInputStream);
 
-function makeDataURL(encoder, mimetype) {
-        var rawStream = encoder.QueryInterface(Ci.nsIInputStream);
-
-        var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
-        stream.QueryInterface(Ci.nsIBinaryInputStream);
+  var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
+  stream.QueryInterface(Ci.nsIBinaryInputStream);
 
-        stream.setInputStream(rawStream);
+  stream.setInputStream(rawStream);
 
-        var bytes = stream.readByteArray(stream.available()); // returns int[]
+  var bytes = stream.readByteArray(stream.available()); // returns int[]
 
-        var base64String = toBase64(bytes);
+  var base64String = toBase64(bytes);
 
-        return "data:" + mimetype + ";base64," + base64String;
+  return "data:" + mimetype + ";base64," + base64String;
 }
 
 function makeDataURLFromAsync(encoder, mimetype, expected) {
-        do_test_pending();
-        var rawStream = encoder.QueryInterface(Ci.nsIAsyncInputStream);
-
-        var currentThread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
+  do_test_pending();
+  var rawStream = encoder.QueryInterface(Ci.nsIAsyncInputStream);
 
-        var bytes = [];
+  var currentThread = Cc["@mozilla.org/thread-manager;1"].getService()
+    .currentThread;
 
-        var binarystream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
-        binarystream.QueryInterface(Ci.nsIBinaryInputStream);
+  var bytes = [];
+
+  var binarystream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
+  binarystream.QueryInterface(Ci.nsIBinaryInputStream);
 
-        var asyncReader =
-        {
-            onInputStreamReady(stream)
-            {
-                binarystream.setInputStream(stream);
-                var available = 0;
-                try {
-                  available = stream.available();
-                } catch(e) { }
+  var asyncReader = {
+    onInputStreamReady(stream) {
+      binarystream.setInputStream(stream);
+      var available = 0;
+      try {
+        available = stream.available();
+      } catch (e) {}
 
-                if (available > 0)
-                {
-                    bytes = bytes.concat(binarystream.readByteArray(available));
-                    stream.asyncWait(this, 0, 0, currentThread);
-                } else {
-                    var base64String = toBase64(bytes);
-                    var dataURL = "data:" + mimetype + ";base64," + base64String;
-                    Assert.equal(dataURL, expected);
-                    do_test_finished();
-                }
-
-            }
-        };
-        rawStream.asyncWait(asyncReader, 0, 0, currentThread);
+      if (available > 0) {
+        bytes = bytes.concat(binarystream.readByteArray(available));
+        stream.asyncWait(this, 0, 0, currentThread);
+      } else {
+        var base64String = toBase64(bytes);
+        var dataURL = "data:" + mimetype + ";base64," + base64String;
+        Assert.equal(dataURL, expected);
+        do_test_finished();
+      }
+    },
+  };
+  rawStream.asyncWait(asyncReader, 0, 0, currentThread);
 }
 
 /* toBase64 copied from extensions/xml-rpc/src/nsXmlRpcClient.js */
 
 /* Convert data (an array of integers) to a Base64 string. */
-const toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +
-    '0123456789+/';
-const base64Pad = '=';
+const toBase64Table =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/";
+const base64Pad = "=";
 function toBase64(data) {
-    var result = '';
-    var length = data.length;
-    var i;
-    // Convert every three bytes to 4 ascii characters.
-    for (i = 0; i < (length - 2); i += 3) {
-        result += toBase64Table[data[i] >> 2];
-        result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
-        result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
-        result += toBase64Table[data[i+2] & 0x3f];
-    }
+  var result = "";
+  var length = data.length;
+  var i;
+  // Convert every three bytes to 4 ascii characters.
+  for (i = 0; i < length - 2; i += 3) {
+    result += toBase64Table[data[i] >> 2];
+    result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+    result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
+    result += toBase64Table[data[i + 2] & 0x3f];
+  }
 
-    // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
-    if (length%3) {
-        i = length - (length%3);
-        result += toBase64Table[data[i] >> 2];
-        if ((length%3) == 2) {
-            result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
-            result += toBase64Table[(data[i+1] & 0x0f) << 2];
-            result += base64Pad;
-        } else {
-            result += toBase64Table[(data[i] & 0x03) << 4];
-            result += base64Pad + base64Pad;
-        }
+  // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
+  if (length % 3) {
+    i = length - (length % 3);
+    result += toBase64Table[data[i] >> 2];
+    if (length % 3 == 2) {
+      result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+      result += toBase64Table[(data[i + 1] & 0x0f) << 2];
+      result += base64Pad;
+    } else {
+      result += toBase64Table[(data[i] & 0x03) << 4];
+      result += base64Pad + base64Pad;
     }
+  }
 
-    return result;
+  return result;
 }
--- a/image/test/unit/test_imgtools.js
+++ b/image/test/unit/test_imgtools.js
@@ -1,742 +1,797 @@
 /*
  * Tests for imgITools
  */
 
-const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 
 /*
  * dumpToFile()
  *
  * For test development, dumps the specified array to a file.
  * Call |dumpToFile(outData);| in a test to file to a file.
  */
 function dumpToFile(aData) {
-    var outputFile = do_get_tempdir();
-    outputFile.append("testdump.png");
+  var outputFile = do_get_tempdir();
+  outputFile.append("testdump.png");
 
-    var outputStream = Cc["@mozilla.org/network/file-output-stream;1"].
-                       createInstance(Ci.nsIFileOutputStream);
-    // WR_ONLY|CREAT|TRUNC
-    outputStream.init(outputFile, 0x02 | 0x08 | 0x20, 0o644, null);
+  var outputStream = Cc[
+    "@mozilla.org/network/file-output-stream;1"
+  ].createInstance(Ci.nsIFileOutputStream);
+  // WR_ONLY|CREAT|TRUNC
+  outputStream.init(outputFile, 0x02 | 0x08 | 0x20, 0o644, null);
 
-    var bos = Cc["@mozilla.org/binaryoutputstream;1"].
-              createInstance(Ci.nsIBinaryOutputStream);
-    bos.setOutputStream(outputStream);
+  var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(
+    Ci.nsIBinaryOutputStream
+  );
+  bos.setOutputStream(outputStream);
 
-    bos.writeByteArray(aData, aData.length);
+  bos.writeByteArray(aData, aData.length);
 
-    outputStream.close();
+  outputStream.close();
 }
 
-
 /*
  * getFileInputStream()
  *
  * Returns an input stream for the specified file.
  */
 function getFileInputStream(aFile) {
-    var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].
-                      createInstance(Ci.nsIFileInputStream);
-    // init the stream as RD_ONLY, -1 == default permissions.
-    inputStream.init(aFile, 0x01, -1, null);
+  var inputStream = Cc[
+    "@mozilla.org/network/file-input-stream;1"
+  ].createInstance(Ci.nsIFileInputStream);
+  // init the stream as RD_ONLY, -1 == default permissions.
+  inputStream.init(aFile, 0x01, -1, null);
 
-    // Blah. The image decoders use ReadSegments, which isn't implemented on
-    // file input streams. Use a buffered stream to make it work.
-    var bis = Cc["@mozilla.org/network/buffered-input-stream;1"].
-              createInstance(Ci.nsIBufferedInputStream);
-    bis.init(inputStream, 1024);
+  // Blah. The image decoders use ReadSegments, which isn't implemented on
+  // file input streams. Use a buffered stream to make it work.
+  var bis = Cc["@mozilla.org/network/buffered-input-stream;1"].createInstance(
+    Ci.nsIBufferedInputStream
+  );
+  bis.init(inputStream, 1024);
 
-    return bis;
+  return bis;
 }
 
-
 /*
  * streamToArray()
  *
  * Consumes an input stream, and returns its bytes as an array.
  */
 function streamToArray(aStream) {
-    var size = aStream.available();
+  var size = aStream.available();
 
-    // use a binary input stream to grab the bytes.
-    var bis = Cc["@mozilla.org/binaryinputstream;1"].
-              createInstance(Ci.nsIBinaryInputStream);
-    bis.setInputStream(aStream);
+  // use a binary input stream to grab the bytes.
+  var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+    Ci.nsIBinaryInputStream
+  );
+  bis.setInputStream(aStream);
 
-    var bytes = bis.readByteArray(size);
-    if (size != bytes.length)
-        throw "Didn't read expected number of bytes";
+  var bytes = bis.readByteArray(size);
+  if (size != bytes.length) {
+    throw "Didn't read expected number of bytes";
+  }
 
-    return bytes;
+  return bytes;
 }
 
-
 /*
  * compareArrays
  *
  * Compares two arrays, and throws if there's a difference.
  */
 function compareArrays(aArray1, aArray2) {
-    Assert.equal(aArray1.length, aArray2.length);
+  Assert.equal(aArray1.length, aArray2.length);
 
-    for (var i = 0; i < aArray1.length; i++)
-        if (aArray1[i] != aArray2[i])
-            throw "arrays differ at index " + i;
+  for (var i = 0; i < aArray1.length; i++) {
+    if (aArray1[i] != aArray2[i]) {
+      throw "arrays differ at index " + i;
+    }
+  }
 }
 
-
 /*
  * checkExpectedError
  *
  * Checks to see if a thrown error was expected or not, and if it
  * matches the expected value.
  */
-function checkExpectedError (aExpectedError, aActualError) {
+function checkExpectedError(aExpectedError, aActualError) {
   if (aExpectedError) {
-      if (!aActualError)
-          throw "Didn't throw as expected (" + aExpectedError + ")";
+    if (!aActualError) {
+      throw "Didn't throw as expected (" + aExpectedError + ")";
+    }
 
-      if (!aExpectedError.test(aActualError))
-          throw "Threw (" + aActualError + "), not (" + aExpectedError;
+    if (!aExpectedError.test(aActualError)) {
+      throw "Threw (" + aActualError + "), not (" + aExpectedError;
+    }
 
-      // We got the expected error, so make a note in the test log.
-      dump("...that error was expected.\n\n");
+    // We got the expected error, so make a note in the test log.
+    dump("...that error was expected.\n\n");
   } else if (aActualError) {
-      throw "Threw unexpected error: " + aActualError;
+    throw "Threw unexpected error: " + aActualError;
   }
 }
 
-
 function run_test() {
-
-try {
-
-
-/* ========== 0 ========== */
-var testnum = 0;
-var testdesc = "imgITools setup";
-var err = null;
-
-var imgTools = Cc["@mozilla.org/image/tools;1"].
-               getService(Ci.imgITools);
-
-if (!imgTools)
-    throw "Couldn't get imgITools service"
-
-// Ugh, this is an ugly hack. The pixel values we get in Windows are sometimes
-// +/- 1 value compared to other platforms, so we need to compare against a
-// different set of reference images. nsIXULRuntime.OS doesn't seem to be
-// available in xpcshell, so we'll use this as a kludgy way to figure out if
-// we're running on Windows.
-var isWindows = mozinfo.os == "win";
-
-
-/* ========== 1 ========== */
-testnum++;
-testdesc = "test decoding a PNG";
-
-// 64x64 png, 8415 bytes.
-var imgName = "image1.png";
-var inMimeType = "image/png";
-var imgFile = do_get_file(imgName);
-
-var istream = getFileInputStream(imgFile);
-Assert.equal(istream.available(), 8415);
-
-var buffer = NetUtil.readInputStreamToString(istream, istream.available());
-var container = imgTools.decodeImageFromBuffer(buffer, buffer.length,
-                                               inMimeType);
-
-// It's not easy to look at the pixel values from JS, so just
-// check the container's size.
-Assert.equal(container.width,  64);
-Assert.equal(container.height, 64);
-
-
-/* ========== 2 ========== */
-testnum++;
-testdesc = "test encoding a scaled JPEG";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 16);
-
-var encodedBytes = streamToArray(istream);
-// Get bytes for exected result
-var refName = "image1png16x16.jpg";
-var refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1051);
-var referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 3 ========== */
-testnum++;
-testdesc = "test encoding an unscaled JPEG";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeImage(container, "image/jpeg");
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image1png64x64.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 4503);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 4 ========== */
-testnum++;
-testdesc = "test decoding a JPEG";
-
-// 32x32 jpeg, 3494 bytes.
-imgName = "image2.jpg";
-inMimeType = "image/jpeg";
-imgFile = do_get_file(imgName);
-
-istream = getFileInputStream(imgFile);
-Assert.equal(istream.available(), 3494);
-
-buffer = NetUtil.readInputStreamToString(istream, istream.available());
-container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType);
-
-// It's not easy to look at the pixel values from JS, so just
-// check the container's size.
-Assert.equal(container.width,  32);
-Assert.equal(container.height, 32);
-
-
-/* ========== 5 ========== */
-testnum++;
-testdesc = "test encoding a scaled PNG";
-
-if (!isWindows) {
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container, "image/png", 16, 16);
-
-encodedBytes = streamToArray(istream);
-// Get bytes for exected result
-refName = isWindows ? "image2jpg16x16-win.png" : "image2jpg16x16.png";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 950);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-}
-
-
-/* ========== 6 ========== */
-testnum++;
-testdesc = "test encoding an unscaled PNG";
+  try {
+    /* ========== 0 ========== */
+    var testnum = 0;
+    var testdesc = "imgITools setup";
+    var err = null;
 
-if (!isWindows) {
-// we'll reuse the container from the previous test
-istream = imgTools.encodeImage(container, "image/png");
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = isWindows ? "image2jpg32x32-win.png" : "image2jpg32x32.png";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 3105);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-}
-
-
-/* ========== 7 ========== */
-testnum++;
-testdesc = "test decoding a ICO";
-
-// 16x16 ico, 1406 bytes.
-imgName = "image3.ico";
-inMimeType = "image/x-icon";
-imgFile = do_get_file(imgName);
-
-istream = getFileInputStream(imgFile);
-Assert.equal(istream.available(), 1406);
-
-buffer = NetUtil.readInputStreamToString(istream, istream.available());
-container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType);
-
-// It's not easy to look at the pixel values from JS, so just
-// check the container's size.
-Assert.equal(container.width,  16);
-Assert.equal(container.height, 16);
-
-
-/* ========== 8 ========== */
-testnum++;
-testdesc = "test encoding a scaled PNG"; // note that we're scaling UP
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container, "image/png", 32, 32);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image3ico32x32.png";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 2285);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 9 ========== */
-testnum++;
-testdesc = "test encoding an unscaled PNG";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeImage(container, "image/png");
-encodedBytes = streamToArray(istream);
+    var imgTools = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools);
 
-// Get bytes for exected result
-refName = "image3ico16x16.png";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 330);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 10 ========== */
-testnum++;
-testdesc = "test decoding a GIF";
-
-// 32x32 gif, 1809 bytes.
-imgName = "image4.gif";
-inMimeType = "image/gif";
-imgFile = do_get_file(imgName);
-
-istream = getFileInputStream(imgFile);
-Assert.equal(istream.available(), 1809);
-
-buffer = NetUtil.readInputStreamToString(istream, istream.available());
-container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType);
-
-// It's not easy to look at the pixel values from JS, so just
-// check the container's size.
-Assert.equal(container.width, 32);
-Assert.equal(container.height, 32);
-
-/* ========== 11 ========== */
-testnum++;
-testdesc = "test encoding an unscaled ICO with format options " +
-           "(format=bmp;bpp=32)";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeImage(container,
-                               "image/vnd.microsoft.icon",
-                               "format=bmp;bpp=32");
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image4gif32x32bmp32bpp.ico";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 4286);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-/* ========== 12 ========== */
-testnum++;
-testdesc = "test encoding a scaled ICO with format options " +
-           "(format=bmp;bpp=32)";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container,
-                                     "image/vnd.microsoft.icon",
-                                     16,
-                                     16,
-                                     "format=bmp;bpp=32");
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image4gif16x16bmp32bpp.ico";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1150);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
+    if (!imgTools) {
+      throw "Couldn't get imgITools service";
+    }
 
-/* ========== 13 ========== */
-testnum++;
-testdesc = "test encoding an unscaled ICO with format options " +
-           "(format=bmp;bpp=24)";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeImage(container,
-                               "image/vnd.microsoft.icon",
-                               "format=bmp;bpp=24");
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image4gif32x32bmp24bpp.ico";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 3262);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-/* ========== 14 ========== */
-testnum++;
-testdesc = "test encoding a scaled ICO with format options " +
-           "(format=bmp;bpp=24)";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container,
-                                     "image/vnd.microsoft.icon",
-                                     16,
-                                     16,
-                                     "format=bmp;bpp=24");
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image4gif16x16bmp24bpp.ico";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 894);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 15 ========== */
-testnum++;
-testdesc = "test cropping a JPG";
-
-// 32x32 jpeg, 3494 bytes.
-imgName = "image2.jpg";
-inMimeType = "image/jpeg";
-imgFile = do_get_file(imgName);
-
-istream = getFileInputStream(imgFile);
-Assert.equal(istream.available(), 3494);
-
-buffer = NetUtil.readInputStreamToString(istream, istream.available());
-container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType);
-
-// It's not easy to look at the pixel values from JS, so just
-// check the container's size.
-Assert.equal(container.width,  32);
-Assert.equal(container.height, 32);
-
-// encode a cropped image
-istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 16, 16);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image2jpg16x16cropped.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 879);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 16 ========== */
-testnum++;
-testdesc = "test cropping a JPG with an offset";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeCroppedImage(container, "image/jpeg", 16, 16, 16, 16);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image2jpg16x16cropped2.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 878);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 17 ========== */
-testnum++;
-testdesc = "test cropping a JPG without a given height";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 16, 0);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image2jpg16x32cropped3.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1127);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 18 ========== */
-testnum++;
-testdesc = "test cropping a JPG without a given width";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 16);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image2jpg32x16cropped4.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1135);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
+    // Ugh, this is an ugly hack. The pixel values we get in Windows are sometimes
+    // +/- 1 value compared to other platforms, so we need to compare against a
+    // different set of reference images. nsIXULRuntime.OS doesn't seem to be
+    // available in xpcshell, so we'll use this as a kludgy way to figure out if
+    // we're running on Windows.
+    var isWindows = mozinfo.os == "win";
 
-/* ========== 19 ========== */
-testnum++;
-testdesc = "test cropping a JPG without a given width and height";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 0);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image2jpg32x32.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1634);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 20 ========== */
-testnum++;
-testdesc = "test scaling a JPG without a given width";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 16);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image2jpg32x16scaled.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1227);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 21 ========== */
-testnum++;
-testdesc = "test scaling a JPG without a given height";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 0);
-encodedBytes = streamToArray(istream);
-
-// Get bytes for exected result
-refName = "image2jpg16x32scaled.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1219);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 22 ========== */
-testnum++;
-testdesc = "test scaling a JPG without a given width and height";
-
-// we'll reuse the container from the previous test
-istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 0);
-encodedBytes = streamToArray(istream);
+    /* ========== 1 ========== */
+    testnum++;
+    testdesc = "test decoding a PNG";
 
-// Get bytes for exected result
-refName = "image2jpg32x32.jpg";
-refFile = do_get_file(refName);
-istream = getFileInputStream(refFile);
-Assert.equal(istream.available(), 1634);
-referenceBytes = streamToArray(istream);
-
-// compare the encoder's output to the reference file.
-compareArrays(encodedBytes, referenceBytes);
-
-
-/* ========== 22 ========== */
-testnum++;
-testdesc = "test invalid arguments for cropping";
-
-var numErrors = 0;
-
-try {
-  // width/height can't be negative
-  imgTools.encodeScaledImage(container, "image/jpeg", -1, -1);
-} catch (e) { numErrors++; }
-
-try {
-  // offsets can't be negative
-  imgTools.encodeCroppedImage(container, "image/jpeg", -1, -1, 16, 16);
-} catch (e) { numErrors++; }
-
-try {
-  // width/height can't be negative
-  imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, -1, -1);
-} catch (e) { numErrors++; }
-
-try {
-  // out of bounds
-  imgTools.encodeCroppedImage(container, "image/jpeg", 17, 17, 16, 16);
-} catch (e) { numErrors++; }
+    // 64x64 png, 8415 bytes.
+    var imgName = "image1.png";
+    var inMimeType = "image/png";
+    var imgFile = do_get_file(imgName);
 
-try {
-  // out of bounds
-  imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 33, 33);
-} catch (e) { numErrors++; }
-
-try {
-  // out of bounds
-  imgTools.encodeCroppedImage(container, "image/jpeg", 1, 1, 0, 0);
-} catch (e) { numErrors++; }
-
-Assert.equal(numErrors, 6);
-
-
-/* ========== bug 363986 ========== */
-testnum = 363986;
-testdesc = "test PNG and JPEG encoders' Read/ReadSegments methods";
-
-var testData = 
-    [{preImage: "image3.ico",
-      preImageMimeType: "image/x-icon",
-      refImage: "image3ico16x16.png",
-      refImageMimeType: "image/png"},
-     {preImage: "image1.png",
-      preImageMimeType: "image/png",
-      refImage: "image1png64x64.jpg",
-      refImageMimeType: "image/jpeg"}];
-
-for(var i=0; i<testData.length; ++i) {
-    var dict = testData[i];
-
-    var imgFile = do_get_file(dict.refImage);
     var istream = getFileInputStream(imgFile);
-    var refBytes = streamToArray(istream);
-
-    imgFile = do_get_file(dict.preImage);
-    istream = getFileInputStream(imgFile);
+    Assert.equal(istream.available(), 8415);
 
     var buffer = NetUtil.readInputStreamToString(istream, istream.available());
-    var container = imgTools.decodeImageFromBuffer(buffer, buffer.length,
-                                                   dict.preImageMimeType);
+    var container = imgTools.decodeImageFromBuffer(
+      buffer,
+      buffer.length,
+      inMimeType
+    );
+
+    // It's not easy to look at the pixel values from JS, so just
+    // check the container's size.
+    Assert.equal(container.width, 64);
+    Assert.equal(container.height, 64);
+
+    /* ========== 2 ========== */
+    testnum++;
+    testdesc = "test encoding a scaled JPEG";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 16);
+
+    var encodedBytes = streamToArray(istream);
+    // Get bytes for exected result
+    var refName = "image1png16x16.jpg";
+    var refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1051);
+    var referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 3 ========== */
+    testnum++;
+    testdesc = "test encoding an unscaled JPEG";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeImage(container, "image/jpeg");
+    encodedBytes = streamToArray(istream);
 
-    istream = imgTools.encodeImage(container, dict.refImageMimeType);
+    // Get bytes for exected result
+    refName = "image1png64x64.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 4503);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 4 ========== */
+    testnum++;
+    testdesc = "test decoding a JPEG";
+
+    // 32x32 jpeg, 3494 bytes.
+    imgName = "image2.jpg";
+    inMimeType = "image/jpeg";
+    imgFile = do_get_file(imgName);
+
+    istream = getFileInputStream(imgFile);
+    Assert.equal(istream.available(), 3494);
+
+    buffer = NetUtil.readInputStreamToString(istream, istream.available());
+    container = imgTools.decodeImageFromBuffer(
+      buffer,
+      buffer.length,
+      inMimeType
+    );
+
+    // It's not easy to look at the pixel values from JS, so just
+    // check the container's size.
+    Assert.equal(container.width, 32);
+    Assert.equal(container.height, 32);
+
+    /* ========== 5 ========== */
+    testnum++;
+    testdesc = "test encoding a scaled PNG";
 
-    var sstream = Cc["@mozilla.org/storagestream;1"].
-	          createInstance(Ci.nsIStorageStream);
-    sstream.init(4096, 4294967295, null);
-    var ostream = sstream.getOutputStream(0);
-    var bostream = Cc["@mozilla.org/network/buffered-output-stream;1"].
-	           createInstance(Ci.nsIBufferedOutputStream);
+    if (!isWindows) {
+      // we'll reuse the container from the previous test
+      istream = imgTools.encodeScaledImage(container, "image/png", 16, 16);
+
+      encodedBytes = streamToArray(istream);
+      // Get bytes for exected result
+      refName = isWindows ? "image2jpg16x16-win.png" : "image2jpg16x16.png";
+      refFile = do_get_file(refName);
+      istream = getFileInputStream(refFile);
+      Assert.equal(istream.available(), 950);
+      referenceBytes = streamToArray(istream);
+
+      // compare the encoder's output to the reference file.
+      compareArrays(encodedBytes, referenceBytes);
+    }
+
+    /* ========== 6 ========== */
+    testnum++;
+    testdesc = "test encoding an unscaled PNG";
+
+    if (!isWindows) {
+      // we'll reuse the container from the previous test
+      istream = imgTools.encodeImage(container, "image/png");
+      encodedBytes = streamToArray(istream);
+
+      // Get bytes for exected result
+      refName = isWindows ? "image2jpg32x32-win.png" : "image2jpg32x32.png";
+      refFile = do_get_file(refName);
+      istream = getFileInputStream(refFile);
+      Assert.equal(istream.available(), 3105);
+      referenceBytes = streamToArray(istream);
+
+      // compare the encoder's output to the reference file.
+      compareArrays(encodedBytes, referenceBytes);
+    }
+
+    /* ========== 7 ========== */
+    testnum++;
+    testdesc = "test decoding a ICO";
 
-    // use a tiny buffer to make sure the image data doesn't fully fit in it
-    bostream.init(ostream, 8);
+    // 16x16 ico, 1406 bytes.
+    imgName = "image3.ico";
+    inMimeType = "image/x-icon";
+    imgFile = do_get_file(imgName);
+
+    istream = getFileInputStream(imgFile);
+    Assert.equal(istream.available(), 1406);
+
+    buffer = NetUtil.readInputStreamToString(istream, istream.available());
+    container = imgTools.decodeImageFromBuffer(
+      buffer,
+      buffer.length,
+      inMimeType
+    );
+
+    // It's not easy to look at the pixel values from JS, so just
+    // check the container's size.
+    Assert.equal(container.width, 16);
+    Assert.equal(container.height, 16);
 
-    bostream.writeFrom(istream, istream.available());
-    bostream.flush(); bostream.close();
+    /* ========== 8 ========== */
+    testnum++;
+    testdesc = "test encoding a scaled PNG"; // note that we're scaling UP
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeScaledImage(container, "image/png", 32, 32);
+    encodedBytes = streamToArray(istream);
 
-    var encBytes = streamToArray(sstream.newInputStream(0));
+    // Get bytes for exected result
+    refName = "image3ico32x32.png";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 2285);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 9 ========== */
+    testnum++;
+    testdesc = "test encoding an unscaled PNG";
 
-    compareArrays(refBytes, encBytes);
-}
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeImage(container, "image/png");
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image3ico16x16.png";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 330);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 10 ========== */
+    testnum++;
+    testdesc = "test decoding a GIF";
 
+    // 32x32 gif, 1809 bytes.
+    imgName = "image4.gif";
+    inMimeType = "image/gif";
+    imgFile = do_get_file(imgName);
+
+    istream = getFileInputStream(imgFile);
+    Assert.equal(istream.available(), 1809);
+
+    buffer = NetUtil.readInputStreamToString(istream, istream.available());
+    container = imgTools.decodeImageFromBuffer(
+      buffer,
+      buffer.length,
+      inMimeType
+    );
+
+    // It's not easy to look at the pixel values from JS, so just
+    // check the container's size.
+    Assert.equal(container.width, 32);
+    Assert.equal(container.height, 32);
 
-/* ========== bug 413512  ========== */
-testnum = 413512;
-testdesc = "test decoding bad favicon (bug 413512)";
+    /* ========== 11 ========== */
+    testnum++;
+    testdesc =
+      "test encoding an unscaled ICO with format options " +
+      "(format=bmp;bpp=32)";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeImage(
+      container,
+      "image/vnd.microsoft.icon",
+      "format=bmp;bpp=32"
+    );
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image4gif32x32bmp32bpp.ico";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 4286);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 12 ========== */
+    testnum++;
+    testdesc =
+      "test encoding a scaled ICO with format options " + "(format=bmp;bpp=32)";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeScaledImage(
+      container,
+      "image/vnd.microsoft.icon",
+      16,
+      16,
+      "format=bmp;bpp=32"
+    );
+    encodedBytes = streamToArray(istream);
 
-imgName = "bug413512.ico";
-inMimeType = "image/x-icon";
-imgFile = do_get_file(imgName);
+    // Get bytes for exected result
+    refName = "image4gif16x16bmp32bpp.ico";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1150);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 13 ========== */
+    testnum++;
+    testdesc =
+      "test encoding an unscaled ICO with format options " +
+      "(format=bmp;bpp=24)";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeImage(
+      container,
+      "image/vnd.microsoft.icon",
+      "format=bmp;bpp=24"
+    );
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image4gif32x32bmp24bpp.ico";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 3262);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 14 ========== */
+    testnum++;
+    testdesc =
+      "test encoding a scaled ICO with format options " + "(format=bmp;bpp=24)";
 
-istream = getFileInputStream(imgFile);
-Assert.equal(istream.available(), 17759);
-var errsrc = "none";
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeScaledImage(
+      container,
+      "image/vnd.microsoft.icon",
+      16,
+      16,
+      "format=bmp;bpp=24"
+    );
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image4gif16x16bmp24bpp.ico";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 894);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
 
-try {
-  buffer = NetUtil.readInputStreamToString(istream, istream.available());
-  container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType);
+    /* ========== 15 ========== */
+    testnum++;
+    testdesc = "test cropping a JPG";
+
+    // 32x32 jpeg, 3494 bytes.
+    imgName = "image2.jpg";
+    inMimeType = "image/jpeg";
+    imgFile = do_get_file(imgName);
+
+    istream = getFileInputStream(imgFile);
+    Assert.equal(istream.available(), 3494);
+
+    buffer = NetUtil.readInputStreamToString(istream, istream.available());
+    container = imgTools.decodeImageFromBuffer(
+      buffer,
+      buffer.length,
+      inMimeType
+    );
+
+    // It's not easy to look at the pixel values from JS, so just
+    // check the container's size.
+    Assert.equal(container.width, 32);
+    Assert.equal(container.height, 32);
 
-  // We expect to hit an error during encoding because the ICO header of the
-  // image is fine, but the actual resources are corrupt. Since
-  // decodeImageFromBuffer() only performs a metadata decode, it doesn't decode
-  // far enough to realize this, but we'll find out when we do a full decode
-  // during encodeImage().
-  try {
-      istream = imgTools.encodeImage(container, "image/png");
-  } catch (e) {
-      err = e;
-      errsrc = "encode";
-  }
-} catch (e) {
-  err = e;
-  errsrc = "decode";
-}
+    // encode a cropped image
+    istream = imgTools.encodeCroppedImage(
+      container,
+      "image/jpeg",
+      0,
+      0,
+      16,
+      16
+    );
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg16x16cropped.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 879);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 16 ========== */
+    testnum++;
+    testdesc = "test cropping a JPG with an offset";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeCroppedImage(
+      container,
+      "image/jpeg",
+      16,
+      16,
+      16,
+      16
+    );
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg16x16cropped2.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 878);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 17 ========== */
+    testnum++;
+    testdesc = "test cropping a JPG without a given height";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 16, 0);
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg16x32cropped3.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1127);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 18 ========== */
+    testnum++;
+    testdesc = "test cropping a JPG without a given width";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 16);
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg32x16cropped4.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1135);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
 
-Assert.equal(errsrc, "encode");
-checkExpectedError(/NS_ERROR_FAILURE/, err);
+    /* ========== 19 ========== */
+    testnum++;
+    testdesc = "test cropping a JPG without a given width and height";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 0);
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg32x32.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1634);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 20 ========== */
+    testnum++;
+    testdesc = "test scaling a JPG without a given width";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 16);
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg32x16scaled.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1227);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 21 ========== */
+    testnum++;
+    testdesc = "test scaling a JPG without a given height";
 
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 0);
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg16x32scaled.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1219);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 22 ========== */
+    testnum++;
+    testdesc = "test scaling a JPG without a given width and height";
+
+    // we'll reuse the container from the previous test
+    istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 0);
+    encodedBytes = streamToArray(istream);
+
+    // Get bytes for exected result
+    refName = "image2jpg32x32.jpg";
+    refFile = do_get_file(refName);
+    istream = getFileInputStream(refFile);
+    Assert.equal(istream.available(), 1634);
+    referenceBytes = streamToArray(istream);
+
+    // compare the encoder's output to the reference file.
+    compareArrays(encodedBytes, referenceBytes);
+
+    /* ========== 22 ========== */
+    testnum++;
+    testdesc = "test invalid arguments for cropping";
+
+    var numErrors = 0;
+
+    try {
+      // width/height can't be negative
+      imgTools.encodeScaledImage(container, "image/jpeg", -1, -1);
+    } catch (e) {
+      numErrors++;
+    }
 
-/* ========== bug 815359  ========== */
-testnum = 815359;
-testdesc = "test correct ico hotspots (bug 815359)";
+    try {
+      // offsets can't be negative
+      imgTools.encodeCroppedImage(container, "image/jpeg", -1, -1, 16, 16);
+    } catch (e) {
+      numErrors++;
+    }
+
+    try {
+      // width/height can't be negative
+      imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, -1, -1);
+    } catch (e) {
+      numErrors++;
+    }
+
+    try {
+      // out of bounds
+      imgTools.encodeCroppedImage(container, "image/jpeg", 17, 17, 16, 16);
+    } catch (e) {
+      numErrors++;
+    }
+
+    try {
+      // out of bounds
+      imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 33, 33);
+    } catch (e) {
+      numErrors++;
+    }
+
+    try {
+      // out of bounds
+      imgTools.encodeCroppedImage(container, "image/jpeg", 1, 1, 0, 0);
+    } catch (e) {
+      numErrors++;
+    }
+
+    Assert.equal(numErrors, 6);
 
-imgName = "bug815359.ico";
-inMimeType = "image/x-icon";
-imgFile = do_get_file(imgName);
+    /* ========== bug 363986 ========== */
+    testnum = 363986;
+    testdesc = "test PNG and JPEG encoders' Read/ReadSegments methods";
+
+    var testData = [
+      {
+        preImage: "image3.ico",
+        preImageMimeType: "image/x-icon",
+        refImage: "image3ico16x16.png",
+        refImageMimeType: "image/png",
+      },
+      {
+        preImage: "image1.png",
+        preImageMimeType: "image/png",
+        refImage: "image1png64x64.jpg",
+        refImageMimeType: "image/jpeg",
+      },
+    ];
 
-istream = getFileInputStream(imgFile);
-Assert.equal(istream.available(), 4286);
+    for (var i = 0; i < testData.length; ++i) {
+      var dict = testData[i];
+
+      var imgFile = do_get_file(dict.refImage);
+      var istream = getFileInputStream(imgFile);
+      var refBytes = streamToArray(istream);
+
+      imgFile = do_get_file(dict.preImage);
+      istream = getFileInputStream(imgFile);
+
+      var buffer = NetUtil.readInputStreamToString(
+        istream,
+        istream.available()
+      );
+      var container = imgTools.decodeImageFromBuffer(
+        buffer,
+        buffer.length,
+        dict.preImageMimeType
+      );
+
+      istream = imgTools.encodeImage(container, dict.refImageMimeType);
 
-buffer = NetUtil.readInputStreamToString(istream, istream.available());
-container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType);
+      var sstream = Cc["@mozilla.org/storagestream;1"].createInstance(
+        Ci.nsIStorageStream
+      );
+      sstream.init(4096, 4294967295, null);
+      var ostream = sstream.getOutputStream(0);
+      var bostream = Cc[
+        "@mozilla.org/network/buffered-output-stream;1"
+      ].createInstance(Ci.nsIBufferedOutputStream);
+
+      // use a tiny buffer to make sure the image data doesn't fully fit in it
+      bostream.init(ostream, 8);
+
+      bostream.writeFrom(istream, istream.available());
+      bostream.flush();
+      bostream.close();
+
+      var encBytes = streamToArray(sstream.newInputStream(0));
 
-var props = container.QueryInterface(Ci.nsIProperties);
+      compareArrays(refBytes, encBytes);
+    }
+
+    /* ========== bug 413512  ========== */
+    testnum = 413512;
+    testdesc = "test decoding bad favicon (bug 413512)";
+
+    imgName = "bug413512.ico";
+    inMimeType = "image/x-icon";
+    imgFile = do_get_file(imgName);
 
-Assert.equal(props.get("hotspotX", Ci.nsISupportsPRUint32).data, 10);
-Assert.equal(props.get("hotspotY", Ci.nsISupportsPRUint32).data, 9);
+    istream = getFileInputStream(imgFile);
+    Assert.equal(istream.available(), 17759);
+    var errsrc = "none";
+
+    try {
+      buffer = NetUtil.readInputStreamToString(istream, istream.available());
+      container = imgTools.decodeImageFromBuffer(
+        buffer,
+        buffer.length,
+        inMimeType
+      );
 
+      // We expect to hit an error during encoding because the ICO header of the
+      // image is fine, but the actual resources are corrupt. Since
+      // decodeImageFromBuffer() only performs a metadata decode, it doesn't decode
+      // far enough to realize this, but we'll find out when we do a full decode
+      // during encodeImage().
+      try {
+        istream = imgTools.encodeImage(container, "image/png");
+      } catch (e) {
+        err = e;
+        errsrc = "encode";
+      }
+    } catch (e) {
+      err = e;
+      errsrc = "decode";
+    }
 
-/* ========== end ========== */
+    Assert.equal(errsrc, "encode");
+    checkExpectedError(/NS_ERROR_FAILURE/, err);
+
+    /* ========== bug 815359  ========== */
+    testnum = 815359;
+    testdesc = "test correct ico hotspots (bug 815359)";
 
-} catch (e) {
+    imgName = "bug815359.ico";
+    inMimeType = "image/x-icon";
+    imgFile = do_get_file(imgName);
+
+    istream = getFileInputStream(imgFile);
+    Assert.equal(istream.available(), 4286);
+
+    buffer = NetUtil.readInputStreamToString(istream, istream.available());
+    container = imgTools.decodeImageFromBuffer(
+      buffer,
+      buffer.length,
+      inMimeType
+    );
+
+    var props = container.QueryInterface(Ci.nsIProperties);
+
+    Assert.equal(props.get("hotspotX", Ci.nsISupportsPRUint32).data, 10);
+    Assert.equal(props.get("hotspotY", Ci.nsISupportsPRUint32).data, 9);
+
+    /* ========== end ========== */
+  } catch (e) {
     throw "FAILED in test #" + testnum + " -- " + testdesc + ": " + e;
+  }
 }
-};
--- a/image/test/unit/test_moz_icon_uri.js
+++ b/image/test/unit/test_moz_icon_uri.js
@@ -6,17 +6,19 @@
 // There are 3 types of valid icon URIs:
 // 1. moz-icon:[valid URL]
 // 2. moz-icon://[file name]
 // 3. moz-icon://stock/[icon identifier]
 // Plus we also support moz-icon://[valid URL] for backwards compatibility.
 
 // Main test entry point.
 function run_test() {
-  let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+  let ioService = Cc["@mozilla.org/network/io-service;1"].getService(
+    Ci.nsIIOService
+  );
   let currentSpec = ""; // the uri spec that we're currently testing
   let exception = false; // whether or not an exception was thrown
   let uri = null; // the current URI
   let iconURI = null; // the current icon URI
 
   // Note that if the scheme is not correct the ioservice won't even create an icon URI
   // so don't bother testing incorrect schemes here.
 
@@ -128,27 +130,29 @@ function run_test() {
   } catch (e) {
     exception = true;
   }
   Assert.equal(exception, true);
   exception = false; // reset exception value
 
   // Now test an icon URI that has a URI for a path but that is not a URL. This should fail.
   // This is png data for a little red dot that I got from wikipedia.
-  currentSpec = "moz-icon:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==";
+  currentSpec =
+    "moz-icon:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==";
   try {
     uri = ioService.newURI(currentSpec);
   } catch (e) {
     exception = true;
   }
   Assert.equal(exception, true);
   exception = false; // reset exception value
 
   // Now test a URI that should be a file name but is ridiculously long. This should fail.
-  currentSpec = "moz-icon://data:application/vnd.ms-excel;base64,PHhtbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI+PHNzOldvcmtib29rIHhtbG5zOnNzPSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOm9mZmljZTpzcHJlYWRzaGVldCIgeG1sbnM6eD0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6ZXhjZWwiIHhtbG5zOm89InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSI+PG86RG9jdW1lbnRQcm9wZXJ0aWVzPjxvOlRpdGxlPkFycmF5IEdyaWQ8L286VGl0bGU+PC9vOkRvY3VtZW50UHJvcGVydGllcz48c3M6RXhjZWxXb3JrYm9vaz48c3M6V2luZG93SGVpZ2h0PjkwMDA8L3NzOldpbmRvd0hlaWdodD48c3M6V2luZG93V2lkdGg+MTc0ODA8L3NzOldpbmRvd1dpZHRoPjxzczpQcm90ZWN0U3RydWN0dXJlPkZhbHNlPC9zczpQcm90ZWN0U3RydWN0dXJlPjxzczpQcm90ZWN0V2luZG93cz5GYWxzZTwvc3M6UHJvdGVjdFdpbmRvd3M+PC9zczpFeGNlbFdvcmtib29rPjxzczpTdHlsZXM+PHNzOlN0eWxlIHNzOklEPSJEZWZhdWx0Ij48c3M6QWxpZ25tZW50IHNzOlZlcnRpY2FsPSJUb3AiIHNzOldyYXBUZXh0PSIxIiAvPjxzczpGb250IHNzOkZvbnROYW1lPSJhcmlhbCIgc3M6U2l6ZT0iMTAiIC8+PHNzOkJvcmRlcnM+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJUb3AiIC8+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJCb3R0b20iIC8+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJMZWZ0IiAvPjxzczpCb3JkZXIgc3M6Q29sb3I9IiNlNGU0ZTQiIHNzOldlaWdodD0iMSIgc3M6TGluZVN0eWxlPSJDb250aW51b3VzIiBzczpQb3NpdGlvbj0iUmlnaHQiIC8+PC9zczpCb3JkZXJzPjxzczpJbnRlcmlvciAvPjxzczpOdW1iZXJGb3JtYXQgLz48c3M6UHJvdGVjdGlvbiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOklEPSJ0aXRsZSI+PHNzOkJvcmRlcnMgLz48c3M6Rm9udCAvPjxzczpBbGlnbm1lbnQgc3M6V3JhcFRleHQ9IjEiIHNzOlZlcnRpY2FsPSJDZW50ZXIiIHNzOkhvcml6b250YWw9IkNlbnRlciIgLz48c3M6TnVtYmVyRm9ybWF0IHNzOkZvcm1hdD0iQCIgLz48L3NzOlN0eWxlPjxzczpTdHlsZSBzczpJRD0iaGVhZGVyY2VsbCI+PHNzOkZvbnQgc3M6Qm9sZD0iMSIgc3M6U2l6ZT0iMTAiIC8+PHNzOkFsaWdubWVudCBzczpXcmFwVGV4dD0iMSIgc3M6SG9yaXpvbnRhbD0iQ2VudGVyIiAvPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNBM0M5RjEiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6SUQ9ImV2ZW4iPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNDQ0ZGRkYiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJldmVuIiBzczpJRD0iZXZlbmRhdGUiPjxzczpOdW1iZXJGb3JtYXQgc3M6Rm9ybWF0PSJ5eXl5LW1tLWRkIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOlBhcmVudD0iZXZlbiIgc3M6SUQ9ImV2ZW5pbnQiPjxzczpOdW1iZXJGb3JtYXQgc3M6Rm9ybWF0PSIwIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOlBhcmVudD0iZXZlbiIgc3M6SUQ9ImV2ZW5mbG9hdCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAuMDAwIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOklEPSJvZGQiPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNDQ0NDRkYiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJvZGQiIHNzOklEPSJvZGRkYXRlIj48c3M6TnVtYmVyRm9ybWF0IHNzOkZvcm1hdD0ieXl5eS1tbS1kZCIgLz48L3NzOlN0eWxlPjxzczpTdHlsZSBzczpQYXJlbnQ9Im9kZCIgc3M6SUQ9Im9kZGludCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJvZGQiIHNzOklEPSJvZGRmbG9hdCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAuMDAwIiAvPjwvc3M6U3R5bGU+PC9zczpTdHlsZXM+PHNzOldvcmtzaGVldCBzczpOYW1lPSJBcnJheSBHcmlkIj48c3M6TmFtZXM+PHNzOk5hbWVkUmFuZ2Ugc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiBzczpSZWZlcnNUbz0iPSdBcnJheSBHcmlkJyFSMTpSMiIgLz48L3NzOk5hbWVzPjxzczpUYWJsZSB4OkZ1bGxSb3dzPSIxIiB4OkZ1bGxDb2x1bW5zPSIxIiBzczpFeHBhbmRlZENvbHVtbkNvdW50PSI1IiBzczpFeHBhbmRlZFJvd0NvdW50PSIzMSI+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSIyNzEiIC8+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSI3NSIgLz48c3M6Q29sdW1uIHNzOkF1dG9GaXRXaWR0aD0iMSIgc3M6V2lkdGg9Ijc1IiAvPjxzczpDb2x1bW4gc3M6QXV0b0ZpdFdpZHRoPSIxIiBzczpXaWR0aD0iNzUiIC8+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSI4NSIgLz48c3M6Um93IHNzOkhlaWdodD0iMzgiPjxzczpDZWxsIHNzOlN0eWxlSUQ9InRpdGxlIiBzczpNZXJnZUFjcm9zcz0iNCI+PHNzOkRhdGEgeG1sbnM6aHRtbD0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MCIgc3M6VHlwZT0iU3RyaW5nIj48aHRtbDpCPiAoYykyMDA4IFNFQk4gVUE8L2h0bWw6Qj48L3NzOkRhdGE+PHNzOk5hbWVkQ2VsbCBzczpOYW1lPSJQcmludF9UaXRsZXMiIC8+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3cgc3M6QXV0b0ZpdEhlaWdodD0iMSI+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Db21wYW55PC9zczpEYXRhPjxzczpOYW1lZENlbGwgc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiAvPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJoZWFkZXJjZWxsIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlByaWNlPC9zczpEYXRhPjxzczpOYW1lZENlbGwgc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiAvPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJoZWFkZXJjZWxsIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkNoYW5nZTwvc3M6RGF0YT48c3M6TmFtZWRDZWxsIHNzOk5hbWU9IlByaW50X1RpdGxlcyIgLz48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4lIENoYW5nZTwvc3M6RGF0YT48c3M6TmFtZWRDZWxsIHNzOk5hbWU9IlByaW50X1RpdGxlcyIgLz48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5MYXN0IFVwZGF0ZWQ8L3NzOkRhdGE+PHNzOk5hbWVkQ2VsbCBzczpOYW1lPSJQcmludF9UaXRsZXMiIC8+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zbSBDbzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj43MS43Mjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BVCZUIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zMS42MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPi0wLjQ4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTEuNTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BbGNvYSBJbmM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MjkuMDE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC40Mjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjQ3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+QWx0cmlhIEdyb3VwIEluYzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjgzLjgxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4yODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMzQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BbWVyaWNhbiBFeHByZXNzIENvbXBhbnk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NTIuNTU8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+QW1lcmljYW4gSW50ZXJuYXRpb25hbCBHcm91cCwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjY0LjEzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4zMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNDk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Cb2VpbmcgQ28uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjc1LjQzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC43MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkNhdGVycGlsbGFyIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj42Ny4yNzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuOTI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjM5PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+Q2l0aWdyb3VwLCBJbmMuPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjQ5LjM3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wNDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkUuSS4gZHUgUG9udCBkZSBOZW1vdXJzIGFuZCBDb21wYW55PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDAuNDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjUxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MS4yODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkV4eG9uIE1vYmlsIENvcnA8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjguMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC40Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC42NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkdlbmVyYWwgRWxlY3RyaWMgQ29tcGFueTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjM0LjE0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTAuMDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC4yMzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkdlbmVyYWwgTW90b3JzIENvcnBvcmF0aW9uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjMwLjI3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+My43NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkhld2xldHQtUGFja2FyZCBDby48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNi41Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPi0wLjAzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTAuMDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Ib25leXdlbGwgSW50bCBJbmM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MzguNzc8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wNTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjEzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+SW50ZWwgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xOS44ODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMzE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjU4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+SW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lczwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj44MS40MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQ0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5KUCBNb3JnYW4gJiBDaGFzZSAmIENvPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDUuNzM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjA3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4xNTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkpvaG5zb24gJiBKb2huc29uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjY0LjcyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wOTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPk1jRG9uYWxkJ3MgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNi43Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuODY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yLjQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5NZXJjayAmIENvLiwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj40MC45Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5NaWNyb3NvZnQgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yNS44NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjU0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+UGZpemVyIEluYzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yNy45Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MS40NTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlRoZSBDb2NhLUNvbGEgQ29tcGFueTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjQ1LjA3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4yNjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5UaGUgSG9tZSBEZXBvdCwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNC42NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjM1PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5UaGUgUHJvY3RlciAmIEdhbWJsZSBDb21wYW55PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjEuOTE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wMjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlVuaXRlZCBUZWNobm9sb2dpZXMgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjMuMjY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC41NTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjg4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+VmVyaXpvbiBDb21tdW5pY2F0aW9uczwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjM1LjU3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4zOTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMTE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XYWwtTWFydCBTdG9yZXMsIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDUuNDU8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC43Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjYzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PC9zczpUYWJsZT48eDpXb3Jrc2hlZXRPcHRpb25zPjx4OlBhZ2VTZXR1cD48eDpMYXlvdXQgeDpDZW50ZXJIb3Jpem9udGFsPSIxIiB4Ok9yaWVudGF0aW9uPSJMYW5kc2NhcGUiIC8+PHg6Rm9vdGVyIHg6RGF0YT0iUGFnZSAmYW1wO1Agb2YgJmFtcDtOIiB4Ok1hcmdpbj0iMC41IiAvPjx4OlBhZ2VNYXJnaW5zIHg6VG9wPSIwLjUiIHg6UmlnaHQ9IjAuNSIgeDpMZWZ0PSIwLjUiIHg6Qm90dG9tPSIwLjgiIC8+PC94OlBhZ2VTZXR1cD48eDpGaXRUb1BhZ2UgLz48eDpQcmludD48eDpQcmludEVycm9ycz5CbGFuazwveDpQcmludEVycm9ycz48eDpGaXRXaWR0aD4xPC94OkZpdFdpZHRoPjx4OkZpdEhlaWdodD4zMjc2NzwveDpGaXRIZWlnaHQ+PHg6VmFsaWRQcmludGVySW5mbyAvPjx4OlZlcnRpY2FsUmVzb2x1dGlvbj42MDA8L3g6VmVydGljYWxSZXNvbHV0aW9uPjwveDpQcmludD48eDpTZWxlY3RlZCAvPjx4OkRvTm90RGlzcGxheUdyaWRsaW5lcyAvPjx4OlByb3RlY3RPYmplY3RzPkZhbHNlPC94OlByb3RlY3RPYmplY3RzPjx4OlByb3RlY3RTY2VuYXJpb3M+RmFsc2U8L3g6UHJvdGVjdFNjZW5hcmlvcz48L3g6V29ya3NoZWV0T3B0aW9ucz48L3NzOldvcmtzaGVldD48L3NzOldvcmtib29rPg==";
+  currentSpec =
+    "moz-icon://data:application/vnd.ms-excel;base64,PHhtbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI+PHNzOldvcmtib29rIHhtbG5zOnNzPSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOm9mZmljZTpzcHJlYWRzaGVldCIgeG1sbnM6eD0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6ZXhjZWwiIHhtbG5zOm89InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSI+PG86RG9jdW1lbnRQcm9wZXJ0aWVzPjxvOlRpdGxlPkFycmF5IEdyaWQ8L286VGl0bGU+PC9vOkRvY3VtZW50UHJvcGVydGllcz48c3M6RXhjZWxXb3JrYm9vaz48c3M6V2luZG93SGVpZ2h0PjkwMDA8L3NzOldpbmRvd0hlaWdodD48c3M6V2luZG93V2lkdGg+MTc0ODA8L3NzOldpbmRvd1dpZHRoPjxzczpQcm90ZWN0U3RydWN0dXJlPkZhbHNlPC9zczpQcm90ZWN0U3RydWN0dXJlPjxzczpQcm90ZWN0V2luZG93cz5GYWxzZTwvc3M6UHJvdGVjdFdpbmRvd3M+PC9zczpFeGNlbFdvcmtib29rPjxzczpTdHlsZXM+PHNzOlN0eWxlIHNzOklEPSJEZWZhdWx0Ij48c3M6QWxpZ25tZW50IHNzOlZlcnRpY2FsPSJUb3AiIHNzOldyYXBUZXh0PSIxIiAvPjxzczpGb250IHNzOkZvbnROYW1lPSJhcmlhbCIgc3M6U2l6ZT0iMTAiIC8+PHNzOkJvcmRlcnM+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJUb3AiIC8+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJCb3R0b20iIC8+PHNzOkJvcmRlciBzczpDb2xvcj0iI2U0ZTRlNCIgc3M6V2VpZ2h0PSIxIiBzczpMaW5lU3R5bGU9IkNvbnRpbnVvdXMiIHNzOlBvc2l0aW9uPSJMZWZ0IiAvPjxzczpCb3JkZXIgc3M6Q29sb3I9IiNlNGU0ZTQiIHNzOldlaWdodD0iMSIgc3M6TGluZVN0eWxlPSJDb250aW51b3VzIiBzczpQb3NpdGlvbj0iUmlnaHQiIC8+PC9zczpCb3JkZXJzPjxzczpJbnRlcmlvciAvPjxzczpOdW1iZXJGb3JtYXQgLz48c3M6UHJvdGVjdGlvbiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOklEPSJ0aXRsZSI+PHNzOkJvcmRlcnMgLz48c3M6Rm9udCAvPjxzczpBbGlnbm1lbnQgc3M6V3JhcFRleHQ9IjEiIHNzOlZlcnRpY2FsPSJDZW50ZXIiIHNzOkhvcml6b250YWw9IkNlbnRlciIgLz48c3M6TnVtYmVyRm9ybWF0IHNzOkZvcm1hdD0iQCIgLz48L3NzOlN0eWxlPjxzczpTdHlsZSBzczpJRD0iaGVhZGVyY2VsbCI+PHNzOkZvbnQgc3M6Qm9sZD0iMSIgc3M6U2l6ZT0iMTAiIC8+PHNzOkFsaWdubWVudCBzczpXcmFwVGV4dD0iMSIgc3M6SG9yaXpvbnRhbD0iQ2VudGVyIiAvPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNBM0M5RjEiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6SUQ9ImV2ZW4iPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNDQ0ZGRkYiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJldmVuIiBzczpJRD0iZXZlbmRhdGUiPjxzczpOdW1iZXJGb3JtYXQgc3M6Rm9ybWF0PSJ5eXl5LW1tLWRkIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOlBhcmVudD0iZXZlbiIgc3M6SUQ9ImV2ZW5pbnQiPjxzczpOdW1iZXJGb3JtYXQgc3M6Rm9ybWF0PSIwIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOlBhcmVudD0iZXZlbiIgc3M6SUQ9ImV2ZW5mbG9hdCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAuMDAwIiAvPjwvc3M6U3R5bGU+PHNzOlN0eWxlIHNzOklEPSJvZGQiPjxzczpJbnRlcmlvciBzczpQYXR0ZXJuPSJTb2xpZCIgc3M6Q29sb3I9IiNDQ0NDRkYiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJvZGQiIHNzOklEPSJvZGRkYXRlIj48c3M6TnVtYmVyRm9ybWF0IHNzOkZvcm1hdD0ieXl5eS1tbS1kZCIgLz48L3NzOlN0eWxlPjxzczpTdHlsZSBzczpQYXJlbnQ9Im9kZCIgc3M6SUQ9Im9kZGludCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAiIC8+PC9zczpTdHlsZT48c3M6U3R5bGUgc3M6UGFyZW50PSJvZGQiIHNzOklEPSJvZGRmbG9hdCI+PHNzOk51bWJlckZvcm1hdCBzczpGb3JtYXQ9IjAuMDAwIiAvPjwvc3M6U3R5bGU+PC9zczpTdHlsZXM+PHNzOldvcmtzaGVldCBzczpOYW1lPSJBcnJheSBHcmlkIj48c3M6TmFtZXM+PHNzOk5hbWVkUmFuZ2Ugc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiBzczpSZWZlcnNUbz0iPSdBcnJheSBHcmlkJyFSMTpSMiIgLz48L3NzOk5hbWVzPjxzczpUYWJsZSB4OkZ1bGxSb3dzPSIxIiB4OkZ1bGxDb2x1bW5zPSIxIiBzczpFeHBhbmRlZENvbHVtbkNvdW50PSI1IiBzczpFeHBhbmRlZFJvd0NvdW50PSIzMSI+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSIyNzEiIC8+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSI3NSIgLz48c3M6Q29sdW1uIHNzOkF1dG9GaXRXaWR0aD0iMSIgc3M6V2lkdGg9Ijc1IiAvPjxzczpDb2x1bW4gc3M6QXV0b0ZpdFdpZHRoPSIxIiBzczpXaWR0aD0iNzUiIC8+PHNzOkNvbHVtbiBzczpBdXRvRml0V2lkdGg9IjEiIHNzOldpZHRoPSI4NSIgLz48c3M6Um93IHNzOkhlaWdodD0iMzgiPjxzczpDZWxsIHNzOlN0eWxlSUQ9InRpdGxlIiBzczpNZXJnZUFjcm9zcz0iNCI+PHNzOkRhdGEgeG1sbnM6aHRtbD0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MCIgc3M6VHlwZT0iU3RyaW5nIj48aHRtbDpCPiAoYykyMDA4IFNFQk4gVUE8L2h0bWw6Qj48L3NzOkRhdGE+PHNzOk5hbWVkQ2VsbCBzczpOYW1lPSJQcmludF9UaXRsZXMiIC8+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3cgc3M6QXV0b0ZpdEhlaWdodD0iMSI+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Db21wYW55PC9zczpEYXRhPjxzczpOYW1lZENlbGwgc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiAvPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJoZWFkZXJjZWxsIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlByaWNlPC9zczpEYXRhPjxzczpOYW1lZENlbGwgc3M6TmFtZT0iUHJpbnRfVGl0bGVzIiAvPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJoZWFkZXJjZWxsIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkNoYW5nZTwvc3M6RGF0YT48c3M6TmFtZWRDZWxsIHNzOk5hbWU9IlByaW50X1RpdGxlcyIgLz48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4lIENoYW5nZTwvc3M6RGF0YT48c3M6TmFtZWRDZWxsIHNzOk5hbWU9IlByaW50X1RpdGxlcyIgLz48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iaGVhZGVyY2VsbCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5MYXN0IFVwZGF0ZWQ8L3NzOkRhdGE+PHNzOk5hbWVkQ2VsbCBzczpOYW1lPSJQcmludF9UaXRsZXMiIC8+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zbSBDbzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj43MS43Mjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BVCZUIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zMS42MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPi0wLjQ4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTEuNTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BbGNvYSBJbmM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MjkuMDE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC40Mjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjQ3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+QWx0cmlhIEdyb3VwIEluYzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjgzLjgxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4yODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMzQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5BbWVyaWNhbiBFeHByZXNzIENvbXBhbnk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NTIuNTU8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+QW1lcmljYW4gSW50ZXJuYXRpb25hbCBHcm91cCwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjY0LjEzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4zMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNDk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Cb2VpbmcgQ28uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjc1LjQzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC43MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkNhdGVycGlsbGFyIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj42Ny4yNzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuOTI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjM5PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+Q2l0aWdyb3VwLCBJbmMuPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjQ5LjM3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wNDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkUuSS4gZHUgUG9udCBkZSBOZW1vdXJzIGFuZCBDb21wYW55PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDAuNDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjUxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MS4yODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkV4eG9uIE1vYmlsIENvcnA8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjguMTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC40Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC42NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkdlbmVyYWwgRWxlY3RyaWMgQ29tcGFueTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjM0LjE0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTAuMDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4tMC4yMzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkdlbmVyYWwgTW90b3JzIENvcnBvcmF0aW9uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjMwLjI3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDk8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+My43NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkhld2xldHQtUGFja2FyZCBDby48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNi41Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPi0wLjAzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+LTAuMDg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5Ib25leXdlbGwgSW50bCBJbmM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MzguNzc8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wNTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjEzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+SW50ZWwgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xOS44ODwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMzE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjU4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+SW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lczwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj44MS40MTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQ0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5KUCBNb3JnYW4gJiBDaGFzZSAmIENvPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDUuNzM8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjA3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4xNTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPkpvaG5zb24gJiBKb2huc29uPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjY0LjcyPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMDY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wOTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPk1jRG9uYWxkJ3MgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNi43Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuODY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yLjQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5NZXJjayAmIENvLiwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj40MC45Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5NaWNyb3NvZnQgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yNS44NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuMTQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjU0PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+UGZpemVyIEluYzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4yNy45Njwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjQ8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MS40NTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlRoZSBDb2NhLUNvbGEgQ29tcGFueTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjQ1LjA3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4yNjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjAuNTg8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5UaGUgSG9tZSBEZXBvdCwgSW5jLjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4zNC42NDwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjM1PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMDI8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+V2VkIFNlcCAwMSAyMDEwIDAwOjAwOjAwIEdNVCsxMDAwIChFU1QpPC9zczpEYXRhPjwvc3M6Q2VsbD48L3NzOlJvdz48c3M6Um93PjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5UaGUgUHJvY3RlciAmIEdhbWJsZSBDb21wYW55PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjEuOTE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjAxPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4wMjwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPlVuaXRlZCBUZWNobm9sb2dpZXMgQ29ycG9yYXRpb248L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NjMuMjY8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC41NTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4wLjg4PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PHNzOlJvdz48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+VmVyaXpvbiBDb21tdW5pY2F0aW9uczwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjM1LjU3PC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJvZGQiPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC4zOTwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0ib2RkIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPjEuMTE8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9Im9kZCI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XZWQgU2VwIDAxIDIwMTAgMDA6MDA6MDAgR01UKzEwMDAgKEVTVCk8L3NzOkRhdGE+PC9zczpDZWxsPjwvc3M6Um93PjxzczpSb3c+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj5XYWwtTWFydCBTdG9yZXMsIEluYy48L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+NDUuNDU8L3NzOkRhdGE+PC9zczpDZWxsPjxzczpDZWxsIHNzOlN0eWxlSUQ9ImV2ZW4iPjxzczpEYXRhIHNzOlR5cGU9IlN0cmluZyI+MC43Mzwvc3M6RGF0YT48L3NzOkNlbGw+PHNzOkNlbGwgc3M6U3R5bGVJRD0iZXZlbiI+PHNzOkRhdGEgc3M6VHlwZT0iU3RyaW5nIj4xLjYzPC9zczpEYXRhPjwvc3M6Q2VsbD48c3M6Q2VsbCBzczpTdHlsZUlEPSJldmVuIj48c3M6RGF0YSBzczpUeXBlPSJTdHJpbmciPldlZCBTZXAgMDEgMjAxMCAwMDowMDowMCBHTVQrMTAwMCAoRVNUKTwvc3M6RGF0YT48L3NzOkNlbGw+PC9zczpSb3c+PC9zczpUYWJsZT48eDpXb3Jrc2hlZXRPcHRpb25zPjx4OlBhZ2VTZXR1cD48eDpMYXlvdXQgeDpDZW50ZXJIb3Jpem9udGFsPSIxIiB4Ok9yaWVudGF0aW9uPSJMYW5kc2NhcGUiIC8+PHg6Rm9vdGVyIHg6RGF0YT0iUGFnZSAmYW1wO1Agb2YgJmFtcDtOIiB4Ok1hcmdpbj0iMC41IiAvPjx4OlBhZ2VNYXJnaW5zIHg6VG9wPSIwLjUiIHg6UmlnaHQ9IjAuNSIgeDpMZWZ0PSIwLjUiIHg6Qm90dG9tPSIwLjgiIC8+PC94OlBhZ2VTZXR1cD48eDpGaXRUb1BhZ2UgLz48eDpQcmludD48eDpQcmludEVycm9ycz5CbGFuazwveDpQcmludEVycm9ycz48eDpGaXRXaWR0aD4xPC94OkZpdFdpZHRoPjx4OkZpdEhlaWdodD4zMjc2NzwveDpGaXRIZWlnaHQ+PHg6VmFsaWRQcmludGVySW5mbyAvPjx4OlZlcnRpY2FsUmVzb2x1dGlvbj42MDA8L3g6VmVydGljYWxSZXNvbHV0aW9uPjwveDpQcmludD48eDpTZWxlY3RlZCAvPjx4OkRvTm90RGlzcGxheUdyaWRsaW5lcyAvPjx4OlByb3RlY3RPYmplY3RzPkZhbHNlPC94OlByb3RlY3RPYmplY3RzPjx4OlByb3RlY3RTY2VuYXJpb3M+RmFsc2U8L3g6UHJvdGVjdFNjZW5hcmlvcz48L3g6V29ya3NoZWV0T3B0aW9ucz48L3NzOldvcmtzaGVldD48L3NzOldvcmtib29rPg==";
   try {
     uri = ioService.newURI(currentSpec);
   } catch (e) {
     exception = true;
   }
   Assert.equal(exception, true);
   exception = false; // reset exception value
-};
+}
--- a/image/test/unit/test_private_channel.js
+++ b/image/test/unit/test_private_channel.js
@@ -1,76 +1,108 @@
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
 
 var server = new HttpServer();
-server.registerPathHandler('/image.png', imageHandler);
+server.registerPathHandler("/image.png", imageHandler);
 server.start(-1);
 
-load('image_load_helpers.js');
+load("image_load_helpers.js");
 
 var gHits = 0;
 
-var gIoService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-var gPublicLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
-var gPrivateLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
+var gIoService = Cc["@mozilla.org/network/io-service;1"].getService(
+  Ci.nsIIOService
+);
+var gPublicLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+  Ci.imgILoader
+);
+var gPrivateLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+  Ci.imgILoader
+);
 gPrivateLoader.QueryInterface(Ci.imgICache).respectPrivacyNotifications();
 
 var nonPrivateLoadContext = Cu.createLoadContext();
 var privateLoadContext = Cu.createPrivateLoadContext();
 
 function imageHandler(metadata, response) {
   gHits++;
   response.setHeader("Cache-Control", "max-age=10000", false);
   response.setStatusLine(metadata.httpVersion, 200, "OK");
   response.setHeader("Content-Type", "image/png", false);
-  var body = "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
+  var body =
+    "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
   response.bodyOutputStream.write(body, body.length);
 }
 
 var requests = [];
 var listeners = [];
 
-var gImgPath = 'http://localhost:' + server.identity.primaryPort + '/image.png';
+var gImgPath = "http://localhost:" + server.identity.primaryPort + "/image.png";
 
 function setup_chan(path, isPrivate, callback) {
   var uri = NetUtil.newURI(gImgPath);
   var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
-  var principal = Services.scriptSecurityManager
-                          .createCodebasePrincipal(uri, {privateBrowsingId: isPrivate ? 1 : 0});
-  var chan =  NetUtil.newChannel({uri, loadingPrincipal: principal,
-                                  securityFlags,
-                                  contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE});
-  chan.notificationCallbacks = isPrivate ? privateLoadContext
-                                         : nonPrivateLoadContext;
+  var principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {
+    privateBrowsingId: isPrivate ? 1 : 0,
+  });
+  var chan = NetUtil.newChannel({
+    uri,
+    loadingPrincipal: principal,
+    securityFlags,
+    contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE,
+  });
+  chan.notificationCallbacks = isPrivate
+    ? privateLoadContext
+    : nonPrivateLoadContext;
   var channelListener = new ChannelListener();
   chan.asyncOpen(channelListener);
 
   var listener = new ImageListener(null, callback);
   var outlistener = {};
   var loader = isPrivate ? gPrivateLoader : gPublicLoader;
-  var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                .createScriptedObserver(listener);
+  var outer = Cc["@mozilla.org/image/tools;1"]
+    .getService(Ci.imgITools)
+    .createScriptedObserver(listener);
   listeners.push(outer);
-  requests.push(loader.loadImageWithChannelXPCOM(chan, outer, null, outlistener));
+  requests.push(
+    loader.loadImageWithChannelXPCOM(chan, outer, null, outlistener)
+  );
   channelListener.outputListener = outlistener.value;
   listener.synchronous = false;
 }
 
 function loadImage(isPrivate, callback) {
   var listener = new ImageListener(null, callback);
-  var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-                .createScriptedObserver(listener);
+  var outer = Cc["@mozilla.org/image/tools;1"]
+    .getService(Ci.imgITools)
+    .createScriptedObserver(listener);
   var uri = gIoService.newURI(gImgPath);
-  var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(Ci.nsILoadGroup);
-  loadGroup.notificationCallbacks = isPrivate ? privateLoadContext
-                                              : nonPrivateLoadContext;
+  var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(
+    Ci.nsILoadGroup
+  );
+  loadGroup.notificationCallbacks = isPrivate
+    ? privateLoadContext
+    : nonPrivateLoadContext;
   var loader = isPrivate ? gPrivateLoader : gPublicLoader;
-  requests.push(loader.loadImageXPCOM(uri, null, null, "default", null, loadGroup, outer, null, 0, null));
+  requests.push(
+    loader.loadImageXPCOM(
+      uri,
+      null,
+      null,
+      "default",
+      null,
+      loadGroup,
+      outer,
+      null,
+      0,
+      null
+    )
+  );
   listener.synchronous = false;
 }
 
 function run_loadImage_tests() {
   function observer() {
     Services.obs.removeObserver(observer, "cacheservice:empty-cache");
     gHits = 0;
     loadImage(false, function() {
@@ -81,23 +113,23 @@ function run_loadImage_tests() {
             server.stop(do_test_finished);
           });
         });
       });
     });
   }
 
   Services.obs.addObserver(observer, "cacheservice:empty-cache");
-  let cs = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
-             .getService(Ci.nsICacheStorageService);
+  let cs = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(
+    Ci.nsICacheStorageService
+  );
   cs.clear();
 }
 
-function cleanup()
-{
+function cleanup() {
   for (var i = 0; i < requests.length; ++i) {
     requests[i].cancelAndForgetObserver(0);
   }
 }
 
 function run_test() {
   registerCleanupFunction(cleanup);
 
@@ -105,19 +137,19 @@ function run_test() {
 
   Services.prefs.setBoolPref("network.http.rcwn.enabled", false);
 
   // We create a public channel that loads an image, then an identical
   // one that should cause a cache read. We then create a private channel
   // and load the same image, and do that a second time to ensure a cache
   // read. In total, we should cause two separate http responses to occur,
   // since the private channels shouldn't be able to use the public cache.
-  setup_chan('/image.png', false, function() {
-    setup_chan('/image.png', false, function() {
-      setup_chan('/image.png', true, function() {
-        setup_chan('/image.png', true, function() {
+  setup_chan("/image.png", false, function() {
+    setup_chan("/image.png", false, function() {
+      setup_chan("/image.png", true, function() {
+        setup_chan("/image.png", true, function() {
           Assert.equal(gHits, 2);
           run_loadImage_tests();
         });
       });
     });
   });
 }