Bug 1333602 - Update new frontend (1/24/2017). r=jdescottes
authorJason Laster <jason.laster.11@gmail.com>
Wed, 25 Jan 2017 11:49:00 +0800
changeset 466675 fe88899da4aa4902599899058d4af72bc752ca15
parent 466674 4477cdb38b11e900bb79d3dad791f0511aff7c5b
child 466676 e6ed73323bb33d4bdb6278395fd9acaba58cc092
push id42948
push userbmo:gasolin@mozilla.com
push dateThu, 26 Jan 2017 07:49:21 +0000
reviewersjdescottes
bugs1333602
milestone54.0a1
Bug 1333602 - Update new frontend (1/24/2017). r=jdescottes * copy files from Debugger * kill svgs * add modes * add theme changes * add property changes * remove old system for updating bundles
devtools/client/debugger/new/debugger.css
devtools/client/debugger/new/debugger.js
devtools/client/debugger/new/images/Icons.js
devtools/client/debugger/new/images/Svg.js
devtools/client/debugger/new/images/angle-brackets.svg
devtools/client/debugger/new/images/arrow.svg
devtools/client/debugger/new/images/blackBox.svg
devtools/client/debugger/new/images/breakpoint.svg
devtools/client/debugger/new/images/close.svg
devtools/client/debugger/new/images/disableBreakpoints.svg
devtools/client/debugger/new/images/domain.svg
devtools/client/debugger/new/images/favicon.png
devtools/client/debugger/new/images/file.svg
devtools/client/debugger/new/images/folder.svg
devtools/client/debugger/new/images/globe.svg
devtools/client/debugger/new/images/magnifying-glass.svg
devtools/client/debugger/new/images/pause-circle.svg
devtools/client/debugger/new/images/pause-exceptions.svg
devtools/client/debugger/new/images/pause.svg
devtools/client/debugger/new/images/play.svg
devtools/client/debugger/new/images/plus.svg
devtools/client/debugger/new/images/prettyPrint.svg
devtools/client/debugger/new/images/resume.svg
devtools/client/debugger/new/images/sad-face.svg
devtools/client/debugger/new/images/settings.svg
devtools/client/debugger/new/images/stepIn.svg
devtools/client/debugger/new/images/stepOut.svg
devtools/client/debugger/new/images/stepOver.svg
devtools/client/debugger/new/images/subSettings.svg
devtools/client/debugger/new/images/toggle-breakpoints.svg
devtools/client/debugger/new/images/worker.svg
devtools/client/debugger/new/pretty-print-worker.js
devtools/client/debugger/new/source-map-worker.js
devtools/client/debugger/new/test/mochitest/browser.ini
devtools/client/debugger/new/test/mochitest/browser_dbg-console.js
devtools/client/debugger/new/test/mochitest/browser_dbg_keyboard_navigation.js
devtools/client/debugger/new/test/mochitest/head.js
devtools/client/jar.mn
devtools/client/locales/en-US/debugger.properties
devtools/client/package.json
devtools/client/sourceeditor/codemirror/codemirror.bundle.js
devtools/client/sourceeditor/codemirror/mode/coffeescript/coffeescript.js
devtools/client/sourceeditor/codemirror/mode/elm/elm.js
devtools/client/sourceeditor/codemirror/mode/jsx/jsx.js
devtools/client/sourceeditor/webpack.config.js
devtools/client/themes/dark-theme.css
devtools/client/update-tools.js
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -201,50 +201,16 @@ body {
 }
 
 .landing-page .panel .footer-note {
   padding: var(--base-spacing) 0;
   text-align: center;
   font-size: 14px;
   color: var(--theme-comment);
 }
-/* vim:set ts=2 sw=2 sts=2 et: */
-
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-:root.theme-light,
-:root .theme-light {
-  --theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
-  --theme-faded-tab-color: #7e7e7e;
-}
-
-:root.theme-dark,
-:root .theme-dark {
-  --theme-faded-tab-color: #6e7d8c;
-}
-
-* {
-  box-sizing: border-box;
-}
-
-html,
-body {
-  height: 100%;
-  margin: 0;
-  padding: 0;
-  width: 100%;
-}
-
-#mount {
-  display: flex;
-  height: 100%;
-}
-
 .debugger {
   display: flex;
   flex: 1;
   height: 100%;
 }
 
 .editor-pane {
   display: flex;
@@ -889,16 +855,17 @@ html .arrow.expanded svg {
 
 .tree button {
   display: block;
 }
 
 .tree .node {
   padding: 2px 5px;
   position: relative;
+  cursor: pointer;
 }
 
 .tree .node.focused {
   color: white;
   background-color: var(--theme-selection-background);
 }
 
 html:not([dir="rtl"]) .tree .node > div {
@@ -955,93 +922,696 @@ html[dir="rtl"] .tree .node > div {
   cursor: pointer;
 }
 
 .sources-list {
   flex: 1;
   display: flex;
   overflow: hidden;
 }
-
-.tree {
+/* BASICS */
+
+.CodeMirror {
+  /* Set height, width, borders, and global font properties here */
+  font-family: monospace;
+  height: 300px;
+  color: black;
+}
+
+/* PADDING */
+
+.CodeMirror-lines {
+  padding: 4px 0; /* Vertical padding around content */
+}
+.CodeMirror pre {
+  padding: 0 4px; /* Horizontal padding of content */
+}
+
+.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
+  background-color: white; /* The little square between H and V scrollbars */
+}
+
+/* GUTTER */
+
+.CodeMirror-gutters {
+  border-right: 1px solid #ddd;
+  background-color: #f7f7f7;
+  white-space: nowrap;
+}
+.CodeMirror-linenumbers {}
+.CodeMirror-linenumber {
+  padding: 0 3px 0 5px;
+  min-width: 20px;
+  text-align: right;
+  color: #999;
+  white-space: nowrap;
+}
+
+.CodeMirror-guttermarker { color: black; }
+.CodeMirror-guttermarker-subtle { color: #999; }
+
+/* CURSOR */
+
+.CodeMirror-cursor {
+  border-left: 1px solid black;
+  border-right: none;
+  width: 0;
+}
+/* Shown when moving in bi-directional text */
+.CodeMirror div.CodeMirror-secondarycursor {
+  border-left: 1px solid silver;
+}
+.cm-fat-cursor .CodeMirror-cursor {
+  width: auto;
+  border: 0 !important;
+  background: #7e7;
+}
+.cm-fat-cursor div.CodeMirror-cursors {
+  z-index: 1;
+}
+
+.cm-animate-fat-cursor {
+  width: auto;
+  border: 0;
+  -webkit-animation: blink 1.06s steps(1) infinite;
+  -moz-animation: blink 1.06s steps(1) infinite;
+  animation: blink 1.06s steps(1) infinite;
+  background-color: #7e7;
+}
+@-moz-keyframes blink {
+  0% {}
+  50% { background-color: transparent; }
+  100% {}
+}
+@-webkit-keyframes blink {
+  0% {}
+  50% { background-color: transparent; }
+  100% {}
+}
+@keyframes blink {
+  0% {}
+  50% { background-color: transparent; }
+  100% {}
+}
+
+/* Can style cursor different in overwrite (non-insert) mode */
+.CodeMirror-overwrite .CodeMirror-cursor {}
+
+.cm-tab { display: inline-block; text-decoration: inherit; }
+
+.CodeMirror-rulers {
+  position: absolute;
+  left: 0; right: 0; top: -50px; bottom: -20px;
+  overflow: hidden;
+}
+.CodeMirror-ruler {
+  border-left: 1px solid #ccc;
+  top: 0; bottom: 0;
+  position: absolute;
+}
+
+/* DEFAULT THEME */
+
+.cm-s-default .cm-header {color: blue;}
+.cm-s-default .cm-quote {color: #090;}
+.cm-negative {color: #d44;}
+.cm-positive {color: #292;}
+.cm-header, .cm-strong {font-weight: bold;}
+.cm-em {font-style: italic;}
+.cm-link {text-decoration: underline;}
+.cm-strikethrough {text-decoration: line-through;}
+
+.cm-s-default .cm-keyword {color: #708;}
+.cm-s-default .cm-atom {color: #219;}
+.cm-s-default .cm-number {color: #164;}
+.cm-s-default .cm-def {color: #00f;}
+.cm-s-default .cm-variable,
+.cm-s-default .cm-punctuation,
+.cm-s-default .cm-property,
+.cm-s-default .cm-operator {}
+.cm-s-default .cm-variable-2 {color: #05a;}
+.cm-s-default .cm-variable-3 {color: #085;}
+.cm-s-default .cm-comment {color: #a50;}
+.cm-s-default .cm-string {color: #a11;}
+.cm-s-default .cm-string-2 {color: #f50;}
+.cm-s-default .cm-meta {color: #555;}
+.cm-s-default .cm-qualifier {color: #555;}
+.cm-s-default .cm-builtin {color: #30a;}
+.cm-s-default .cm-bracket {color: #997;}
+.cm-s-default .cm-tag {color: #170;}
+.cm-s-default .cm-attribute {color: #00c;}
+.cm-s-default .cm-hr {color: #999;}
+.cm-s-default .cm-link {color: #00c;}
+
+.cm-s-default .cm-error {color: #f00;}
+.cm-invalidchar {color: #f00;}
+
+.CodeMirror-composing { border-bottom: 2px solid; }
+
+/* Default styles for common addons */
+
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
+.CodeMirror-activeline-background {background: #e8f2ff;}
+
+/* STOP */
+
+/* The rest of this file contains styles related to the mechanics of
+   the editor. You probably shouldn't touch them. */
+
+.CodeMirror {
+  position: relative;
+  overflow: hidden;
+  background: white;
+}
+
+.CodeMirror-scroll {
+  overflow: scroll !important; /* Things will break if this is overridden */
+  /* 30px is the magic margin used to hide the element's real scrollbars */
+  /* See overflow: hidden in .CodeMirror */
+  margin-bottom: -30px; margin-right: -30px;
+  padding-bottom: 30px;
+  height: 100%;
+  outline: none; /* Prevent dragging from highlighting the element */
+  position: relative;
+}
+.CodeMirror-sizer {
+  position: relative;
+  border-right: 30px solid transparent;
+}
+
+/* The fake, visible scrollbars. Used to force redraw during scrolling
+   before actual scrolling happens, thus preventing shaking and
+   flickering artifacts. */
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
+  position: absolute;
+  z-index: 6;
+  display: none;
+}
+.CodeMirror-vscrollbar {
+  right: 0; top: 0;
+  overflow-x: hidden;
+  overflow-y: scroll;
+}
+.CodeMirror-hscrollbar {
+  bottom: 0; left: 0;
+  overflow-y: hidden;
+  overflow-x: scroll;
+}
+.CodeMirror-scrollbar-filler {
+  right: 0; bottom: 0;
+}
+.CodeMirror-gutter-filler {
+  left: 0; bottom: 0;
+}
+
+.CodeMirror-gutters {
+  position: absolute; left: 0; top: 0;
+  min-height: 100%;
+  z-index: 3;
+}
+.CodeMirror-gutter {
+  white-space: normal;
+  height: 100%;
+  display: inline-block;
+  vertical-align: top;
+  margin-bottom: -30px;
+}
+.CodeMirror-gutter-wrapper {
+  position: absolute;
+  z-index: 4;
+  background: none !important;
+  border: none !important;
+}
+.CodeMirror-gutter-background {
+  position: absolute;
+  top: 0; bottom: 0;
+  z-index: 4;
+}
+.CodeMirror-gutter-elt {
+  position: absolute;
+  cursor: default;
+  z-index: 4;
+}
+.CodeMirror-gutter-wrapper {
   -webkit-user-select: none;
   -moz-user-select: none;
-  -ms-user-select: none;
-  -o-user-select: none;
   user-select: none;
-
-  flex: 1;
-  white-space: nowrap;
+}
+
+.CodeMirror-lines {
+  cursor: text;
+  min-height: 1px; /* prevents collapsing before first draw */
+}
+.CodeMirror pre {
+  /* Reset some styles that the rest of the page might have set */
+  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
+  border-width: 0;
+  background: transparent;
+  font-family: inherit;
+  font-size: inherit;
+  margin: 0;
+  white-space: pre;
+  word-wrap: normal;
+  line-height: inherit;
+  color: inherit;
+  z-index: 2;
+  position: relative;
+  overflow: visible;
+  -webkit-tap-highlight-color: transparent;
+  -webkit-font-variant-ligatures: contextual;
+  font-variant-ligatures: contextual;
+}
+.CodeMirror-wrap pre {
+  word-wrap: break-word;
+  white-space: pre-wrap;
+  word-break: normal;
+}
+
+.CodeMirror-linebackground {
+  position: absolute;
+  left: 0; right: 0; top: 0; bottom: 0;
+  z-index: 0;
+}
+
+.CodeMirror-linewidget {
+  position: relative;
+  z-index: 2;
   overflow: auto;
 }
 
-.tree button {
+.CodeMirror-widget {}
+
+.CodeMirror-code {
+  outline: none;
+}
+
+/* Force content-box sizing for the elements where we expect it */
+.CodeMirror-scroll,
+.CodeMirror-sizer,
+.CodeMirror-gutter,
+.CodeMirror-gutters,
+.CodeMirror-linenumber {
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+
+.CodeMirror-measure {
+  position: absolute;
+  width: 100%;
+  height: 0;
+  overflow: hidden;
+  visibility: hidden;
+}
+
+.CodeMirror-cursor {
+  position: absolute;
+  pointer-events: none;
+}
+.CodeMirror-measure pre { position: static; }
+
+div.CodeMirror-cursors {
+  visibility: hidden;
+  position: relative;
+  z-index: 3;
+}
+div.CodeMirror-dragcursors {
+  visibility: visible;
+}
+
+.CodeMirror-focused div.CodeMirror-cursors {
+  visibility: visible;
+}
+
+.CodeMirror-selected { background: #d9d9d9; }
+.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
+.CodeMirror-crosshair { cursor: crosshair; }
+.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
+.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
+
+.cm-searching {
+  background: #ffa;
+  background: rgba(255, 255, 0, .4);
+}
+
+/* Used to force a border model for a node */
+.cm-force-border { padding-right: .1px; }
+
+@media print {
+  /* Hide the cursor when printing */
+  .CodeMirror div.CodeMirror-cursors {
+    visibility: hidden;
+  }
+}
+
+/* See issue #2901 */
+.cm-tab-wrap-hack:after { content: ''; }
+
+/* Help users use markselection to safely style text background */
+span.CodeMirror-selectedtext { background: none; }
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+:root {
+  /* --breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#light"); */
+  /* --breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#light-hover"); */
+  --breakpoint-active-color: rgba(44,187,15,.2);
+  --breakpoint-active-color-hover: rgba(44,187,15,.5);
+  /* --breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#light-conditional"); */
+}
+
+.theme-dark:root {
+  /* --breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#dark"); */
+  /* --breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-hover"); */
+  --breakpoint-active-color: rgba(0,255,175,.4);
+  --breakpoint-active-color-hover: rgba(0,255,175,.7);
+  /* --breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-conditional"); */
+}
+
+.CodeMirror .errors {
+  width: 16px;
+}
+
+.CodeMirror .error {
+  display: inline-block;
+  margin-left: 5px;
+  width: 12px;
+  height: 12px;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: contain;
+  /* background-image: url("chrome://devtools/skin/images/editor-error.png"); */
+  opacity: 0.75;
+}
+
+.CodeMirror .hit-counts {
+  width: 6px;
+}
+
+.CodeMirror .hit-count {
+  display: inline-block;
+  height: 12px;
+  border: solid rgba(0,0,0,0.2);
+  border-width: 1px 1px 1px 0;
+  border-radius: 0 3px 3px 0;
+  padding: 0 3px;
+  font-size: 10px;
+  pointer-events: none;
+}
+
+.CodeMirror-linenumber:before {
+  content: " ";
   display: block;
-}
-
-.tree .node {
-  padding: 2px 5px;
+  width: calc(100% - 3px);
+  position: absolute;
+  top: 1px;
+  left: 0;
+  height: 12px;
+  z-index: -1;
+  background-size: calc(100% - 2px) 12px;
+  background-repeat: no-repeat;
+  background-position: right center;
+  padding-inline-end: 9px;
+}
+
+.breakpoint .CodeMirror-linenumber {
+  color: var(--theme-body-background);
+}
+
+.breakpoint .CodeMirror-linenumber:before {
+  background-image: var(--breakpoint-background) !important;
+}
+
+.conditional .CodeMirror-linenumber:before {
+  background-image: var(--breakpoint-conditional-background) !important;
+}
+
+.debug-line .CodeMirror-linenumber {
+  background-color: var(--breakpoint-active-color);
+}
+
+.theme-dark .debug-line .CodeMirror-linenumber {
+  color: #c0c0c0;
+}
+
+.debug-line .CodeMirror-line {
+  background-color: var(--breakpoint-active-color) !important;
+}
+
+/* Don't display the highlight color since the debug line
+   is already highlighted */
+.debug-line .CodeMirror-activeline-background {
+  display: none;
+}
+
+.CodeMirror {
+  cursor: text;
+  height: 100%;
+}
+
+.CodeMirror-gutters {
+  cursor: default;
+}
+
+/* This is to avoid the fake horizontal scrollbar div of codemirror to go 0
+height when floating scrollbars are active. Make sure that this value is equal
+to the maximum of `min-height` specific to the `scrollbar[orient="horizontal"]`
+selector in floating-scrollbar-light.css across all platforms. */
+.CodeMirror-hscrollbar {
+  min-height: 10px;
+}
+
+/* This is to avoid the fake vertical scrollbar div of codemirror to go 0
+width when floating scrollbars are active. Make sure that this value is equal
+to the maximum of `min-width` specific to the `scrollbar[orient="vertical"]`
+selector in floating-scrollbar-light.css across all platforms. */
+.CodeMirror-vscrollbar {
+  min-width: 10px;
+}
+
+.cm-trailingspace {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==");
+  opacity: 0.75;
+  background-position: left bottom;
+  background-repeat: repeat-x;
+}
+
+.cm-highlight {
   position: relative;
+}
+
+.cm-highlight:before {
+  position: absolute;
+  border-top-style: solid;
+  border-bottom-style: solid;
+  border-top-color: var(--theme-comment-alt);
+  border-bottom-color: var(--theme-comment-alt);
+  border-top-width: 1px;
+  border-bottom-width: 1px;
+  top: -1px;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  content: "";
+  margin-bottom: -1px;
+}
+
+.cm-highlight-full:before {
+  border: 1px solid var(--theme-comment-alt);
+}
+
+.cm-highlight-start:before {
+  border-left-width: 1px;
+  border-left-style: solid;
+  border-left-color: var(--theme-comment-alt);
+  margin: 0 0 -1px -1px;
+  border-top-left-radius: 2px;
+  border-bottom-left-radius: 2px;
+}
+
+.cm-highlight-end:before {
+  border-right-width: 1px;
+  border-right-style: solid;
+  border-right-color: var(--theme-comment-alt);
+  margin: 0 -1px -1px 0;
+  border-top-right-radius: 2px;
+  border-bottom-right-radius: 2px;
+}
+
+/* CodeMirror dialogs styling */
+
+.CodeMirror-dialog {
+  padding: 4px 3px;
+}
+
+.CodeMirror-dialog,
+.CodeMirror-dialog input {
+  font: message-box;
+}
+
+/* Fold addon */
+
+.CodeMirror-foldmarker {
+  color: blue;
+  text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
+  font-family: sans-serif;
+  line-height: .3;
   cursor: pointer;
 }
 
-.tree-node:hover {
-  background: var(--theme-tab-toolbar-background);
-}
-
-.tree .node.focused {
-  color: white;
-  background-color: var(--theme-selection-background);
-}
-
-.tree .node > div {
-  margin-left: 10px;
-}
-
-.tree .node.focused svg {
-  fill: white;
-}
-
-.sources-list .tree-node button {
-  position: fixed;
+.CodeMirror-foldgutter {
+  width: 16px; /* Same as breakpoints gutter above */
+}
+
+.CodeMirror-foldgutter-open,
+.CodeMirror-foldgutter-folded {
+  color: #555;
+  cursor: pointer;
+}
+
+.CodeMirror-foldgutter-open:after {
+  font-size: 120%;
+  content: "\25BE";
+}
+
+.CodeMirror-foldgutter-folded:after {
+  font-size: 120%;
+  content: "\25B8";
+}
+
+.CodeMirror-hints {
+  position: absolute;
+  z-index: 10;
+  overflow: hidden;
+  list-style: none;
+  margin: 0;
+  padding: 2px;
+  border-radius: 3px;
+  font-size: 90%;
+  max-height: 20em;
+  overflow-y: auto;
+}
+
+.CodeMirror-hint {
+  margin: 0;
+  padding: 0 4px;
+  border-radius: 2px;
+  max-width: 19em;
+  overflow: hidden;
+  white-space: pre;
+  cursor: pointer;
+}
+
+.CodeMirror-Tern-completion {
+  padding-inline-start: 22px;
+  position: relative;
+  line-height: 18px;
+}
+
+.CodeMirror-Tern-completion:before {
+  position: absolute;
+  left: 2px;
+  bottom: 2px;
+  border-radius: 50%;
+  font-size: 12px;
+  font-weight: bold;
+  height: 15px;
+  width: 15px;
+  line-height: 16px;
+  text-align: center;
+  color: #ffffff;
+  box-sizing: border-box;
+}
+
+.CodeMirror-Tern-completion-unknown:before {
+  content: "?";
+}
+
+.CodeMirror-Tern-completion-object:before {
+  content: "O";
+}
+
+.CodeMirror-Tern-completion-fn:before {
+  content: "F";
+}
+
+.CodeMirror-Tern-completion-array:before {
+  content: "A";
+}
+
+.CodeMirror-Tern-completion-number:before {
+  content: "N";
+}
+
+.CodeMirror-Tern-completion-string:before {
+  content: "S";
+}
+
+.CodeMirror-Tern-completion-bool:before {
+  content: "B";
+}
+
+.CodeMirror-Tern-completion-guess {
+  color: #999;
+}
+
+.CodeMirror-Tern-tooltip {
+  border-radius: 3px;
+  padding: 2px 5px;
+  white-space: pre-wrap;
+  max-width: 40em;
+  position: absolute;
+  z-index: 10;
+}
+
+.CodeMirror-Tern-hint-doc {
+  max-width: 25em;
+}
+
+.CodeMirror-Tern-farg-current {
+  text-decoration: underline;
+}
+
+.CodeMirror-Tern-fhint-guess {
+  opacity: .7;
 }
 .toggle-button-start,
 .toggle-button-end {
   position: absolute;
   width: 16px;
   height: 16px;
   transition: transform 0.25s ease-in-out;
   margin: 0 4px;
+  cursor: pointer;
 }
 
 .toggle-button-start svg,
 .toggle-button-end svg {
   fill: var(--theme-comment);
 }
 
-.toggle-button-end svg {
+html:not([dir="rtl"]) .toggle-button-end svg,
+html[dir="rtl"] .toggle-button-start svg {
   transform: rotate(180deg);
 }
 
-.toggle-button-start.vertical svg {
-  transform: rotate(-90deg);
-}
-
 .toggle-button-end.vertical svg {
-  transform: rotate(90deg);
+  transform: rotate(-90deg);
 }
 
 .toggle-button-start {
   top: 7px;
-  left: 0;
+  offset-inline-start: 0;
 }
 
 .toggle-button-end {
   top: 7px;
-  right: 0;
+  offset-inline-end: 0;
 }
 
 .toggle-button-start.collapsed,
 .toggle-button-end.collapsed {
   transform: rotate(180deg);
 }
 
 .source-footer {
@@ -1320,17 +1890,16 @@ html[dir="rtl"] .editor-mount {
 .why-paused {
   background-color: var(--breakpoint-active-color);
   border: 1.7px solid var(--breakpoint-active-color);
   color: var(--theme-highlight-blue);
   padding: 10px 10px 10px 20px;
   white-space: normal;
   opacity: 0.9;
   font-size: 12px;
-  text-align: center;
   font-weight: bold;
 }
 
 .theme-dark .secondary-panes .why-paused {
   color: white;
 }
 .breakpoints-list * {
   -moz-user-select: none;
@@ -1406,17 +1975,20 @@ html .breakpoints-list .breakpoint.pause
 }
 
 :root.theme-dark .breakpoint-snippet {
   color: var(--theme-body-color);
   opacity: 0.6;
 }
 
 .breakpoint-snippet {
+  overflow: hidden;
+  text-overflow: ellipsis;
   padding-inline-start: 18px;
+  padding-inline-end: 18px;
 }
 
 .breakpoint .close-btn {
   position: absolute;
   offset-inline-end: 6px;
   top: 12px;
 }
 
@@ -1497,17 +2069,17 @@ html .breakpoints-list .breakpoint.pause
   color: var(--theme-content-color2);
   max-width: 50% !important;
 }
 
 .expression-error {
   color: var(--theme-highlight-red);
 }
 
-.object-node.not-enumerable {
+.object-node.default-property {
   opacity: 0.6;
 }
 
 .object-label {
   color: var(--theme-highlight-blue);
 }
 
 .objectBox-object,
@@ -1800,16 +2372,71 @@ html .breakpoints-list .breakpoint.pause
   z-index: 100;
 }
 
 .welcomebox .toggle-button-end {
   bottom: 11px;
   position: absolute;
   top: auto;
 }
+.dropdown {
+  background: var(--theme-body-background);
+  border: 1px solid var(--theme-splitter-color);
+  box-shadow: 0 4px 4px 0 var(--theme-search-overlays-semitransparent);
+  max-height: 300px;
+  position: absolute;
+  offset-inline-end: 8px;
+  top: 35px;
+  width: 150px;
+  z-index: 1000;
+}
+
+.dropdown-button {
+  position: absolute;
+  offset-inline-end: 18px;
+  top: 4px;
+  font-size: 18px;
+  color: var(--theme-comment);
+  cursor: pointer;
+  background: none;
+  border: none;
+  padding: 0 5px;
+  font-weight: 100;
+}
+
+.dropdown li {
+  transition: all 0.25s ease;
+  padding: 2px 10px 10px 5px;
+  overflow: hidden;
+  height: 30px;
+  text-overflow: ellipsis;
+}
+
+.dropdown li:hover {
+  background-color: var(--theme-search-overlays-semitransparent);
+  cursor: pointer;
+}
+
+.dropdown ul {
+  list-style: none;
+  line-height: 2em;
+  font-size: 1em;
+  margin: 0;
+  padding: 0;
+}
+
+.dropdown-mask {
+  position: fixed;
+  width: 100%;
+  height: 100%;
+  background: transparent;
+  z-index: 999;
+  left: 0;
+  top: 0;
+}
 .source-header {
   border-bottom: 1px solid var(--theme-splitter-color);
   height: 30px;
   display: flex;
   flex: 1;
   flex-flow: row wrap;
   -webkit-align-items: stretch;
   align-items: stretch;
@@ -1826,17 +2453,17 @@ html .breakpoints-list .breakpoint.pause
   margin-inline-start: 21px;
 }
 
 .source-header .new-tab-btn {
   width: 14px;
   height: 14px;
   display: inline-block;
   position: relative;
-  top: 5px;
+  top: 4px;
   margin: 4px;
   margin-inline-start: 8px;
   line-height: 0;
   cursor: pointer;
   fill: var(--theme-comment);
   transition: 0.1s ease;
 }
 
@@ -1921,96 +2548,9 @@ html .breakpoints-list .breakpoint.pause
 .source-tab .close {
   display: none;
 }
 
 .source-tab:hover .close {
   display: block;
 }
 
-.toggle-button-start,
-.toggle-button-end {
-  position: absolute;
-  width: 16px;
-  height: 16px;
-  margin: 0 4px;
-  cursor: pointer;
-}
-
-.toggle-button-start svg,
-.toggle-button-end svg {
-  fill: var(--theme-comment);
-}
-
-.toggle-button-end svg {
-  transform: rotate(180deg);
-}
-
-.toggle-button-start {
-  top: 8px;
-  left: 0;
-}
-
-.toggle-button-end {
-  top: 8px;
-  right: 0;
-}
-
-.toggle-button-start.collapsed,
-.toggle-button-end.collapsed {
-  transform: rotate(180deg);
-  flex: 1;
-}
-.dropdown {
-  background: var(--theme-body-background);
-  border: 1px solid var(--theme-splitter-color);
-  box-shadow: 0 4px 4px 0 var(--theme-search-overlays-semitransparent);
-  max-height: 300px;
-  position: absolute;
-  right: 8px;
-  top: 35px;
-  width: 150px;
-  z-index: 1000;
-}
-
-.dropdown-button {
-  position: absolute;
-  right: 18px;
-  top: 4px;
-  font-size: 18px;
-  color: var(--theme-body-color);
-  cursor: pointer;
-  background: none;
-  border: none;
-}
-
-.dropdown li {
-  transition: all 0.25s ease;
-  padding: 2px 10px 10px 5px;
-  overflow: hidden;
-  height: 30px;
-  text-overflow: ellipsis;
-}
-
-.dropdown li:hover {
-  background-color: var(--theme-search-overlays-semitransparent);
-  cursor: pointer;
-}
-
-.dropdown ul {
-  list-style: none;
-  line-height: 2em;
-  font-size: 1em;
-  margin: 0;
-  padding: 0;
-}
-
-.dropdown-mask {
-  position: fixed;
-  width: 100%;
-  height: 100%;
-  background: transparent;
-  z-index: 999;
-  left: 0;
-  top: 0;
-}
-
 /*# sourceMappingURL=debugger.css.map*/
\ No newline at end of file
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -72,111 +72,101 @@ var Debugger =
 	module.exports = __webpack_require__(1);
 
 
 /***/ },
 /* 1 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var React = __webpack_require__(2);
-
+	
 	var _require = __webpack_require__(3),
 	    bindActionCreators = _require.bindActionCreators,
 	    combineReducers = _require.combineReducers;
-
+	
 	var ReactDOM = __webpack_require__(22);
-
+	
 	var _require2 = __webpack_require__(23),
 	    getClient = _require2.getClient,
 	    firefox = _require2.firefox;
-
-	var _require3 = __webpack_require__(178),
+	
+	var _require3 = __webpack_require__(129),
 	    renderRoot = _require3.renderRoot,
 	    bootstrap = _require3.bootstrap,
-	    L10N = _require3.L10N;
-
-	var _require4 = __webpack_require__(65),
+	    L10N = _require3.L10N,
+	    unmountRoot = _require3.unmountRoot;
+	
+	var _require4 = __webpack_require__(197),
 	    getValue = _require4.getValue,
 	    isFirefoxPanel = _require4.isFirefoxPanel;
-
-	var configureStore = __webpack_require__(227);
-
-	var _require5 = __webpack_require__(237),
+	
+	var configureStore = __webpack_require__(244);
+	
+	var _require5 = __webpack_require__(254),
 	    onConnect = _require5.onConnect,
 	    onFirefoxConnect = _require5.onFirefoxConnect;
-
-	var reducers = __webpack_require__(238);
-	var selectors = __webpack_require__(253);
-
-	var App = __webpack_require__(254);
-
+	
+	var reducers = __webpack_require__(288);
+	var selectors = __webpack_require__(303);
+	
+	var App = __webpack_require__(304);
+	
 	var createStore = configureStore({
 	  log: getValue("logging.actions"),
 	  makeThunkArgs: (args, state) => {
 	    return Object.assign({}, args, { client: getClient(state) });
 	  }
 	});
-
+	
 	var store = createStore(combineReducers(reducers));
-	var actions = bindActionCreators(__webpack_require__(255), store.dispatch);
-
+	var actions = bindActionCreators(__webpack_require__(314), store.dispatch);
+	
 	if (!isFirefoxPanel()) {
 	  window.L10N = L10N;
-	  window.L10N.setBundle(__webpack_require__(500));
-	}
-
+	  window.L10N.setBundle(__webpack_require__(636));
+	}
+	
 	window.appStore = store;
-
+	
 	// Expose the bound actions so external things can do things like
 	// selecting a source.
 	window.actions = {
 	  selectSource: actions.selectSource,
 	  selectSourceURL: actions.selectSourceURL
 	};
-
+	
 	// Globals needed for mocha integration tests
 	window.getGlobalsForTesting = () => {
 	  return {
 	    debuggerStore: store,
 	    launchpadStore: window.launchpadStore,
 	    selectors,
 	    actions
 	  };
 	};
-
-	function unmountRoot() {
-	  var mount = document.querySelector("#mount div");
-	  ReactDOM.unmountComponentAtNode(mount);
-	}
-
+	
 	if (isFirefoxPanel()) {
 	  (function () {
-	    var sourceMap = __webpack_require__(257);
-	    var prettyPrint = __webpack_require__(268);
-
+	    var sourceMap = __webpack_require__(316);
+	    var prettyPrint = __webpack_require__(383);
+	
 	    module.exports = {
 	      bootstrap: (_ref) => {
 	        var threadClient = _ref.threadClient,
 	            tabTarget = _ref.tabTarget,
 	            toolbox = _ref.toolbox;
-
-	        // jlast: remove when docker updates
-	        if (!window.L10N) {
-	          window.L10N = L10N;
-	          window.L10N.setBundle(__webpack_require__(500));
-	        }
-
+	
 	        firefox.setThreadClient(threadClient);
 	        firefox.setTabTarget(tabTarget);
 	        renderRoot(React, ReactDOM, App, store);
 	        firefox.initPage(actions);
 	        return onFirefoxConnect(actions, firefox);
 	      },
 	      destroy: () => {
-	        unmountRoot();
+	        unmountRoot(ReactDOM);
 	        sourceMap.destroyWorker();
 	        prettyPrint.destroyWorker();
 	      },
 	      store: store,
 	      actions: actions,
 	      selectors: selectors,
 	      client: firefox.clientCommands
 	    };
@@ -191,92 +181,92 @@ var Debugger =
 
 	module.exports = devtoolsRequire("devtools/client/shared/vendor/react");
 
 /***/ },
 /* 3 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
-
+	
 	exports.__esModule = true;
 	exports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined;
-
+	
 	var _createStore = __webpack_require__(4);
-
+	
 	var _createStore2 = _interopRequireDefault(_createStore);
-
+	
 	var _combineReducers = __webpack_require__(17);
-
+	
 	var _combineReducers2 = _interopRequireDefault(_combineReducers);
-
+	
 	var _bindActionCreators = __webpack_require__(19);
-
+	
 	var _bindActionCreators2 = _interopRequireDefault(_bindActionCreators);
-
+	
 	var _applyMiddleware = __webpack_require__(20);
-
+	
 	var _applyMiddleware2 = _interopRequireDefault(_applyMiddleware);
-
+	
 	var _compose = __webpack_require__(21);
-
+	
 	var _compose2 = _interopRequireDefault(_compose);
-
+	
 	var _warning = __webpack_require__(18);
-
+	
 	var _warning2 = _interopRequireDefault(_warning);
-
+	
 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
-
+	
 	/*
 	* This is a dummy function to check if the function name has been altered by minification.
 	* If the function has been minified and NODE_ENV !== 'production', warn the user.
 	*/
 	function isCrushed() {}
-
+	
 	if (false) {
 	  (0, _warning2["default"])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');
 	}
-
+	
 	exports.createStore = _createStore2["default"];
 	exports.combineReducers = _combineReducers2["default"];
 	exports.bindActionCreators = _bindActionCreators2["default"];
 	exports.applyMiddleware = _applyMiddleware2["default"];
 	exports.compose = _compose2["default"];
 
 /***/ },
 /* 4 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
-
+	
 	exports.__esModule = true;
 	exports.ActionTypes = undefined;
 	exports["default"] = createStore;
-
+	
 	var _isPlainObject = __webpack_require__(5);
-
+	
 	var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
-
+	
 	var _symbolObservable = __webpack_require__(15);
-
+	
 	var _symbolObservable2 = _interopRequireDefault(_symbolObservable);
-
+	
 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
-
+	
 	/**
 	 * These are private action types reserved by Redux.
 	 * For any unknown actions, you must return the current state.
 	 * If the current state is undefined, you must return the initial state.
 	 * Do not reference these action types directly in your code.
 	 */
 	var ActionTypes = exports.ActionTypes = {
 	  INIT: '@@redux/INIT'
 	};
-
+	
 	/**
 	 * Creates a Redux store that holds the state tree.
 	 * The only way to change the data in the store is to call `dispatch()` on it.
 	 *
 	 * There should only be a single store in your app. To specify how different
 	 * parts of the state tree respond to actions, you may combine several reducers
 	 * into a single reducer function by using `combineReducers`.
 	 *
@@ -294,55 +284,55 @@ var Debugger =
 	 * time travel, persistence, etc. The only store enhancer that ships with Redux
 	 * is `applyMiddleware()`.
 	 *
 	 * @returns {Store} A Redux store that lets you read the state, dispatch actions
 	 * and subscribe to changes.
 	 */
 	function createStore(reducer, initialState, enhancer) {
 	  var _ref2;
-
+	
 	  if (typeof initialState === 'function' && typeof enhancer === 'undefined') {
 	    enhancer = initialState;
 	    initialState = undefined;
 	  }
-
+	
 	  if (typeof enhancer !== 'undefined') {
 	    if (typeof enhancer !== 'function') {
 	      throw new Error('Expected the enhancer to be a function.');
 	    }
-
+	
 	    return enhancer(createStore)(reducer, initialState);
 	  }
-
+	
 	  if (typeof reducer !== 'function') {
 	    throw new Error('Expected the reducer to be a function.');
 	  }
-
+	
 	  var currentReducer = reducer;
 	  var currentState = initialState;
 	  var currentListeners = [];
 	  var nextListeners = currentListeners;
 	  var isDispatching = false;
-
+	
 	  function ensureCanMutateNextListeners() {
 	    if (nextListeners === currentListeners) {
 	      nextListeners = currentListeners.slice();
 	    }
 	  }
-
+	
 	  /**
 	   * Reads the state tree managed by the store.
 	   *
 	   * @returns {any} The current state tree of your application.
 	   */
 	  function getState() {
 	    return currentState;
 	  }
-
+	
 	  /**
 	   * Adds a change listener. It will be called any time an action is dispatched,
 	   * and some part of the state tree may potentially have changed. You may then
 	   * call `getState()` to read the current state tree inside the callback.
 	   *
 	   * You may call `dispatch()` from a change listener, with the following
 	   * caveats:
 	   *
@@ -360,35 +350,35 @@ var Debugger =
 	   *
 	   * @param {Function} listener A callback to be invoked on every dispatch.
 	   * @returns {Function} A function to remove this change listener.
 	   */
 	  function subscribe(listener) {
 	    if (typeof listener !== 'function') {
 	      throw new Error('Expected listener to be a function.');
 	    }
-
+	
 	    var isSubscribed = true;
-
+	
 	    ensureCanMutateNextListeners();
 	    nextListeners.push(listener);
-
+	
 	    return function unsubscribe() {
 	      if (!isSubscribed) {
 	        return;
 	      }
-
+	
 	      isSubscribed = false;
-
+	
 	      ensureCanMutateNextListeners();
 	      var index = nextListeners.indexOf(listener);
 	      nextListeners.splice(index, 1);
 	    };
 	  }
-
+	
 	  /**
 	   * Dispatches an action. It is the only way to trigger a state change.
 	   *
 	   * The `reducer` function, used to create the store, will be called with the
 	   * current state tree and the given `action`. Its return value will
 	   * be considered the **next** state of the tree, and the change listeners
 	   * will be notified.
 	   *
@@ -408,136 +398,136 @@ var Debugger =
 	   *
 	   * Note that, if you use a custom middleware, it may wrap `dispatch()` to
 	   * return something else (for example, a Promise you can await).
 	   */
 	  function dispatch(action) {
 	    if (!(0, _isPlainObject2["default"])(action)) {
 	      throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');
 	    }
-
+	
 	    if (typeof action.type === 'undefined') {
 	      throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?');
 	    }
-
+	
 	    if (isDispatching) {
 	      throw new Error('Reducers may not dispatch actions.');
 	    }
-
+	
 	    try {
 	      isDispatching = true;
 	      currentState = currentReducer(currentState, action);
 	    } finally {
 	      isDispatching = false;
 	    }
-
+	
 	    var listeners = currentListeners = nextListeners;
 	    for (var i = 0; i < listeners.length; i++) {
 	      listeners[i]();
 	    }
-
+	
 	    return action;
 	  }
-
+	
 	  /**
 	   * Replaces the reducer currently used by the store to calculate the state.
 	   *
 	   * You might need this if your app implements code splitting and you want to
 	   * load some of the reducers dynamically. You might also need this if you
 	   * implement a hot reloading mechanism for Redux.
 	   *
 	   * @param {Function} nextReducer The reducer for the store to use instead.
 	   * @returns {void}
 	   */
 	  function replaceReducer(nextReducer) {
 	    if (typeof nextReducer !== 'function') {
 	      throw new Error('Expected the nextReducer to be a function.');
 	    }
-
+	
 	    currentReducer = nextReducer;
 	    dispatch({ type: ActionTypes.INIT });
 	  }
-
+	
 	  /**
 	   * Interoperability point for observable/reactive libraries.
 	   * @returns {observable} A minimal observable of state changes.
 	   * For more information, see the observable proposal:
 	   * https://github.com/zenparsing/es-observable
 	   */
 	  function observable() {
 	    var _ref;
-
+	
 	    var outerSubscribe = subscribe;
 	    return _ref = {
 	      /**
 	       * The minimal observable subscription method.
 	       * @param {Object} observer Any object that can be used as an observer.
 	       * The observer object should have a `next` method.
 	       * @returns {subscription} An object with an `unsubscribe` method that can
 	       * be used to unsubscribe the observable from the store, and prevent further
 	       * emission of values from the observable.
 	       */
-
+	
 	      subscribe: function subscribe(observer) {
 	        if (typeof observer !== 'object') {
 	          throw new TypeError('Expected the observer to be an object.');
 	        }
-
+	
 	        function observeState() {
 	          if (observer.next) {
 	            observer.next(getState());
 	          }
 	        }
-
+	
 	        observeState();
 	        var unsubscribe = outerSubscribe(observeState);
 	        return { unsubscribe: unsubscribe };
 	      }
 	    }, _ref[_symbolObservable2["default"]] = function () {
 	      return this;
 	    }, _ref;
 	  }
-
+	
 	  // When a store is created, an "INIT" action is dispatched so that every
 	  // reducer returns their initial state. This effectively populates
 	  // the initial state tree.
 	  dispatch({ type: ActionTypes.INIT });
-
+	
 	  return _ref2 = {
 	    dispatch: dispatch,
 	    subscribe: subscribe,
 	    getState: getState,
 	    replaceReducer: replaceReducer
 	  }, _ref2[_symbolObservable2["default"]] = observable, _ref2;
 	}
 
 /***/ },
 /* 5 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var baseGetTag = __webpack_require__(6),
 	    getPrototype = __webpack_require__(12),
 	    isObjectLike = __webpack_require__(14);
-
+	
 	/** `Object#toString` result references. */
 	var objectTag = '[object Object]';
-
+	
 	/** Used for built-in method references. */
 	var funcProto = Function.prototype,
 	    objectProto = Object.prototype;
-
+	
 	/** Used to resolve the decompiled source of functions. */
 	var funcToString = funcProto.toString;
-
+	
 	/** Used to check objects for own properties. */
 	var hasOwnProperty = objectProto.hasOwnProperty;
-
+	
 	/** Used to infer the `Object` constructor. */
 	var objectCtorString = funcToString.call(Object);
-
+	
 	/**
 	 * Checks if `value` is a plain object, that is, an object created by the
 	 * `Object` constructor or one with a `[[Prototype]]` of `null`.
 	 *
 	 * @static
 	 * @memberOf _
 	 * @since 0.8.0
 	 * @category Lang
@@ -568,181 +558,181 @@ var Debugger =
 	  var proto = getPrototype(value);
 	  if (proto === null) {
 	    return true;
 	  }
 	  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
 	  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
 	    funcToString.call(Ctor) == objectCtorString;
 	}
-
+	
 	module.exports = isPlainObject;
 
 
 /***/ },
 /* 6 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var Symbol = __webpack_require__(7),
 	    getRawTag = __webpack_require__(10),
 	    objectToString = __webpack_require__(11);
-
+	
 	/** `Object#toString` result references. */
 	var nullTag = '[object Null]',
 	    undefinedTag = '[object Undefined]';
-
+	
 	/** Built-in value references. */
 	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
-
+	
 	/**
 	 * The base implementation of `getTag` without fallbacks for buggy environments.
 	 *
 	 * @private
 	 * @param {*} value The value to query.
 	 * @returns {string} Returns the `toStringTag`.
 	 */
 	function baseGetTag(value) {
 	  if (value == null) {
 	    return value === undefined ? undefinedTag : nullTag;
 	  }
 	  return (symToStringTag && symToStringTag in Object(value))
 	    ? getRawTag(value)
 	    : objectToString(value);
 	}
-
+	
 	module.exports = baseGetTag;
 
 
 /***/ },
 /* 7 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var root = __webpack_require__(8);
-
+	
 	/** Built-in value references. */
 	var Symbol = root.Symbol;
-
+	
 	module.exports = Symbol;
 
 
 /***/ },
 /* 8 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var freeGlobal = __webpack_require__(9);
-
+	
 	/** Detect free variable `self`. */
 	var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
-
+	
 	/** Used as a reference to the global object. */
 	var root = freeGlobal || freeSelf || Function('return this')();
-
+	
 	module.exports = root;
 
 
 /***/ },
 /* 9 */
 /***/ function(module, exports) {
 
 	/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */
 	var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
-
+	
 	module.exports = freeGlobal;
-
+	
 	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
 
 /***/ },
 /* 10 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var Symbol = __webpack_require__(7);
-
+	
 	/** Used for built-in method references. */
 	var objectProto = Object.prototype;
-
+	
 	/** Used to check objects for own properties. */
 	var hasOwnProperty = objectProto.hasOwnProperty;
-
+	
 	/**
 	 * Used to resolve the
 	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 	 * of values.
 	 */
 	var nativeObjectToString = objectProto.toString;
-
+	
 	/** Built-in value references. */
 	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
-
+	
 	/**
 	 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
 	 *
 	 * @private
 	 * @param {*} value The value to query.
 	 * @returns {string} Returns the raw `toStringTag`.
 	 */
 	function getRawTag(value) {
 	  var isOwn = hasOwnProperty.call(value, symToStringTag),
 	      tag = value[symToStringTag];
-
+	
 	  try {
 	    value[symToStringTag] = undefined;
 	    var unmasked = true;
 	  } catch (e) {}
-
+	
 	  var result = nativeObjectToString.call(value);
 	  if (unmasked) {
 	    if (isOwn) {
 	      value[symToStringTag] = tag;
 	    } else {
 	      delete value[symToStringTag];
 	    }
 	  }
 	  return result;
 	}
-
+	
 	module.exports = getRawTag;
 
 
 /***/ },
 /* 11 */
 /***/ function(module, exports) {
 
 	/** Used for built-in method references. */
 	var objectProto = Object.prototype;
-
+	
 	/**
 	 * Used to resolve the
 	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 	 * of values.
 	 */
 	var nativeObjectToString = objectProto.toString;
-
+	
 	/**
 	 * Converts `value` to a string using `Object.prototype.toString`.
 	 *
 	 * @private
 	 * @param {*} value The value to convert.
 	 * @returns {string} Returns the converted string.
 	 */
 	function objectToString(value) {
 	  return nativeObjectToString.call(value);
 	}
-
+	
 	module.exports = objectToString;
 
 
 /***/ },
 /* 12 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var overArg = __webpack_require__(13);
-
+	
 	/** Built-in value references. */
 	var getPrototype = overArg(Object.getPrototypeOf, Object);
-
+	
 	module.exports = getPrototype;
 
 
 /***/ },
 /* 13 */
 /***/ function(module, exports) {
 
 	/**
@@ -753,17 +743,17 @@ var Debugger =
 	 * @param {Function} transform The argument transform.
 	 * @returns {Function} Returns the new function.
 	 */
 	function overArg(func, transform) {
 	  return function(arg) {
 	    return func(transform(arg));
 	  };
 	}
-
+	
 	module.exports = overArg;
 
 
 /***/ },
 /* 14 */
 /***/ function(module, exports) {
 
 	/**
@@ -788,121 +778,121 @@ var Debugger =
 	 * // => false
 	 *
 	 * _.isObjectLike(null);
 	 * // => false
 	 */
 	function isObjectLike(value) {
 	  return value != null && typeof value == 'object';
 	}
-
+	
 	module.exports = isObjectLike;
 
 
 /***/ },
 /* 15 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* WEBPACK VAR INJECTION */(function(global) {/* global window */
 	'use strict';
-
+	
 	module.exports = __webpack_require__(16)(global || window || this);
-
+	
 	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
 
 /***/ },
 /* 16 */
 /***/ function(module, exports) {
 
 	'use strict';
-
+	
 	module.exports = function symbolObservablePonyfill(root) {
 		var result;
 		var Symbol = root.Symbol;
-
+	
 		if (typeof Symbol === 'function') {
 			if (Symbol.observable) {
 				result = Symbol.observable;
 			} else {
 				result = Symbol('observable');
 				Symbol.observable = result;
 			}
 		} else {
 			result = '@@observable';
 		}
-
+	
 		return result;
 	};
 
 
 /***/ },
 /* 17 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
-
+	
 	exports.__esModule = true;
 	exports["default"] = combineReducers;
-
+	
 	var _createStore = __webpack_require__(4);
-
+	
 	var _isPlainObject = __webpack_require__(5);
-
+	
 	var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
-
+	
 	var _warning = __webpack_require__(18);
-
+	
 	var _warning2 = _interopRequireDefault(_warning);
-
+	
 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
-
+	
 	function getUndefinedStateErrorMessage(key, action) {
 	  var actionType = action && action.type;
 	  var actionName = actionType && '"' + actionType.toString() + '"' || 'an action';
-
+	
 	  return 'Given action ' + actionName + ', reducer "' + key + '" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.';
 	}
-
+	
 	function getUnexpectedStateShapeWarningMessage(inputState, reducers, action) {
 	  var reducerKeys = Object.keys(reducers);
 	  var argumentName = action && action.type === _createStore.ActionTypes.INIT ? 'initialState argument passed to createStore' : 'previous state received by the reducer';
-
+	
 	  if (reducerKeys.length === 0) {
 	    return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';
 	  }
-
+	
 	  if (!(0, _isPlainObject2["default"])(inputState)) {
 	    return 'The ' + argumentName + ' has unexpected type of "' + {}.toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] + '". Expected argument to be an object with the following ' + ('keys: "' + reducerKeys.join('", "') + '"');
 	  }
-
+	
 	  var unexpectedKeys = Object.keys(inputState).filter(function (key) {
 	    return !reducers.hasOwnProperty(key);
 	  });
-
+	
 	  if (unexpectedKeys.length > 0) {
 	    return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('"' + unexpectedKeys.join('", "') + '" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('"' + reducerKeys.join('", "') + '". Unexpected keys will be ignored.');
 	  }
 	}
-
+	
 	function assertReducerSanity(reducers) {
 	  Object.keys(reducers).forEach(function (key) {
 	    var reducer = reducers[key];
 	    var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT });
-
+	
 	    if (typeof initialState === 'undefined') {
 	      throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');
 	    }
-
+	
 	    var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');
 	    if (typeof reducer(undefined, { type: type }) === 'undefined') {
 	      throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');
 	    }
 	  });
 	}
-
+	
 	/**
 	 * Turns an object whose values are different reducer functions, into a single
 	 * reducer function. It will call every child reducer, and gather their results
 	 * into a single state object, whose keys correspond to the keys of the passed
 	 * reducer functions.
 	 *
 	 * @param {Object} reducers An object whose values correspond to different
 	 * reducer functions that need to be combined into one. One handy way to obtain
@@ -919,39 +909,39 @@ var Debugger =
 	  var finalReducers = {};
 	  for (var i = 0; i < reducerKeys.length; i++) {
 	    var key = reducerKeys[i];
 	    if (typeof reducers[key] === 'function') {
 	      finalReducers[key] = reducers[key];
 	    }
 	  }
 	  var finalReducerKeys = Object.keys(finalReducers);
-
+	
 	  var sanityError;
 	  try {
 	    assertReducerSanity(finalReducers);
 	  } catch (e) {
 	    sanityError = e;
 	  }
-
+	
 	  return function combination() {
 	    var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
 	    var action = arguments[1];
-
+	
 	    if (sanityError) {
 	      throw sanityError;
 	    }
-
+	
 	    if (false) {
 	      var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action);
 	      if (warningMessage) {
 	        (0, _warning2["default"])(warningMessage);
 	      }
 	    }
-
+	
 	    var hasChanged = false;
 	    var nextState = {};
 	    for (var i = 0; i < finalReducerKeys.length; i++) {
 	      var key = finalReducerKeys[i];
 	      var reducer = finalReducers[key];
 	      var previousStateForKey = state[key];
 	      var nextStateForKey = reducer(previousStateForKey, action);
 	      if (typeof nextStateForKey === 'undefined') {
@@ -965,17 +955,17 @@ var Debugger =
 	  };
 	}
 
 /***/ },
 /* 18 */
 /***/ function(module, exports) {
 
 	'use strict';
-
+	
 	exports.__esModule = true;
 	exports["default"] = warning;
 	/**
 	 * Prints a warning in the console if it exists.
 	 *
 	 * @param {String} message The warning message.
 	 * @returns {void}
 	 */
@@ -995,25 +985,25 @@ var Debugger =
 	  /* eslint-enable no-empty */
 	}
 
 /***/ },
 /* 19 */
 /***/ function(module, exports) {
 
 	'use strict';
-
+	
 	exports.__esModule = true;
 	exports["default"] = bindActionCreators;
 	function bindActionCreator(actionCreator, dispatch) {
 	  return function () {
 	    return dispatch(actionCreator.apply(undefined, arguments));
 	  };
 	}
-
+	
 	/**
 	 * Turns an object whose values are action creators, into an object with the
 	 * same keys, but with every function wrapped into a `dispatch` call so they
 	 * may be invoked directly. This is just a convenience method, as you can call
 	 * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
 	 *
 	 * For convenience, you can also pass a single function as the first argument,
 	 * and get a function in return.
@@ -1029,21 +1019,21 @@ var Debugger =
 	 * every action creator wrapped into the `dispatch` call. If you passed a
 	 * function as `actionCreators`, the return value will also be a single
 	 * function.
 	 */
 	function bindActionCreators(actionCreators, dispatch) {
 	  if (typeof actionCreators === 'function') {
 	    return bindActionCreator(actionCreators, dispatch);
 	  }
-
+	
 	  if (typeof actionCreators !== 'object' || actionCreators === null) {
 	    throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?');
 	  }
-
+	
 	  var keys = Object.keys(actionCreators);
 	  var boundActionCreators = {};
 	  for (var i = 0; i < keys.length; i++) {
 	    var key = keys[i];
 	    var actionCreator = actionCreators[key];
 	    if (typeof actionCreator === 'function') {
 	      boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
 	    }
@@ -1051,29 +1041,29 @@ var Debugger =
 	  return boundActionCreators;
 	}
 
 /***/ },
 /* 20 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
-
+	
 	exports.__esModule = true;
-
+	
 	var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
+	
 	exports["default"] = applyMiddleware;
-
+	
 	var _compose = __webpack_require__(21);
-
+	
 	var _compose2 = _interopRequireDefault(_compose);
-
+	
 	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
-
+	
 	/**
 	 * Creates a store enhancer that applies middleware to the dispatch method
 	 * of the Redux store. This is handy for a variety of tasks, such as expressing
 	 * asynchronous actions in a concise manner, or logging every action payload.
 	 *
 	 * See `redux-thunk` package as an example of the Redux middleware.
 	 *
 	 * Because middleware is potentially asynchronous, this should be the first
@@ -1084,82 +1074,82 @@ var Debugger =
 	 *
 	 * @param {...Function} middlewares The middleware chain to be applied.
 	 * @returns {Function} A store enhancer applying the middleware.
 	 */
 	function applyMiddleware() {
 	  for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
 	    middlewares[_key] = arguments[_key];
 	  }
-
+	
 	  return function (createStore) {
 	    return function (reducer, initialState, enhancer) {
 	      var store = createStore(reducer, initialState, enhancer);
 	      var _dispatch = store.dispatch;
 	      var chain = [];
-
+	
 	      var middlewareAPI = {
 	        getState: store.getState,
 	        dispatch: function dispatch(action) {
 	          return _dispatch(action);
 	        }
 	      };
 	      chain = middlewares.map(function (middleware) {
 	        return middleware(middlewareAPI);
 	      });
 	      _dispatch = _compose2["default"].apply(undefined, chain)(store.dispatch);
-
+	
 	      return _extends({}, store, {
 	        dispatch: _dispatch
 	      });
 	    };
 	  };
 	}
 
 /***/ },
 /* 21 */
 /***/ function(module, exports) {
 
 	"use strict";
-
+	
 	exports.__esModule = true;
 	exports["default"] = compose;
 	/**
 	 * Composes single-argument functions from right to left. The rightmost
 	 * function can take multiple arguments as it provides the signature for
 	 * the resulting composite function.
 	 *
 	 * @param {...Function} funcs The functions to compose.
 	 * @returns {Function} A function obtained by composing the argument functions
 	 * from right to left. For example, compose(f, g, h) is identical to doing
 	 * (...args) => f(g(h(...args))).
 	 */
-
+	
 	function compose() {
 	  for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {
 	    funcs[_key] = arguments[_key];
 	  }
-
+	
 	  if (funcs.length === 0) {
 	    return function (arg) {
 	      return arg;
 	    };
 	  } else {
 	    var _ret = function () {
 	      var last = funcs[funcs.length - 1];
 	      var rest = funcs.slice(0, -1);
 	      return {
 	        v: function v() {
 	          return rest.reduceRight(function (composed, f) {
 	            return f(composed);
 	          }, last.apply(undefined, arguments));
 	        }
 	      };
 	    }();
-
+	
 	    if (typeof _ret === "object") return _ret.v;
 	  }
 	}
 
 /***/ },
 /* 22 */
 /***/ function(module, exports, __webpack_require__) {
 
@@ -1174,21 +1164,21 @@ var Debugger =
 	 * of patent rights can be found in the PATENTS file in the same directory.
 	 *
 	 */
 	// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
 	;(function(f) {
 	  // CommonJS
 	  if (true) {
 	    module.exports = f(__webpack_require__(2));
-
+	
 	  // RequireJS
 	  } else if (typeof define === "function" && define.amd) {
 	    define(['react'], f);
-
+	
 	  // <script>
 	  } else {
 	    var g;
 	    if (typeof window !== "undefined") {
 	      g = window;
 	    } else if (typeof global !== "undefined") {
 	      g = global;
 	    } else if (typeof self !== "undefined") {
@@ -1196,258 +1186,246 @@ var Debugger =
 	    } else {
 	      // works providing we're not in "use strict";
 	      // needed for Java 8 Nashorn
 	      // see https://github.com/facebook/react/issues/3037
 	      g = this;
 	    }
 	    g.ReactDOM = f(g.React);
 	  }
-
+	
 	})(function(React) {
 	  return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
 	});
 
 
 /***/ },
 /* 23 */
 /***/ function(module, exports, __webpack_require__) {
 
 	const { Task } = __webpack_require__(24);
 	const firefox = __webpack_require__(25);
-	const chrome = __webpack_require__(116);
-	const { createSource } = __webpack_require__(115);
-
+	const chrome = __webpack_require__(123);
+	const { createSource } = __webpack_require__(122);
+	
 	let clientType = null;
 	function getClient() {
 	  if (clientType === "chrome" || clientType === "node") {
 	    return chrome.clientCommands;
 	  }
-
+	
 	  return firefox.clientCommands;
 	}
-
+	
 	function startDebugging(connTarget, actions) {
 	  if (connTarget.type === "node") {
 	    return startDebuggingNode(connTarget.param, actions);
 	  }
-
+	
 	  const target = connTarget.type === "chrome" ? chrome : firefox;
 	  return startDebuggingTab(target, connTarget.param, actions);
 	}
-
+	
 	function startDebuggingNode(tabId, actions) {
 	  return Task.spawn(function* () {
 	    clientType = "node";
-
+	
 	    const tabs = yield chrome.connectNodeClient();
 	    const tab = tabs.find(t => t.id.indexOf(tabId) !== -1);
-
+	
 	    yield chrome.connectNode(tab.tab);
 	    chrome.initPage(actions, { clientType });
-
+	
 	    return { tabs, tab, client: chrome };
 	  });
 	}
-
+	
 	function startDebuggingTab(targetEnv, tabId, actions) {
 	  return Task.spawn(function* () {
 	    const tabs = yield targetEnv.connectClient();
 	    const tab = tabs.find(t => t.id.indexOf(tabId) !== -1);
 	    yield targetEnv.connectTab(tab.tab);
-
+	
 	    clientType = targetEnv === firefox ? "firefox" : "chrome";
 	    targetEnv.initPage(actions, { clientType });
-
+	
 	    return { tabs, tab, client: targetEnv };
 	  });
 	}
-
+	
 	module.exports = {
 	  getClient,
 	  startDebugging,
 	  firefox,
 	  chrome,
 	  createSource
 	};
 
-
 /***/ },
 /* 24 */
 /***/ function(module, exports) {
 
 	/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 	/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	/**
 	 * This object provides the public module functions.
 	 */
-	var Task = {
+	const Task = {
 	  // XXX: Not sure if this works in all cases...
 	  async: function (task) {
 	    return function () {
 	      return Task.spawn(task, this, arguments);
 	    };
 	  },
-
+	
 	  /**
 	   * Creates and starts a new task.
 	   * @param task A generator function
 	   * @return A promise, resolved when the task terminates
 	   */
 	  spawn: function (task, scope, args) {
 	    return new Promise(function (resolve, reject) {
-	      var iterator = task.apply(scope, args);
-
-	      var callNext = lastValue => {
-	        var iteration = iterator.next(lastValue);
+	      const iterator = task.apply(scope, args);
+	
+	      const callNext = lastValue => {
+	        const iteration = iterator.next(lastValue);
 	        Promise.resolve(iteration.value).then(value => {
 	          if (iteration.done) {
 	            resolve(value);
 	          } else {
 	            callNext(value);
 	          }
 	        }).catch(error => {
 	          reject(error);
 	          iterator.throw(error);
 	        });
 	      };
-
+	
 	      callNext(undefined);
 	    });
 	  }
 	};
-
+	
 	module.exports = { Task };
 
 /***/ },
 /* 25 */
 /***/ function(module, exports, __webpack_require__) {
 
-	var _require = __webpack_require__(26),
-	    DebuggerClient = _require.DebuggerClient,
-	    DebuggerTransport = _require.DebuggerTransport,
-	    TargetFactory = _require.TargetFactory,
-	    WebsocketTransport = _require.WebsocketTransport;
-
-	var _require2 = __webpack_require__(65),
-	    getValue = _require2.getValue;
-
-	var _require3 = __webpack_require__(113),
-	    setupCommands = _require3.setupCommands,
-	    clientCommands = _require3.clientCommands;
-
-	var _require4 = __webpack_require__(114),
-	    setupEvents = _require4.setupEvents,
-	    clientEvents = _require4.clientEvents;
-
-	var debuggerClient = null;
-	var threadClient = null;
-	var tabTarget = null;
-
+	const { DebuggerClient, DebuggerTransport,
+	  TargetFactory, WebsocketTransport } = __webpack_require__(26);
+	const { getValue } = __webpack_require__(65);
+	const { setupCommands, clientCommands } = __webpack_require__(120);
+	const { setupEvents, clientEvents } = __webpack_require__(121);
+	
+	let debuggerClient = null;
+	let threadClient = null;
+	let tabTarget = null;
+	
 	function getThreadClient() {
 	  return threadClient;
 	}
-
+	
 	function setThreadClient(client) {
 	  threadClient = client;
 	}
-
+	
 	function getTabTarget() {
 	  return tabTarget;
 	}
-
+	
 	function setTabTarget(target) {
 	  tabTarget = target;
 	}
-
+	
 	function lookupTabTarget(tab) {
-	  var options = { client: debuggerClient, form: tab, chrome: false };
+	  const options = { client: debuggerClient, form: tab, chrome: false };
 	  return TargetFactory.forRemoteTab(options);
 	}
-
+	
 	function createTabs(tabs) {
 	  return tabs.map(tab => {
 	    return {
 	      title: tab.title,
 	      url: tab.url,
 	      id: tab.actor,
 	      tab,
 	      clientType: "firefox"
 	    };
 	  });
 	}
-
+	
 	function connectClient() {
-	  var useProxy = !getValue("firefox.webSocketConnection");
-	  var firefoxHost = getValue(useProxy ? "firefox.proxyHost" : "firefox.webSocketHost");
-
-	  var socket = new WebSocket(`ws://${ firefoxHost }`);
-	  var transport = useProxy ? new DebuggerTransport(socket) : new WebsocketTransport(socket);
-
+	  const useProxy = !getValue("firefox.webSocketConnection");
+	  const firefoxHost = getValue(useProxy ? "firefox.proxyHost" : "firefox.webSocketHost");
+	
+	  const socket = new WebSocket(`ws://${ firefoxHost }`);
+	  const transport = useProxy ? new DebuggerTransport(socket) : new WebsocketTransport(socket);
+	
 	  return new Promise((resolve, reject) => {
 	    debuggerClient = new DebuggerClient(transport);
 	    debuggerClient.connect().then(() => {
 	      if (debuggerClient !== null) {
 	        return debuggerClient.listTabs().then(response => {
 	          resolve(createTabs(response.tabs));
 	        });
 	      }
 	      return resolve([]);
 	    }).catch(err => {
 	      console.log(err);
 	      resolve([]);
 	    });
 	  });
 	}
-
+	
 	function connectTab(tab) {
 	  return new Promise((resolve, reject) => {
 	    window.addEventListener("beforeunload", () => {
-	      var tt = getTabTarget();
+	      const tt = getTabTarget();
 	      if (tt !== null) {
 	        tt.destroy();
 	      }
 	    });
-
+	
 	    lookupTabTarget(tab).then(target => {
 	      tabTarget = target;
 	      target.activeTab.attachThread({}, (res, _threadClient) => {
 	        threadClient = _threadClient;
 	        threadClient.resume();
 	        resolve();
 	      });
 	    });
 	  });
 	}
-
+	
 	function initPage(actions) {
 	  tabTarget = getTabTarget();
 	  threadClient = getThreadClient();
-
-	  if (!threadClient || !tabTarget || !actions) {
+	
+	  if (!threadClient || !tabTarget) {
 	    return;
 	  }
-
+	
 	  setupCommands({ threadClient, tabTarget, debuggerClient });
-
+	
 	  if (actions) {
 	    // Listen to all the requested events.
 	    setupEvents({ threadClient, actions });
 	    Object.keys(clientEvents).forEach(eventName => {
 	      if (threadClient) {
 	        threadClient.addListener(eventName, clientEvents[eventName]);
 	      }
 	    });
 	  }
 	}
-
+	
 	module.exports = {
 	  connectClient,
 	  connectTab,
 	  clientCommands,
 	  clientEvents,
 	  getThreadClient,
 	  setThreadClient,
 	  getTabTarget,
@@ -1468,17 +1446,17 @@ var Debugger =
 	const AppConstants = __webpack_require__(44);
 	const EventEmitter = __webpack_require__(34);
 	const WebsocketTransport = __webpack_require__(59);
 	const Menu = __webpack_require__(60);
 	const MenuItem = __webpack_require__(61);
 	const Tree = __webpack_require__(62);
 	const sourceUtils = __webpack_require__(63);
 	const frame = __webpack_require__(64);
-
+	
 	module.exports = {
 	  KeyShortcuts,
 	  PrefsHelper,
 	  DebuggerClient,
 	  DebuggerTransport,
 	  TargetFactory,
 	  DevToolsUtils,
 	  AppConstants,
@@ -1494,22 +1472,22 @@ var Debugger =
 
 /***/ },
 /* 27 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	const { Services: { appinfo }} = __webpack_require__(28);
 	const EventEmitter = __webpack_require__(34);
 	const isOSX = appinfo.OS === "Darwin";
 	"use strict";
-
+	
 	// List of electron keys mapped to DOM API (DOM_VK_*) key code
 	const ElectronKeysMapping = {
 	  "F1": "DOM_VK_F1",
 	  "F2": "DOM_VK_F2",
 	  "F3": "DOM_VK_F3",
 	  "F4": "DOM_VK_F4",
 	  "F5": "DOM_VK_F5",
 	  "F6": "DOM_VK_F6",
@@ -1548,17 +1526,17 @@ var Debugger =
 	  "Escape": "DOM_VK_ESCAPE",
 	  "Esc": "DOM_VK_ESCAPE",
 	  "Tab": "DOM_VK_TAB",
 	  "VolumeUp": "DOM_VK_VOLUME_UP",
 	  "VolumeDown": "DOM_VK_VOLUME_DOWN",
 	  "VolumeMute": "DOM_VK_VOLUME_MUTE",
 	  "PrintScreen": "DOM_VK_PRINTSCREEN",
 	};
-
+	
 	/**
 	 * Helper to listen for keyboard events decribed in .properties file.
 	 *
 	 * let shortcuts = new KeyShortcuts({
 	 *   window
 	 * });
 	 * shortcuts.on("Ctrl+F", event => {
 	 *   // `event` is the KeyboardEvent which relates to the key shortcuts
@@ -1572,32 +1550,32 @@ var Debugger =
 	 */
 	function KeyShortcuts({ window, target }) {
 	  this.window = window;
 	  this.target = target || window;
 	  this.keys = new Map();
 	  this.eventEmitter = new EventEmitter();
 	  this.target.addEventListener("keydown", this);
 	}
-
+	
 	/*
 	 * Parse an electron-like key string and return a normalized object which
 	 * allow efficient match on DOM key event. The normalized object matches DOM
 	 * API.
 	 *
 	 * @param DOMWindow window
 	 *        Any DOM Window object, just to fetch its `KeyboardEvent` object
 	 * @param String str
 	 *        The shortcut string to parse, following this document:
 	 *        https://github.com/electron/electron/blob/master/docs/api/accelerator.md
 	 */
 	KeyShortcuts.parseElectronKey = function(window, str) {
 	  let modifiers = str.split("+");
 	  let key = modifiers.pop();
-
+	
 	  let shortcut = {
 	    ctrl: false,
 	    meta: false,
 	    alt: false,
 	    shift: false,
 	    // Set for character keys
 	    key: undefined,
 	    // Set for non-character keys
@@ -1618,41 +1596,41 @@ var Debugger =
 	      shortcut.ctrl = true;
 	    } else if (mod === "Shift") {
 	      shortcut.shift = true;
 	    } else {
 	      console.error("Unsupported modifier:", mod, "from key:", str);
 	      return null;
 	    }
 	  }
-
+	
 	  // Plus is a special case. It's a character key and shouldn't be matched
 	  // against a keycode as it is only accessible via Shift/Capslock
 	  if (key === "Plus") {
 	    key = "+";
 	  }
-
+	
 	  if (typeof key === "string" && key.length === 1) {
 	    // Match any single character
 	    shortcut.key = key.toLowerCase();
 	  } else if (key in ElectronKeysMapping) {
 	    // Maps the others manually to DOM API DOM_VK_*
 	    key = ElectronKeysMapping[key];
 	    shortcut.keyCode = window.KeyboardEvent[key];
 	    // Used only to stringify the shortcut
 	    shortcut.keyCodeString = key;
 	    shortcut.key = key;
 	  } else {
 	    console.error("Unsupported key:", key);
 	    return null;
 	  }
-
+	
 	  return shortcut;
 	};
-
+	
 	KeyShortcuts.stringify = function(shortcut) {
 	  let list = [];
 	  if (shortcut.alt) {
 	    list.push("Alt");
 	  }
 	  if (shortcut.ctrl) {
 	    list.push("Ctrl");
 	  }
@@ -1666,23 +1644,23 @@ var Debugger =
 	  if (shortcut.key) {
 	    key = shortcut.key.toUpperCase();
 	  } else {
 	    key = shortcut.keyCodeString;
 	  }
 	  list.push(key);
 	  return list.join("+");
 	};
-
+	
 	KeyShortcuts.prototype = {
 	  destroy() {
 	    this.target.removeEventListener("keydown", this);
 	    this.keys.clear();
 	  },
-
+	
 	  doesEventMatchShortcut(event, shortcut) {
 	    if (shortcut.meta != event.metaKey) {
 	      return false;
 	    }
 	    if (shortcut.ctrl != event.ctrlKey) {
 	      return false;
 	    }
 	    if (shortcut.alt != event.altKey) {
@@ -1694,68 +1672,68 @@ var Debugger =
 	        event.key.match(/[a-zA-Z]/)) {
 	      return false;
 	    }
 	    if (shortcut.keyCode) {
 	      return event.keyCode == shortcut.keyCode;
 	    } else if (event.key in ElectronKeysMapping) {
 	      return ElectronKeysMapping[event.key] === shortcut.key;
 	    }
-
+	
 	    // get the key from the keyCode if key is not provided.
 	    let key = event.key || String.fromCharCode(event.keyCode);
-
+	
 	    // For character keys, we match if the final character is the expected one.
 	    // But for digits we also accept indirect match to please azerty keyboard,
 	    // which requires Shift to be pressed to get digits.
 	    return key.toLowerCase() == shortcut.key ||
 	      (shortcut.key.match(/^[0-9]$/) &&
 	       event.keyCode == shortcut.key.charCodeAt(0));
 	  },
-
+	
 	  handleEvent(event) {
 	    for (let [key, shortcut] of this.keys) {
 	      if (this.doesEventMatchShortcut(event, shortcut)) {
 	        this.eventEmitter.emit(key, event);
 	      }
 	    }
 	  },
-
+	
 	  on(key, listener) {
 	    if (typeof listener !== "function") {
 	      throw new Error("KeyShortcuts.on() expects a function as " +
 	                      "second argument");
 	    }
 	    if (!this.keys.has(key)) {
 	      let shortcut = KeyShortcuts.parseElectronKey(this.window, key);
 	      // The key string is wrong and we were unable to compute the key shortcut
 	      if (!shortcut) {
 	        return;
 	      }
 	      this.keys.set(key, shortcut);
 	    }
 	    this.eventEmitter.on(key, listener);
 	  },
-
+	
 	  off(key, listener) {
 	    this.eventEmitter.off(key, listener);
 	  },
 	};
 	exports.KeyShortcuts = KeyShortcuts;
 
 
 /***/ },
 /* 28 */
 /***/ function(module, exports, __webpack_require__) {
 
 	const Services = __webpack_require__(29);
 	const SplitBox = __webpack_require__(30);
 	// const SplitBoxCSS = require("./client/shared/components/splitter/SplitBox.css")
 	const sprintf = __webpack_require__(33).sprintf;
-
+	
 	module.exports = {
 	  Services,
 	  SplitBox,
 	  // SplitBoxCSS,
 	  sprintf
 	};
 
 
@@ -1768,23 +1746,23 @@ var Debugger =
 /***/ },
 /* 30 */
 /***/ function(module, exports, __webpack_require__) {
 
 	const React = __webpack_require__(2);
 	const ReactDOM = __webpack_require__(31);
 	const Draggable = React.createFactory(__webpack_require__(32));
 	const { DOM: dom, PropTypes } = React;
-
+	
 	/**
 	 * This component represents a Splitter. The splitter supports vertical
 	 * as well as horizontal mode.
 	 */
 	const SplitBox = React.createClass({
-
+	
 	  propTypes: {
 	    // Custom class name. You can use more names separated by a space.
 	    className: PropTypes.string,
 	    // Initial size of controlled panel.
 	    initialSize: PropTypes.any,
 	    // Optional initial width of controlled panel.
 	    initialWidth: PropTypes.number,
 	    // Optional initial height of controlled panel.
@@ -1805,197 +1783,197 @@ var Debugger =
 	    endPanelControl: PropTypes.bool,
 	    // Size of the splitter handle bar.
 	    splitterSize: PropTypes.number,
 	    // True if the splitter bar is vertical (default is vertical).
 	    vert: PropTypes.bool,
 	    // Optional style properties passed into the splitbox
 	    style: PropTypes.object
 	  },
-
+	
 	  displayName: "SplitBox",
-
+	
 	  getDefaultProps() {
 	    return {
 	      splitterSize: 5,
 	      vert: true,
 	      endPanelControl: false,
 	      endPanelCollapsed: false,
 	      startPanelCollapsed: false
 	    };
 	  },
-
+	
 	  /**
 	   * The state stores the current orientation (vertical or horizontal)
 	   * and the current size (width/height). All these values can change
 	   * during the component's life time.
 	   */
 	  getInitialState() {
 	    return {
 	      vert: this.props.vert,
 	      width: this.props.initialWidth || this.props.initialSize,
 	      height: this.props.initialHeight || this.props.initialSize
 	    };
 	  },
-
+	
 	  componentWillReceiveProps(nextProps) {
 	    if (this.props.vert !== nextProps.vert) {
 	      this.setState({ vert: nextProps.vert });
 	    }
 	  },
-
+	
 	  // Dragging Events
-
+	
 	  /**
 	   * Set 'resizing' cursor on entire document during splitter dragging.
 	   * This avoids cursor-flickering that happens when the mouse leaves
 	   * the splitter bar area (happens frequently).
 	   */
 	  onStartMove() {
 	    const splitBox = ReactDOM.findDOMNode(this);
 	    const doc = splitBox.ownerDocument;
 	    let defaultCursor = doc.documentElement.style.cursor;
 	    doc.documentElement.style.cursor =
 	      (this.state.vert ? "ew-resize" : "ns-resize");
-
+	
 	    splitBox.classList.add("dragging");
-
+	
 	    this.setState({
 	      defaultCursor: defaultCursor
 	    });
 	  },
-
+	
 	  onStopMove() {
 	    const splitBox = ReactDOM.findDOMNode(this);
 	    const doc = splitBox.ownerDocument;
 	    doc.documentElement.style.cursor = this.state.defaultCursor;
-
+	
 	    splitBox.classList.remove("dragging");
 	  },
-
+	
 	  screenX() {
 	    // NOTE: in practice the window might have a border which calls for comparing window.outerWidth and window.innerWidth
 	    return window.screenX;
 	  },
-
+	
 	  screenY() {
 	    // NOTE: in practice the window might have a border which calls for comparing window.outerHeight and window.innerHeight
 	    return window.screenY;
 	  },
-
+	
 	  /**
 	   * Adjust size of the controlled panel. Depending on the current
 	   * orientation we either remember the width or height of
 	   * the splitter box.
 	   */
 	  onMove(x, y) {
 	    const node = ReactDOM.findDOMNode(this);
 	    const doc = node.ownerDocument;
 	    const win = doc.defaultView;
-
+	
 	    let size;
 	    let { endPanelControl } = this.props;
-
+	
 	    if (this.state.vert) {
 	      // Switch the control flag in case of RTL. Note that RTL
 	      // has impact on vertical splitter only.
 	      let dir = win.getComputedStyle(doc.documentElement).direction;
 	      if (dir == "rtl") {
 	        endPanelControl = !endPanelControl;
 	      }
-
+	
 	      let innerOffset = x - this.screenX();
 	      size = endPanelControl ?
 	        (node.offsetLeft + node.offsetWidth) - innerOffset :
 	        innerOffset - node.offsetLeft;
-
+	
 	      this.setState({
 	        width: size
 	      });
 	    } else {
 	      let innerOffset = y - this.screenY();
 	      size = endPanelControl ?
 	        (node.offsetTop + node.offsetHeight) - innerOffset :
 	        innerOffset - node.offsetTop;
-
+	
 	      this.setState({
 	        height: size
 	      });
 	    }
 	  },
-
+	
 	  // Rendering
 	  preparePanelStyles() {
 	    const vert = this.state.vert;
 	    const {
 	      minSize, maxSize, startPanelCollapsed, endPanelControl,
 	      endPanelCollapsed } = this.props;
 	    let leftPanelStyle, rightPanelStyle;
-
+	
 	    // Set proper size for panels depending on the current state.
 	    if (vert) {
 	      let startWidth = endPanelControl ? null : this.state.width,
 	        endWidth = endPanelControl ? this.state.width : null;
-
+	
 	      leftPanelStyle = {
 	        maxWidth: endPanelControl ? null : maxSize,
 	        minWidth: endPanelControl ? null : minSize,
 	        width: startPanelCollapsed ? 0 : startWidth
 	      };
 	      rightPanelStyle = {
 	        maxWidth: endPanelControl ? maxSize : null,
 	        minWidth: endPanelControl ? minSize : null,
 	        width: endPanelCollapsed ? 0 : endWidth
 	      };
 	    } else {
 	      let startHeight = endPanelControl ? null : this.state.height,
 	        endHeight = endPanelControl ? this.state.height : null;
-
+	
 	      leftPanelStyle = {
 	        maxHeight: endPanelControl ? null : maxSize,
 	        minHeight: endPanelControl ? null : minSize,
 	        height: endPanelCollapsed ? maxSize : startHeight
 	      };
 	      rightPanelStyle = {
 	        maxHeight: endPanelControl ? maxSize : null,
 	        minHeight: endPanelControl ? minSize : null,
 	        height: startPanelCollapsed ? maxSize : endHeight
 	      };
 	    }
-
+	
 	    return { leftPanelStyle, rightPanelStyle };
 	  },
-
+	
 	  render() {
 	    const vert = this.state.vert;
 	    const {
 	      startPanelCollapsed,
 	      startPanel,
 	      endPanel,
 	      endPanelControl,
 	      splitterSize,
 	      endPanelCollapsed
 	    } = this.props;
-
+	
 	    let style = Object.assign({}, this.props.style);
-
+	
 	    // Calculate class names list.
 	    let classNames = ["split-box"];
 	    classNames.push(vert ? "vert" : "horz");
 	    if (this.props.className) {
 	      classNames = classNames.concat(this.props.className.split(" "));
 	    }
-
+	
 	    const { leftPanelStyle, rightPanelStyle } = this.preparePanelStyles();
-
+	
 	    // Calculate splitter size
 	    let splitterStyle = {
 	      flex: `0 0 ${splitterSize}px`
 	    };
-
+	
 	    return (
 	      dom.div({
 	        className: classNames.join(" "),
 	        style: style },
 	        !startPanelCollapsed ?
 	          dom.div({
 	            className: endPanelControl ? "uncontrolled" : "controlled",
 	            style: leftPanelStyle },
@@ -2013,17 +1991,17 @@ var Debugger =
 	            className: endPanelControl ? "controlled" : "uncontrolled",
 	            style: rightPanelStyle },
 	            endPanel
 	          ) : null
 	      )
 	    );
 	  }
 	});
-
+	
 	module.exports = SplitBox;
 
 
 /***/ },
 /* 31 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/**
@@ -2037,21 +2015,21 @@ var Debugger =
 	 * of patent rights can be found in the PATENTS file in the same directory.
 	 *
 	 */
 	// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
 	;(function(f) {
 	  // CommonJS
 	  if (true) {
 	    module.exports = f(__webpack_require__(2));
-
+	
 	  // RequireJS
 	  } else if (typeof define === "function" && define.amd) {
 	    define(['react'], f);
-
+	
 	  // <script>
 	  } else {
 	    var g;
 	    if (typeof window !== "undefined") {
 	      g = window;
 	    } else if (typeof global !== "undefined") {
 	      g = global;
 	    } else if (typeof self !== "undefined") {
@@ -2059,78 +2037,78 @@ var Debugger =
 	    } else {
 	      // works providing we're not in "use strict";
 	      // needed for Java 8 Nashorn
 	      // see https://github.com/facebook/react/issues/3037
 	      g = this;
 	    }
 	    g.ReactDOM = f(g.React);
 	  }
-
+	
 	})(function(React) {
 	  return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
 	});
 
 
 /***/ },
 /* 32 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
-	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
-	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-	const React = __webpack_require__(2);
-	const ReactDOM = __webpack_require__(31);
-	const { DOM: dom, PropTypes } = React;
-
-	const Draggable = React.createClass({
-	  displayName: "Draggable",
-
-	  propTypes: {
-	    onMove: PropTypes.func.isRequired,
-	    onStart: PropTypes.func,
-	    onStop: PropTypes.func,
-	    style: PropTypes.object,
-	    className: PropTypes.string
-	  },
-
-	  startDragging(ev) {
-	    ev.preventDefault();
-	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-	    doc.addEventListener("mousemove", this.onMove);
-	    doc.addEventListener("mouseup", this.onUp);
-	    this.props.onStart && this.props.onStart();
-	  },
-
-	  onMove(ev) {
-	    ev.preventDefault();
-	    // Use screen coordinates so, moving mouse over iframes
-	    // doesn't mangle (relative) coordinates.
-	    this.props.onMove(ev.screenX, ev.screenY);
-	  },
-
-	  onUp(ev) {
-	    ev.preventDefault();
-	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-	    doc.removeEventListener("mousemove", this.onMove);
-	    doc.removeEventListener("mouseup", this.onUp);
-	    this.props.onStop && this.props.onStop();
-	  },
-
-	  render() {
-	    return dom.div({
-	      style: this.props.style,
-	      className: this.props.className,
-	      onMouseDown: this.startDragging
-	    });
-	  }
-	});
-
-	module.exports = Draggable;
+	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
+	
+	const React = __webpack_require__(2);
+	const ReactDOM = __webpack_require__(31);
+	const { DOM: dom, PropTypes } = React;
+	
+	const Draggable = React.createClass({
+	  displayName: "Draggable",
+	
+	  propTypes: {
+	    onMove: PropTypes.func.isRequired,
+	    onStart: PropTypes.func,
+	    onStop: PropTypes.func,
+	    style: PropTypes.object,
+	    className: PropTypes.string
+	  },
+	
+	  startDragging(ev) {
+	    ev.preventDefault();
+	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+	    doc.addEventListener("mousemove", this.onMove);
+	    doc.addEventListener("mouseup", this.onUp);
+	    this.props.onStart && this.props.onStart();
+	  },
+	
+	  onMove(ev) {
+	    ev.preventDefault();
+	    // Use screen coordinates so, moving mouse over iframes
+	    // doesn't mangle (relative) coordinates.
+	    this.props.onMove(ev.screenX, ev.screenY);
+	  },
+	
+	  onUp(ev) {
+	    ev.preventDefault();
+	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+	    doc.removeEventListener("mousemove", this.onMove);
+	    doc.removeEventListener("mouseup", this.onUp);
+	    this.props.onStop && this.props.onStop();
+	  },
+	
+	  render() {
+	    return dom.div({
+	      style: this.props.style,
+	      className: this.props.className,
+	      onMouseDown: this.startDragging
+	    });
+	  }
+	});
+	
+	module.exports = Draggable;
 
 
 /***/ },
 /* 33 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/**
 	 * Copyright (c) 2007-2016, Alexandru Marasteanu <hello [at) alexei (dot] ro>
@@ -2154,22 +2132,22 @@ var Debugger =
 	 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 	 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 	 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 	 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 	 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 	 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	 *
 	 */
-
+	
 	/* globals window, exports, define */
-
+	
 	(function(window) {
 	    'use strict'
-
+	
 	    var re = {
 	        not_string: /[^s]/,
 	        not_bool: /[^t]/,
 	        not_type: /[^T]/,
 	        not_primitive: /[^v]/,
 	        number: /[diefg]/,
 	        numeric_arg: /bcdiefguxX/,
 	        json: /[j]/,
@@ -2177,25 +2155,25 @@ var Debugger =
 	        text: /^[^\x25]+/,
 	        modulo: /^\x25{2}/,
 	        placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosStTuvxX])/,
 	        key: /^([a-z_][a-z_\d]*)/i,
 	        key_access: /^\.([a-z_][a-z_\d]*)/i,
 	        index_access: /^\[(\d+)\]/,
 	        sign: /^[\+\-]/
 	    }
-
+	
 	    function sprintf() {
 	        var key = arguments[0], cache = sprintf.cache
 	        if (!(cache[key] && cache.hasOwnProperty(key))) {
 	            cache[key] = sprintf.parse(key)
 	        }
 	        return sprintf.format.call(null, cache[key], arguments)
 	    }
-
+	
 	    sprintf.format = function(parse_tree, argv) {
 	        var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = ''
 	        for (i = 0; i < tree_length; i++) {
 	            node_type = get_type(parse_tree[i])
 	            if (node_type === 'string') {
 	                output[output.length] = parse_tree[i]
 	            }
 	            else if (node_type === 'array') {
@@ -2210,29 +2188,29 @@ var Debugger =
 	                    }
 	                }
 	                else if (match[1]) { // positional argument (explicit)
 	                    arg = argv[match[1]]
 	                }
 	                else { // positional argument (implicit)
 	                    arg = argv[cursor++]
 	                }
-
+	
 	                if (re.not_type.test(match[8]) && re.not_primitive.test(match[8]) && get_type(arg) == 'function') {
 	                    arg = arg()
 	                }
-
+	
 	                if (re.numeric_arg.test(match[8]) && (get_type(arg) != 'number' && isNaN(arg))) {
 	                    throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg)))
 	                }
-
+	
 	                if (re.number.test(match[8])) {
 	                    is_positive = arg >= 0
 	                }
-
+	
 	                switch (match[8]) {
 	                    case 'b':
 	                        arg = parseInt(arg, 10).toString(2)
 	                    break
 	                    case 'c':
 	                        arg = String.fromCharCode(parseInt(arg, 10))
 	                    break
 	                    case 'd':
@@ -2296,19 +2274,19 @@ var Debugger =
 	                    pad_length = match[6] - (sign + arg).length
 	                    pad = match[6] ? (pad_length > 0 ? str_repeat(pad_character, pad_length) : '') : ''
 	                    output[output.length] = match[5] ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
 	                }
 	            }
 	        }
 	        return output.join('')
 	    }
-
+	
 	    sprintf.cache = {}
-
+	
 	    sprintf.parse = function(fmt) {
 	        var _fmt = fmt, match = [], parse_tree = [], arg_names = 0
 	        while (_fmt) {
 	            if ((match = re.text.exec(_fmt)) !== null) {
 	                parse_tree[parse_tree.length] = match[0]
 	            }
 	            else if ((match = re.modulo.exec(_fmt)) !== null) {
 	                parse_tree[parse_tree.length] = '%'
@@ -2346,61 +2324,61 @@ var Debugger =
 	            }
 	            else {
 	                throw new SyntaxError("[sprintf] unexpected placeholder")
 	            }
 	            _fmt = _fmt.substring(match[0].length)
 	        }
 	        return parse_tree
 	    }
-
+	
 	    var vsprintf = function(fmt, argv, _argv) {
 	        _argv = (argv || []).slice(0)
 	        _argv.splice(0, 0, fmt)
 	        return sprintf.apply(null, _argv)
 	    }
-
+	
 	    /**
 	     * helpers
 	     */
 	    function get_type(variable) {
 	        if (typeof variable === 'number') {
 	            return 'number'
 	        }
 	        else if (typeof variable === 'string') {
 	            return 'string'
 	        }
 	        else {
 	            return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase()
 	        }
 	    }
-
+	
 	    var preformattedPadding = {
 	        '0': ['', '0', '00', '000', '0000', '00000', '000000', '0000000'],
 	        ' ': ['', ' ', '  ', '   ', '    ', '     ', '      ', '       '],
 	        '_': ['', '_', '__', '___', '____', '_____', '______', '_______'],
 	    }
 	    function str_repeat(input, multiplier) {
 	        if (multiplier >= 0 && multiplier <= 7 && preformattedPadding[input]) {
 	            return preformattedPadding[input][multiplier]
 	        }
 	        return Array(multiplier + 1).join(input)
 	    }
-
+	
 	    /**
 	     * export to either browser or node.js
 	     */
 	    if (true) {
 	        exports.sprintf = sprintf
 	        exports.vsprintf = vsprintf
 	    }
 	    else {
 	        window.sprintf = sprintf
 	        window.vsprintf = vsprintf
-
+	
 	        if (typeof define === 'function' && define.amd) {
 	            define(function() {
 	                return {
 	                    sprintf: sprintf,
 	                    vsprintf: vsprintf
 	                }
 	            })
 	        }
@@ -2410,42 +2388,42 @@ var Debugger =
 
 /***/ },
 /* 34 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	/**
 	 * EventEmitter.
 	 */
-
+	
 	var EventEmitter = function EventEmitter() {};
 	module.exports = EventEmitter;
-
+	
 	const { Cu } = __webpack_require__(35);
 	const promise = __webpack_require__(40);
-
+	
 	/**
 	 * Decorate an object with event emitter functionality.
 	 *
 	 * @param Object aObjectToDecorate
 	 *        Bind all public methods of EventEmitter to
 	 *        the aObjectToDecorate object.
 	 */
 	EventEmitter.decorate = function EventEmitter_decorate (aObjectToDecorate) {
 	  let emitter = new EventEmitter();
 	  aObjectToDecorate.on = emitter.on.bind(emitter);
 	  aObjectToDecorate.off = emitter.off.bind(emitter);
 	  aObjectToDecorate.once = emitter.once.bind(emitter);
 	  aObjectToDecorate.emit = emitter.emit.bind(emitter);
 	};
-
+	
 	EventEmitter.prototype = {
 	  /**
 	   * Connect a listener.
 	   *
 	   * @param string aEvent
 	   *        The event name to which we're connecting.
 	   * @param function aListener
 	   *        Called when the event is fired.
@@ -2453,48 +2431,48 @@ var Debugger =
 	  on: function EventEmitter_on(aEvent, aListener) {
 	    if (!this._eventEmitterListeners)
 	      this._eventEmitterListeners = new Map();
 	    if (!this._eventEmitterListeners.has(aEvent)) {
 	      this._eventEmitterListeners.set(aEvent, []);
 	    }
 	    this._eventEmitterListeners.get(aEvent).push(aListener);
 	  },
-
+	
 	  /**
 	   * Listen for the next time an event is fired.
 	   *
 	   * @param string aEvent
 	   *        The event name to which we're connecting.
 	   * @param function aListener
 	   *        (Optional) Called when the event is fired. Will be called at most
 	   *        one time.
 	   * @return promise
 	   *        A promise which is resolved when the event next happens. The
 	   *        resolution value of the promise is the first event argument. If
 	   *        you need access to second or subsequent event arguments (it's rare
 	   *        that this is needed) then use aListener
 	   */
 	  once: function EventEmitter_once(aEvent, aListener) {
 	    let deferred = promise.defer();
-
+	
 	    let handler = (aEvent, aFirstArg, ...aRest) => {
 	      this.off(aEvent, handler);
 	      if (aListener) {
 	        aListener.apply(null, [aEvent, aFirstArg, ...aRest]);
 	      }
 	      deferred.resolve(aFirstArg);
 	    };
-
+	
 	    handler._originalListener = aListener;
 	    this.on(aEvent, handler);
-
+	
 	    return deferred.promise;
 	  },
-
+	
 	  /**
 	   * Remove a previously-registered event listener.  Works for events
 	   * registered with either on or once.
 	   *
 	   * @param string aEvent
 	   *        The event name whose listener we're disconnecting.
 	   * @param function aListener
 	   *        The listener to remove.
@@ -2504,34 +2482,34 @@ var Debugger =
 	      return;
 	    let listeners = this._eventEmitterListeners.get(aEvent);
 	    if (listeners) {
 	      this._eventEmitterListeners.set(aEvent, listeners.filter(l => {
 	        return l !== aListener && l._originalListener !== aListener;
 	      }));
 	    }
 	  },
-
+	
 	  /**
 	   * Emit an event.  All arguments to this method will
 	   * be sent to listener functions.
 	   */
 	  emit: function EventEmitter_emit(aEvent) {
 	    if (!this._eventEmitterListeners || !this._eventEmitterListeners.has(aEvent)) {
 	      return;
 	    }
-
+	
 	    let originalListeners = this._eventEmitterListeners.get(aEvent);
 	    for (let listener of this._eventEmitterListeners.get(aEvent)) {
 	      // If the object was destroyed during event emission, stop
 	      // emitting.
 	      if (!this._eventEmitterListeners) {
 	        break;
 	      }
-
+	
 	      // If listeners were removed during emission, make sure the
 	      // event handler we're going to fire wasn't removed.
 	      if (originalListeners === this._eventEmitterListeners.get(aEvent) ||
 	          this._eventEmitterListeners.get(aEvent).some(l => l === listener)) {
 	        try {
 	          listener.apply(null, arguments);
 	        }
 	        catch (ex) {
@@ -2548,32 +2526,32 @@ var Debugger =
 
 /***/ },
 /* 35 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/*
 	 * A sham for https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/chrome
 	 */
-
+	
 	var { inDOMUtils } = __webpack_require__(36);
-
+	
 	var ourServices = {
 	  inIDOMUtils: inDOMUtils,
 	  nsIClipboardHelper: {
 	    copyString: () => {}
 	  },
 	  nsIXULChromeRegistry: {
 	    isLocaleRTL: () => {return false;}
 	  },
 	  nsIDOMParser: {
-
-	  },
-	};
-
+	
+	  },
+	};
+	
 	module.exports = {
 	  Cc: name => {
 	    if(typeof console !== "undefined") {
 	      console.log('Cc sham for', name);
 	    }
 	    return {
 	      getService: (name) => ourServices[name],
 	      createInstance: (iface) => ourServices[iface],
@@ -2592,17 +2570,17 @@ var Debugger =
 	      "DISPATCH_SYNC":1
 	    },
 	    nsIDOMNode: typeof HTMLElement !== "undefined" ? HTMLElement : null,
 	    nsIFocusManager: {
 	      MOVEFOCUS_BACKWARD: 2,
 	      MOVEFOCUS_FORWARD: 1,
 	    },
 	    nsIDOMKeyEvent: {
-
+	
 	    },
 	    nsIDOMCSSRule: {"UNKNOWN_RULE":0,"STYLE_RULE":1,"CHARSET_RULE":2,"IMPORT_RULE":3,"MEDIA_RULE":4,"FONT_FACE_RULE":5,"PAGE_RULE":6,"KEYFRAMES_RULE":7,"KEYFRAME_RULE":8,"MOZ_KEYFRAMES_RULE":7,"MOZ_KEYFRAME_RULE":8,"NAMESPACE_RULE":10,"COUNTER_STYLE_RULE":11,"SUPPORTS_RULE":12,"FONT_FEATURE_VALUES_RULE":14},
 	    inIDOMUtils: "inIDOMUtils",
 	    nsIClipboardHelper: "nsIClipboardHelper",
 	    nsIXULChromeRegistry: "nsIXULChromeRegistry",
 	  },
 	  Cu: {
 	    reportError: msg => { (typeof console !== "undefined") ? console.error(msg) : dump(msg) },
@@ -2615,58 +2593,58 @@ var Debugger =
 	};
 
 
 /***/ },
 /* 36 */
 /***/ function(module, exports, __webpack_require__) {
 
 	// A sham for inDOMUtils.
-
+	
 	"use strict";
-
+	
 	var { CSSLexer } = __webpack_require__(37);
 	var { cssColors } = __webpack_require__(38);
 	var { cssProperties } = __webpack_require__(39);
-
+	
 	var cssRGBMap;
-
+	
 	// From inIDOMUtils.idl.
 	var EXCLUDE_SHORTHANDS = (1 << 0);
 	var INCLUDE_ALIASES = (1 << 1);
 	var TYPE_LENGTH = 0;
 	var TYPE_PERCENTAGE = 1;
 	var TYPE_COLOR = 2;
 	var TYPE_URL = 3;
 	var TYPE_ANGLE = 4;
 	var TYPE_FREQUENCY = 5;
 	var TYPE_TIME = 6;
 	var TYPE_GRADIENT = 7;
 	var TYPE_TIMING_FUNCTION = 8;
 	var TYPE_IMAGE_RECT = 9;
 	var TYPE_NUMBER = 10;
-
+	
 	function getCSSLexer(text) {
 	  return new CSSLexer(text);
 	}
-
+	
 	function rgbToColorName(r, g, b) {
 	  if (!cssRGBMap) {
 	    cssRGBMap = new Map();
 	    for (let name in cssColors) {
 	      cssRGBMap.set(JSON.stringify(cssColors[name]), name);
 	    }
 	  }
 	  let value = cssRGBMap.get(JSON.stringify([r, g, b]));
 	  if (!value) {
 	    throw new Error("no such color");
 	  }
 	  return value;
 	}
-
+	
 	// Taken from dom/tests/mochitest/ajax/mochikit/MochiKit/Color.js
 	function _hslValue(n1, n2, hue) {
 	  if (hue > 6.0) {
 	    hue -= 6.0;
 	  } else if (hue < 0.0) {
 	    hue += 6.0;
 	  }
 	  var val;
@@ -2676,17 +2654,17 @@ var Debugger =
 	    val = n2;
 	  } else if (hue < 4.0) {
 	    val = n1 + (n2 - n1) * (4.0 - hue);
 	  } else {
 	    val = n1;
 	  }
 	  return val;
 	}
-
+	
 	// Taken from dom/tests/mochitest/ajax/mochikit/MochiKit/Color.js
 	// and then modified.
 	function hslToRGB([hue, saturation, lightness]) {
 	  var red;
 	  var green;
 	  var blue;
 	  if (saturation === 0) {
 	    red = lightness;
@@ -2703,59 +2681,59 @@ var Debugger =
 	    var f = _hslValue;
 	    var h6 = hue * 6.0;
 	    red = f(m1, m2, h6 + 2);
 	    green = f(m1, m2, h6);
 	    blue = f(m1, m2, h6 - 2);
 	  }
 	  return [red, green, blue];
 	}
-
+	
 	function colorToRGBA(name) {
 	  name = name.trim().toLowerCase();
 	  if (name in cssColors) {
 	    return cssColors[name];
 	  }
-
+	
 	  if (name === "transparent") {
 	    return [0, 0, 0, 0];
 	  }
-
+	
 	  let lexer = getCSSLexer(name);
-
+	
 	  let getToken = function() {
 	    while (true) {
 	      let token = lexer.nextToken();
 	      if (!token || token.tokenType !== "comment" ||
 	          token.tokenType !== "whitespace") {
 	        return token;
 	      }
 	    }
 	  };
-
+	
 	  let requireComma = function(token) {
 	    if (token.tokenType !== "symbol" || token.text !== ",") {
 	      return null;
 	    }
 	    return getToken();
 	  };
-
+	
 	  let func = getToken();
 	  if (!func || func.tokenType !== "function") {
 	    return null;
 	  }
 	  let alpha = false;
 	  if (func.text === "rgb" || func.text === "hsl") {
 	    // Nothing.
 	  } else if (func.text === "rgba" || func.text === "hsla") {
 	    alpha = true;
 	  } else {
 	    return null;
 	  }
-
+	
 	  let vals = [];
 	  for (let i = 0; i < 3; ++i) {
 	    let token = getToken();
 	    if (i > 0) {
 	      token = requireComma(token);
 	    }
 	    if (token.tokenType !== "number" || !token.isInteger) {
 	      return null;
@@ -2763,146 +2741,146 @@ var Debugger =
 	    let num = token.number;
 	    if (num < 0) {
 	      num = 0;
 	    } else if (num > 255) {
 	      num = 255;
 	    }
 	    vals.push(num);
 	  }
-
+	
 	  if (func.text === "hsl" || func.text === "hsla") {
 	    vals = hslToRGB(vals);
 	  }
-
+	
 	  if (alpha) {
 	    let token = requireComma(getToken());
 	    if (token.tokenType !== "number") {
 	      return null;
 	    }
 	    let num = token.number;
 	    if (num < 0) {
 	      num = 0;
 	    } else if (num > 1) {
 	      num = 1;
 	    }
 	    vals.push(num);
 	  } else {
 	    vals.push(1);
 	  }
-
+	
 	  let parenToken = getToken();
 	  if (!parenToken || parenToken.tokenType !== "symbol" ||
 	      parenToken.text !== ")") {
 	    return null;
 	  }
 	  if (getToken() !== null) {
 	    return null;
 	  }
-
+	
 	  return vals;
 	}
-
+	
 	function isValidCSSColor(name) {
 	  return colorToRGBA(name) !== null;
 	}
-
+	
 	function isVariable(name) {
 	  return name.startsWith("--");
 	}
-
+	
 	function cssPropertyIsShorthand(name) {
 	  if (isVariable(name)) {
 	    return false;
 	  }
 	  if (!(name in cssProperties)) {
 	    throw Error("unknown property " + name);
 	  }
 	  return !!cssProperties[name].subproperties;
 	}
-
+	
 	function getSubpropertiesForCSSProperty(name) {
 	  if (isVariable(name)) {
 	    return [name];
 	  }
 	  if (!(name in cssProperties)) {
 	    throw Error("unknown property " + name);
 	  }
 	  if ("subproperties" in cssProperties[name]) {
 	    return cssProperties[name].subproperties.slice();
 	  }
 	  return [name];
 	}
-
+	
 	function getCSSValuesForProperty(name) {
 	  if (isVariable(name)) {
 	    return ["initial", "inherit", "unset"];
 	  }
 	  if (!(name in cssProperties)) {
 	    throw Error("unknown property " + name);
 	  }
 	  return cssProperties[name].values.slice();
 	}
-
+	
 	function getCSSPropertyNames(flags) {
 	  let names = Object.keys(cssProperties);
 	  if ((flags & EXCLUDE_SHORTHANDS) !== 0) {
 	    names = names.filter((name) => cssProperties[name].subproperties);
 	  }
 	  if ((flags & INCLUDE_ALIASES) === 0) {
 	    names = names.filter((name) => !cssProperties[name].alias);
 	  }
 	  return names;
 	}
-
+	
 	function cssPropertySupportsType(name, type) {
 	  if (isVariable(name)) {
 	    return false;
 	  }
 	  if (!(name in cssProperties)) {
 	    throw Error("unknown property " + name);
 	  }
 	  return (cssProperties[name].supports & (1 << type)) !== 0;
 	}
-
+	
 	function isInheritedProperty(name) {
 	  if (isVariable(name)) {
 	    return true;
 	  }
 	  if (!(name in cssProperties)) {
 	    return false;
 	  }
 	  return cssProperties[name].inherited;
 	}
-
+	
 	function cssPropertyIsValid(name, value) {
 	  if (isVariable(name)) {
 	    return true;
 	  }
 	  if (!(name in cssProperties)) {
 	    return false;
 	  }
 	  let elt = document.createElement("div");
 	  elt.style = name + ":" + value;
 	  return elt.style.length > 0;
 	}
-
+	
 	exports.inDOMUtils = {
 	  getCSSLexer,
 	  rgbToColorName,
 	  colorToRGBA,
 	  isValidCSSColor,
 	  cssPropertyIsShorthand,
 	  getSubpropertiesForCSSProperty,
 	  getCSSValuesForProperty,
 	  getCSSPropertyNames,
 	  cssPropertySupportsType,
 	  isInheritedProperty,
 	  cssPropertyIsValid,
-
+	
 	  // Constants.
 	  EXCLUDE_SHORTHANDS,
 	  INCLUDE_ALIASES,
 	  TYPE_LENGTH,
 	  TYPE_PERCENTAGE,
 	  TYPE_COLOR,
 	  TYPE_URL,
 	  TYPE_ANGLE,
@@ -2915,117 +2893,117 @@ var Debugger =
 	};
 
 
 /***/ },
 /* 37 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;"use strict";
-
+	
 	(function (root, factory) {
 	    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
 	    // Rhino, and plain browser loading.
 	    if (true) {
 	        !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
 	    } else if (typeof exports !== 'undefined') {
 	        factory(exports);
 	    } else {
 	        factory(root);
 	    }
 	}(this, function (exports) {
-
+	
 	function between(num, first, last) { return num >= first && num <= last; }
 	function digit(code) { return between(code, 0x30,0x39); }
 	function hexdigit(code) { return digit(code) || between(code, 0x41,0x46) || between(code, 0x61,0x66); }
 	function uppercaseletter(code) { return between(code, 0x41,0x5a); }
 	function lowercaseletter(code) { return between(code, 0x61,0x7a); }
 	function letter(code) { return uppercaseletter(code) || lowercaseletter(code); }
 	function nonascii(code) { return code >= 0x80; }
 	function namestartchar(code) { return letter(code) || nonascii(code) || code == 0x5f; }
 	function namechar(code) { return namestartchar(code) || digit(code) || code == 0x2d; }
 	function nonprintable(code) { return between(code, 0,8) || code == 0xb || between(code, 0xe,0x1f) || code == 0x7f; }
 	function newline(code) { return code == 0xa; }
 	function whitespace(code) { return newline(code) || code == 9 || code == 0x20; }
-
+	
 	var maximumallowedcodepoint = 0x10ffff;
-
+	
 	var InvalidCharacterError = function(message) {
 		this.message = message;
 	};
 	InvalidCharacterError.prototype = new Error;
 	InvalidCharacterError.prototype.name = 'InvalidCharacterError';
-
+	
 	function stringFromCode(code) {
 		if(code <= 0xffff) return String.fromCharCode(code);
 		// Otherwise, encode astral char as surrogate pair.
 		code -= Math.pow(2, 20);
 		var lead = Math.floor(code/Math.pow(2, 10)) + 0xd800;
 		var trail = code % Math.pow(2, 10) + 0xdc00;
 		return String.fromCharCode(lead) + String.fromCharCode(trail);
 	}
-
+	
 	function* tokenize(str, options) {
 		if (options === undefined) {
 			options = {};
 		}
 		if (options.loc === undefined) {
 			options.loc = false;
 		}
 		if (options.offsets === undefined) {
 			options.offsets = false;
 		}
 		if (options.keepComments === undefined) {
 			options.keepComments = false;
 		}
 		if (options.startOffset === undefined) {
 			options.startOffset = 0;
 		}
-
+	
 		var i = options.startOffset - 1;
 		var code;
-
+	
 		// Line number information.
 		var line = 0;
 		var column = 0;
 		// The only use of lastLineLength is in reconsume().
 		var lastLineLength = 0;
 		var incrLineno = function() {
 			line += 1;
 			lastLineLength = column;
 			column = 0;
 		};
 		var locStart = {line:line, column:column};
 		var offsetStart = i;
-
+	
 		var codepoint = function(i) {
 			if(i >= str.length) {
 				return -1;
 			}
 			return str.charCodeAt(i);
 		};
 		var next = function(num) {
 			if(num === undefined)
 				num = 1;
 			if(num > 3)
 				throw "Spec Error: no more than three codepoints of lookahead.";
-
+	
 			var rcode;
 			for (var offset = i + 1; num-- > 0; ++offset) {
 				rcode = codepoint(offset);
 				if (rcode === 0xd && codepoint(offset+1) === 0xa) {
 					++offset;
 					rcode = 0xa;
 				} else if (rcode === 0xd || rcode === 0xc) {
 					rcode = 0xa;
 				} else if (rcode === 0x0) {
 					rcode = 0xfffd;
 				}
 			}
-
+	
 			return rcode;
 		};
 		var consume = function(num) {
 			if(num === undefined)
 				num = 1;
 			while(num-- > 0) {
 				++i;
 				code = codepoint(i);
@@ -3053,17 +3031,17 @@ var Debugger =
 			return true;
 		};
 		var eof = function(codepoint) {
 			if(codepoint === undefined) codepoint = code;
 			return codepoint == -1;
 		};
 		var donothing = function() {};
 		var parseerror = function() { console.log("Parse error at index " + i + ", processing codepoint 0x" + code.toString(16) + ".");return true; };
-
+	
 		var consumeAToken = function() {
 			consume();
 			if (!options.keepComments) {
 				while(code == 0x2f && next() == 0x2a) {
 					consumeAComment();
 					consume();
 				}
 			}
@@ -3203,33 +3181,33 @@ var Debugger =
 			}
 			else if(namestartchar(code)) {
 				reconsume();
 				return consumeAnIdentlikeToken();
 			}
 			else if(eof()) return new EOFToken();
 			else return new DelimToken(code);
 		};
-
+	
 		var consumeAComment = function() {
 			consume();
 			var comment = "";
 			while(true) {
 				consume();
 				if(code == 0x2a && next() == 0x2f) {
 					consume();
 					break;
 				} else if(eof()) {
 					break;
 				}
 				comment += stringFromCode(code);
 			}
 			return new CommentToken(comment);
 		};
-
+	
 		var consumeANumericToken = function() {
 			var num = consumeANumber();
 			var token;
 			if(wouldStartAnIdentifier(next(1), next(2), next(3))) {
 				token = new DimensionToken();
 				token.value = num.value;
 				token.repr = num.repr;
 				token.type = num.type;
@@ -3246,17 +3224,17 @@ var Debugger =
 				token.repr = num.repr;
 				token.type = num.type;
 			}
 			token.number = token.value;
 			token.isInteger = token.type === "integer";
 			// FIXME hasSign
 			return token;
 		};
-
+	
 		var consumeAnIdentlikeToken = function() {
 			var str = consumeAName();
 			if(str.toLowerCase() == "url" && next() == 0x28) {
 				consume();
 				while(whitespace(next(1)) && whitespace(next(2)))
 					consume();
 				if((next() == 0x22 || next() == 0x27) ||
 				   (whitespace(next()) && (next(2) == 0x22 || next(2) == 0x27))) {
@@ -3274,17 +3252,17 @@ var Debugger =
 				}
 			} else if(next() == 0x28) {
 				consume();
 				return new FunctionToken(str);
 			} else {
 				return new IdentToken(str);
 			}
 		};
-
+	
 		var consumeAStringToken = function(endingCodePoint) {
 			if(endingCodePoint === undefined) endingCodePoint = code;
 			var string = "";
 			while(consume()) {
 				if(code == endingCodePoint || eof()) {
 					return new StringToken(string);
 				} else if(newline(code)) {
 					reconsume();
@@ -3297,17 +3275,17 @@ var Debugger =
 					} else {
 						string += stringFromCode(consumeEscape());
 					}
 				} else {
 					string += stringFromCode(code);
 				}
 			}
 		};
-
+	
 		var consumeAURLToken = function() {
 			var token = new URLToken("");
 			while(whitespace(next())) consume();
 			if(eof(next())) return token;
 			while(consume()) {
 				if(code == 0x29 || eof()) {
 					break;
 				} else if(whitespace(code)) {
@@ -3334,17 +3312,17 @@ var Debugger =
 					}
 				} else {
 					token.value += stringFromCode(code);
 				}
 			}
 			token.text = token.value;
 			return token;
 		};
-
+	
 		var consumeEscape = function() {
 			// Assume the the current character is the \
 			// and the next code point is not a newline.
 			consume();
 			if(hexdigit(code)) {
 				// Consume 1-6 hex digits
 				var digits = [code];
 				for(var total = 0; total < 5; total++) {
@@ -3360,41 +3338,41 @@ var Debugger =
 				if( value > maximumallowedcodepoint ) value = 0xfffd;
 				return value;
 			} else if(eof()) {
 				return 0xfffd;
 			} else {
 				return code;
 			}
 		};
-
+	
 		var areAValidEscape = function(c1, c2) {
 			if(c1 != 0x5c) return false;
 			if(newline(c2)) return false;
 			return true;
 		};
 		var startsWithAValidEscape = function() {
 			return areAValidEscape(code, next());
 		};
-
+	
 		var wouldStartAnIdentifier = function(c1, c2, c3) {
 			if(c1 == 0x2d) {
 				return namestartchar(c2) || c2 == 0x2d || areAValidEscape(c2, c3);
 			} else if(namestartchar(c1)) {
 				return true;
 			} else if(c1 == 0x5c) {
 				return areAValidEscape(c1, c2);
 			} else {
 				return false;
 			}
 		};
 		var startsWithAnIdentifier = function() {
 			return wouldStartAnIdentifier(code, next(1), next(2));
 		};
-
+	
 		var wouldStartANumber = function(c1, c2, c3) {
 			if(c1 == 0x2b || c1 == 0x2d) {
 				if(digit(c2)) return true;
 				if(c2 == 0x2e && digit(c3)) return true;
 				return false;
 			} else if(c1 == 0x2e) {
 				if(digit(c2)) return true;
 				return false;
@@ -3402,31 +3380,31 @@ var Debugger =
 				return true;
 			} else {
 				return false;
 			}
 		};
 		var startsWithANumber = function() {
 			return wouldStartANumber(code, next(1), next(2));
 		};
-
+	
 		var consumeAName = function() {
 			var result = "";
 			while(consume()) {
 				if(namechar(code)) {
 					result += stringFromCode(code);
 				} else if(startsWithAValidEscape()) {
 					result += stringFromCode(consumeEscape());
 				} else {
 					reconsume();
 					return result;
 				}
 			}
 		};
-
+	
 		var consumeANumber = function() {
 			var repr = [];
 			var type = "integer";
 			if(next() == 0x2b || next() == 0x2d) {
 				consume();
 				repr += stringFromCode(code);
 			}
 			while(digit(next())) {
@@ -3466,37 +3444,37 @@ var Debugger =
 				while(digit(next())) {
 					consume();
 					repr += stringFromCode(code);
 				}
 			}
 			var value = convertAStringToANumber(repr);
 			return {type:type, value:value, repr:repr};
 		};
-
+	
 		var convertAStringToANumber = function(string) {
 			// CSS's number rules are identical to JS, afaik.
 			return +string;
 		};
-
+	
 		var consumeTheRemnantsOfABadURL = function() {
 			while(consume()) {
 				if(code == 0x2d || eof()) {
 					return;
 				} else if(startsWithAValidEscape()) {
 					consumeEscape();
 					donothing();
 				} else {
 					donothing();
 				}
 			}
 		};
-
-
-
+	
+	
+	
 		var iterationCount = 0;
 		while(!eof(next())) {
 			var token = consumeAToken();
 			if (options.loc) {
 				token.loc = {};
 				token.loc.start = {line:locStart.line, column:locStart.column};
 				token.loc.end = {line:line, column:column};
 			}
@@ -3504,128 +3482,128 @@ var Debugger =
 				token.startOffset = offsetStart;
 				token.endOffset = i + 1;
 			}
 			yield token;
 			iterationCount++;
 			if(iterationCount > str.length*2) return "I'm infinite-looping!";
 		}
 	}
-
+	
 	function CSSParserToken() { throw "Abstract Base Class"; }
 	CSSParserToken.prototype.toJSON = function() {
 		return {token: this.tokenType};
 	};
 	CSSParserToken.prototype.toString = function() { return this.tokenType; };
 	CSSParserToken.prototype.toSource = function() { return ''+this; };
-
+	
 	function BadStringToken(text) {
 		this.text = text;
 		return this;
 	}
 	BadStringToken.prototype = Object.create(CSSParserToken.prototype);
 	BadStringToken.prototype.tokenType = "bad_string";
-
+	
 	function BadURLToken() { return this; }
 	BadURLToken.prototype = Object.create(CSSParserToken.prototype);
 	BadURLToken.prototype.tokenType = "bad_url";
-
+	
 	function WhitespaceToken() { return this; }
 	WhitespaceToken.prototype = Object.create(CSSParserToken.prototype);
 	WhitespaceToken.prototype.tokenType = "whitespace";
 	WhitespaceToken.prototype.toString = function() { return "WS"; };
 	WhitespaceToken.prototype.toSource = function() { return " "; };
-
+	
 	function CDOToken() { return this; }
 	CDOToken.prototype = Object.create(CSSParserToken.prototype);
 	CDOToken.prototype.tokenType = "htmlcomment";
 	CDOToken.prototype.toSource = function() { return "<!--"; };
-
+	
 	function CDCToken() { return this; }
 	CDCToken.prototype = Object.create(CSSParserToken.prototype);
 	CDCToken.prototype.tokenType = "htmlcomment";
 	CDCToken.prototype.toSource = function() { return "-->"; };
-
+	
 	function ColonToken() { return this; }
 	ColonToken.prototype = Object.create(CSSParserToken.prototype);
 	ColonToken.prototype.tokenType = "symbol";
 	ColonToken.prototype.text = ":";
-
+	
 	function SemicolonToken() { return this; }
 	SemicolonToken.prototype = Object.create(CSSParserToken.prototype);
 	SemicolonToken.prototype.tokenType = "symbol";
 	SemicolonToken.prototype.text = ";";
-
+	
 	function CommaToken() { return this; }
 	CommaToken.prototype = Object.create(CSSParserToken.prototype);
 	CommaToken.prototype.tokenType = "symbol";
 	CommaToken.prototype.text = ",";
-
+	
 	function GroupingToken() { throw "Abstract Base Class"; }
 	GroupingToken.prototype = Object.create(CSSParserToken.prototype);
-
+	
 	function OpenCurlyToken() { this.value = "{"; this.mirror = "}"; return this; }
 	OpenCurlyToken.prototype = Object.create(GroupingToken.prototype);
 	OpenCurlyToken.prototype.tokenType = "symbol";
 	OpenCurlyToken.prototype.text = "{";
-
+	
 	function CloseCurlyToken() { this.value = "}"; this.mirror = "{"; return this; }
 	CloseCurlyToken.prototype = Object.create(GroupingToken.prototype);
 	CloseCurlyToken.prototype.tokenType = "symbol";
 	CloseCurlyToken.prototype.text = "}";
-
+	
 	function OpenSquareToken() { this.value = "["; this.mirror = "]"; return this; }
 	OpenSquareToken.prototype = Object.create(GroupingToken.prototype);
 	OpenSquareToken.prototype.tokenType = "symbol";
 	OpenSquareToken.prototype.text = "[";
-
+	
 	function CloseSquareToken() { this.value = "]"; this.mirror = "["; return this; }
 	CloseSquareToken.prototype = Object.create(GroupingToken.prototype);
 	CloseSquareToken.prototype.tokenType = "symbol";
 	CloseSquareToken.prototype.text = "]";
-
+	
 	function OpenParenToken() { this.value = "("; this.mirror = ")"; return this; }
 	OpenParenToken.prototype = Object.create(GroupingToken.prototype);
 	OpenParenToken.prototype.tokenType = "symbol";
 	OpenParenToken.prototype.text = "(";
-
+	
 	function CloseParenToken() { this.value = ")"; this.mirror = "("; return this; }
 	CloseParenToken.prototype = Object.create(GroupingToken.prototype);
 	CloseParenToken.prototype.tokenType = "symbol";
 	CloseParenToken.prototype.text = ")";
-
+	
 	function IncludeMatchToken() { return this; }
 	IncludeMatchToken.prototype = Object.create(CSSParserToken.prototype);
 	IncludeMatchToken.prototype.tokenType = "includes";
-
+	
 	function DashMatchToken() { return this; }
 	DashMatchToken.prototype = Object.create(CSSParserToken.prototype);
 	DashMatchToken.prototype.tokenType = "dashmatch";
-
+	
 	function PrefixMatchToken() { return this; }
 	PrefixMatchToken.prototype = Object.create(CSSParserToken.prototype);
 	PrefixMatchToken.prototype.tokenType = "beginsmatch";
-
+	
 	function SuffixMatchToken() { return this; }
 	SuffixMatchToken.prototype = Object.create(CSSParserToken.prototype);
 	SuffixMatchToken.prototype.tokenType = "endsmatch";
-
+	
 	function SubstringMatchToken() { return this; }
 	SubstringMatchToken.prototype = Object.create(CSSParserToken.prototype);
 	SubstringMatchToken.prototype.tokenType = "containsmatch";
-
+	
 	function ColumnToken() { return this; }
 	ColumnToken.prototype = Object.create(CSSParserToken.prototype);
 	ColumnToken.prototype.tokenType = "||";
-
+	
 	function EOFToken() { return this; }
 	EOFToken.prototype = Object.create(CSSParserToken.prototype);
 	EOFToken.prototype.tokenType = "EOF";
 	EOFToken.prototype.toSource = function() { return ""; };
-
+	
 	function DelimToken(code) {
 		this.value = stringFromCode(code);
 		this.text = this.value;
 		return this;
 	}
 	DelimToken.prototype = Object.create(CSSParserToken.prototype);
 	DelimToken.prototype.tokenType = "symbol";
 	DelimToken.prototype.toString = function() { return "DELIM("+this.value+")"; };
@@ -3635,62 +3613,62 @@ var Debugger =
 		return json;
 	};
 	DelimToken.prototype.toSource = function() {
 		if(this.value == "\\")
 			return "\\\n";
 		else
 			return this.value;
 	};
-
+	
 	function StringValuedToken() { throw "Abstract Base Class"; }
 	StringValuedToken.prototype = Object.create(CSSParserToken.prototype);
 	StringValuedToken.prototype.ASCIIMatch = function(str) {
 		return this.value.toLowerCase() == str.toLowerCase();
 	};
 	StringValuedToken.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.value = this.value;
 		return json;
 	};
-
+	
 	function IdentToken(val) {
 		this.value = val;
 		this.text = val;
 	}
 	IdentToken.prototype = Object.create(StringValuedToken.prototype);
 	IdentToken.prototype.tokenType = "ident";
 	IdentToken.prototype.toString = function() { return "IDENT("+this.value+")"; };
 	IdentToken.prototype.toSource = function() {
 		return escapeIdent(this.value);
 	};
-
+	
 	function FunctionToken(val) {
 		this.value = val;
 		this.text = val;
 		this.mirror = ")";
 	}
 	FunctionToken.prototype = Object.create(StringValuedToken.prototype);
 	FunctionToken.prototype.tokenType = "function";
 	FunctionToken.prototype.toString = function() { return "FUNCTION("+this.value+")"; };
 	FunctionToken.prototype.toSource = function() {
 		return escapeIdent(this.value) + "(";
 	};
-
+	
 	function AtKeywordToken(val) {
 		this.value = val;
 		this.text = val;
 	}
 	AtKeywordToken.prototype = Object.create(StringValuedToken.prototype);
 	AtKeywordToken.prototype.tokenType = "at";
 	AtKeywordToken.prototype.toString = function() { return "AT("+this.value+")"; };
 	AtKeywordToken.prototype.toSource = function() {
 		return "@" + escapeIdent(this.value);
 	};
-
+	
 	function HashToken(val) {
 		this.value = val;
 		this.text = val;
 		this.type = "unrestricted";
 	}
 	HashToken.prototype = Object.create(StringValuedToken.prototype);
 	HashToken.prototype.tokenType = "hash";
 	HashToken.prototype.toString = function() { return "HASH("+this.value+")"; };
@@ -3702,48 +3680,48 @@ var Debugger =
 	};
 	HashToken.prototype.toSource = function() {
 		if(this.type == "id") {
 			return "#" + escapeIdent(this.value);
 		} else {
 			return "#" + escapeHash(this.value);
 		}
 	};
-
+	
 	function StringToken(val) {
 		this.value = val;
 		this.text = val;
 	}
 	StringToken.prototype = Object.create(StringValuedToken.prototype);
 	StringToken.prototype.tokenType = "string";
 	StringToken.prototype.toString = function() {
 		return '"' + escapeString(this.value) + '"';
 	};
-
+	
 	function CommentToken(val) {
 		this.value = val;
 	}
 	CommentToken.prototype = Object.create(StringValuedToken.prototype);
 	CommentToken.prototype.tokenType = "comment";
 	CommentToken.prototype.toString = function() {
 		return '/*' + this.value + '*/';
 	}
 	CommentToken.prototype.toSource = CommentToken.prototype.toString;
-
+	
 	function URLToken(val) {
 		this.value = val;
 		this.text = val;
 	}
 	URLToken.prototype = Object.create(StringValuedToken.prototype);
 	URLToken.prototype.tokenType = "url";
 	URLToken.prototype.toString = function() { return "URL("+this.value+")"; };
 	URLToken.prototype.toSource = function() {
 		return 'url("' + escapeString(this.value) + '")';
 	};
-
+	
 	function NumberToken() {
 		this.value = null;
 		this.type = "integer";
 		this.repr = "";
 	}
 	NumberToken.prototype = Object.create(CSSParserToken.prototype);
 	NumberToken.prototype.tokenType = "number";
 	NumberToken.prototype.toString = function() {
@@ -3754,32 +3732,32 @@ var Debugger =
 	NumberToken.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.value = this.value;
 		json.type = this.type;
 		json.repr = this.repr;
 		return json;
 	};
 	NumberToken.prototype.toSource = function() { return this.repr; };
-
+	
 	function PercentageToken() {
 		this.value = null;
 		this.repr = "";
 	}
 	PercentageToken.prototype = Object.create(CSSParserToken.prototype);
 	PercentageToken.prototype.tokenType = "percentage";
 	PercentageToken.prototype.toString = function() { return "PERCENTAGE("+this.value+")"; };
 	PercentageToken.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.value = this.value;
 		json.repr = this.repr;
 		return json;
 	};
 	PercentageToken.prototype.toSource = function() { return this.repr + "%"; };
-
+	
 	function DimensionToken() {
 		this.value = null;
 		this.type = "integer";
 		this.repr = "";
 		this.unit = "";
 	}
 	DimensionToken.prototype = Object.create(CSSParserToken.prototype);
 	DimensionToken.prototype.tokenType = "dimension";
@@ -3797,27 +3775,27 @@ var Debugger =
 		var unit = escapeIdent(this.unit);
 		if(unit[0].toLowerCase() == "e" && (unit[1] == "-" || between(unit.charCodeAt(1), 0x30, 0x39))) {
 			// Unit is ambiguous with scinot
 			// Remove the leading "e", replace with escape.
 			unit = "\\65 " + unit.slice(1, unit.length);
 		}
 		return source+unit;
 	};
-
+	
 	function escapeIdent(string) {
 		string = ''+string;
 		var result = '';
 		var firstcode = string.charCodeAt(0);
 		for(var i = 0; i < string.length; i++) {
 			var code = string.charCodeAt(i);
 			if(code === 0x0) {
 				throw new InvalidCharacterError('Invalid character: the input contains U+0000.');
 			}
-
+	
 			if(
 				between(code, 0x1, 0x1f) || code == 0x7f ||
 				(i === 0 && between(code, 0x30, 0x39)) ||
 				(i == 1 && between(code, 0x30, 0x39) && firstcode == 0x2d)
 			) {
 				result += '\\' + code.toString(16) + ' ';
 			} else if(
 				code >= 0x80 ||
@@ -3829,66 +3807,66 @@ var Debugger =
 			) {
 				result += string[i];
 			} else {
 				result += '\\' + string[i];
 			}
 		}
 		return result;
 	}
-
+	
 	function escapeHash(string) {
 		// Escapes the contents of "unrestricted"-type hash tokens.
 		// Won't preserve the ID-ness of "id"-type hash tokens;
 		// use escapeIdent() for that.
 		string = ''+string;
 		var result = '';
 		for(var i = 0; i < string.length; i++) {
 			var code = string.charCodeAt(i);
 			if(code === 0x0) {
 				throw new InvalidCharacterError('Invalid character: the input contains U+0000.');
 			}
-
+	
 			if(
 				code >= 0x80 ||
 				code == 0x2d ||
 				code == 0x5f ||
 				between(code, 0x30, 0x39) ||
 				between(code, 0x41, 0x5a) ||
 				between(code, 0x61, 0x7a)
 			) {
 				result += string[i];
 			} else {
 				result += '\\' + code.toString(16) + ' ';
 			}
 		}
 		return result;
 	}
-
+	
 	function escapeString(string) {
 		string = ''+string;
 		var result = '';
 		for(var i = 0; i < string.length; i++) {
 			var code = string.charCodeAt(i);
-
+	
 			if(code === 0x0) {
 				throw new InvalidCharacterError('Invalid character: the input contains U+0000.');
 			}
-
+	
 			if(between(code, 0x1, 0x1f) || code == 0x7f) {
 				result += '\\' + code.toString(16) + ' ';
 			} else if(code == 0x22 || code == 0x5c) {
 				result += '\\' + string[i];
 			} else {
 				result += string[i];
 			}
 		}
 		return result;
 	}
-
+	
 	// Exportation.
 	exports.tokenize = tokenize;
 	exports.IdentToken = IdentToken;
 	exports.FunctionToken = FunctionToken;
 	exports.AtKeywordToken = AtKeywordToken;
 	exports.HashToken = HashToken;
 	exports.StringToken = StringToken;
 	exports.BadStringToken = BadStringToken;
@@ -3914,17 +3892,17 @@ var Debugger =
 	exports.CloseParenToken = CloseParenToken;
 	exports.OpenSquareToken = OpenSquareToken;
 	exports.CloseSquareToken = CloseSquareToken;
 	exports.OpenCurlyToken = OpenCurlyToken;
 	exports.CloseCurlyToken = CloseCurlyToken;
 	exports.EOFToken = EOFToken;
 	exports.CSSParserToken = CSSParserToken;
 	exports.GroupingToken = GroupingToken;
-
+	
 	function TokenStream(tokens) {
 		// Assume that tokens is a iterator.
 		this.tokens = tokens;
 		this.token = undefined;
 		this.stored = [];
 	}
 	TokenStream.prototype.consume = function(num) {
 		if(num === undefined) num = 1;
@@ -3956,23 +3934,23 @@ var Debugger =
 				return new EOFToken();
 			this.stored.push(n.value);
 		}
 		return this.stored[0];
 	};
 	TokenStream.prototype.reconsume = function() {
 		this.stored.unshift(this.token);
 	};
-
+	
 	function parseerror(s, msg) {
 		console.log("Parse error at token " + s.i + ": " + s.token + ".\n" + msg);
 		return true;
 	}
 	function donothing(){ return true; }
-
+	
 	function consumeAListOfRules(s, topLevel) {
 		var rules = [];
 		var rule;
 		while(s.consume()) {
 			if(s.token instanceof WhitespaceToken) {
 				continue;
 			} else if(s.token instanceof EOFToken) {
 				return rules;
@@ -3984,49 +3962,49 @@ var Debugger =
 				s.reconsume();
 				if(rule = consumeAnAtRule(s)) rules.push(rule);
 			} else {
 				s.reconsume();
 				if(rule = consumeAQualifiedRule(s)) rules.push(rule);
 			}
 		}
 	}
-
+	
 	function consumeAnAtRule(s) {
 		s.consume();
 		var rule = new AtRule(s.token.value);
 		while(s.consume()) {
 			if(s.token instanceof SemicolonToken || s.token instanceof EOFToken) {
 				return rule;
 			} else if(s.token instanceof OpenCurlyToken) {
 				rule.value = consumeASimpleBlock(s);
 				return rule;
 			} else {
 				s.reconsume();
 				rule.prelude.push(consumeAComponentValue(s));
 			}
 		}
 	}
-
+	
 	function consumeAQualifiedRule(s) {
 		var rule = new QualifiedRule();
 		while(s.consume()) {
 			if(s.token instanceof EOFToken) {
 				parseerror(s, "Hit EOF when trying to parse the prelude of a qualified rule.");
 				return;
 			} else if(s.token instanceof OpenCurlyToken) {
 				rule.value = consumeASimpleBlock(s);
 				return rule;
 			} else {
 				s.reconsume();
 				rule.prelude.push(consumeAComponentValue(s));
 			}
 		}
 	}
-
+	
 	function consumeAListOfDeclarations(s) {
 		var decls = [];
 		while(s.consume()) {
 			if(s.token instanceof WhitespaceToken || s.token instanceof SemicolonToken) {
 				donothing();
 			} else if(s.token instanceof EOFToken) {
 				return decls;
 			} else if(s.token instanceof AtKeywordToken) {
@@ -4041,17 +4019,17 @@ var Debugger =
 			} else {
 				parseerror(s);
 				s.reconsume();
 				while(!(s.next() instanceof SemicolonToken || s.next() instanceof EOFToken))
 					consumeAComponentValue(s);
 			}
 		}
 	}
-
+	
 	function consumeADeclaration(s) {
 		// Assumes that the next input token will be an ident token.
 		s.consume();
 		var decl = new Declaration(s.token.value);
 		while(s.next() instanceof WhitespaceToken) s.consume();
 		if(!(s.next() instanceof ColonToken)) {
 			parseerror(s);
 			return;
@@ -4072,133 +4050,133 @@ var Debugger =
 				decl.important = true;
 				break;
 			} else {
 				break;
 			}
 		}
 		return decl;
 	}
-
+	
 	function consumeAComponentValue(s) {
 		s.consume();
 		if(s.token instanceof OpenCurlyToken || s.token instanceof OpenSquareToken || s.token instanceof OpenParenToken)
 			return consumeASimpleBlock(s);
 		if(s.token instanceof FunctionToken)
 			return consumeAFunction(s);
 		return s.token;
 	}
-
+	
 	function consumeASimpleBlock(s) {
 		var mirror = s.token.mirror;
 		var block = new SimpleBlock(s.token.value);
 		block.startToken = s.token;
 		while(s.consume()) {
 			if(s.token instanceof EOFToken || (s.token instanceof GroupingToken && s.token.value == mirror))
 				return block;
 			else {
 				s.reconsume();
 				block.value.push(consumeAComponentValue(s));
 			}
 		}
 	}
-
+	
 	function consumeAFunction(s) {
 		var func = new Func(s.token.value);
 		while(s.consume()) {
 			if(s.token instanceof EOFToken || s.token instanceof CloseParenToken)
 				return func;
 			else {
 				s.reconsume();
 				func.value.push(consumeAComponentValue(s));
 			}
 		}
 	}
-
+	
 	function normalizeInput(input) {
 		if(typeof input == "string")
 			return new TokenStream(tokenize(input));
 		if(input instanceof TokenStream)
 			return input;
 		if(typeof (input.next) == "function")
 			return new TokenStream(input);
 		if(input.length !== undefined)
 			return new TokenStream(input[Symbol.iterator]());
 		else throw SyntaxError(input);
 	}
-
+	
 	function parseAStylesheet(s) {
 		s = normalizeInput(s);
 		var sheet = new Stylesheet();
 		sheet.value = consumeAListOfRules(s, "top-level");
 		return sheet;
 	}
-
+	
 	function parseAListOfRules(s) {
 		s = normalizeInput(s);
 		return consumeAListOfRules(s);
 	}
-
+	
 	function parseARule(s) {
 		s = normalizeInput(s);
 		while(s.next() instanceof WhitespaceToken) s.consume();
 		if(s.next() instanceof EOFToken) throw SyntaxError();
 		var rule;
 		var startToken = s.next();
 		if(startToken instanceof AtKeywordToken) {
 			rule = consumeAnAtRule(s);
 		} else {
 			rule = consumeAQualifiedRule(s);
 			if(!rule) throw SyntaxError();
 		}
 		rule.startToken = startToken;
 		rule.endToken = s.token;
 		return rule;
 	}
-
+	
 	function parseADeclaration(s) {
 		s = normalizeInput(s);
 		while(s.next() instanceof WhitespaceToken) s.consume();
 		if(!(s.next() instanceof IdentToken)) throw SyntaxError();
 		var decl = consumeADeclaration(s);
 		if(decl)
 			return decl;
 		else
 			throw SyntaxError();
 	}
-
+	
 	function parseAListOfDeclarations(s) {
 		s = normalizeInput(s);
 		return consumeAListOfDeclarations(s);
 	}
-
+	
 	function parseAComponentValue(s) {
 		s = normalizeInput(s);
 		while(s.next() instanceof WhitespaceToken) s.consume();
 		if(s.next() instanceof EOFToken) throw SyntaxError();
 		var val = consumeAComponentValue(s);
 		if(!val) throw SyntaxError();
 		while(s.next() instanceof WhitespaceToken) s.consume();
 		if(s.next() instanceof EOFToken)
 			return val;
 		throw SyntaxError();
 	}
-
+	
 	function parseAListOfComponentValues(s) {
 		s = normalizeInput(s);
 		var vals = [];
 		while(true) {
 			var val = consumeAComponentValue(s);
 			if(val instanceof EOFToken)
 				return vals;
 			else
 				vals.push(val);
 		}
 	}
-
+	
 	function parseACommaSeparatedListOfComponentValues(s) {
 		s = normalizeInput(s);
 		var listOfCVLs = [];
 		while(true) {
 			var vals = [];
 			while(true) {
 				var val = consumeAComponentValue(s);
 				if(val instanceof EOFToken) {
@@ -4208,132 +4186,132 @@ var Debugger =
 					listOfCVLs.push(vals);
 					break;
 				} else {
 					vals.push(val);
 				}
 			}
 		}
 	}
-
-
+	
+	
 	function CSSParserRule() { throw "Abstract Base Class"; }
 	CSSParserRule.prototype.toString = function(indent) {
 		return JSON.stringify(this,null,indent);
 	};
 	CSSParserRule.prototype.toJSON = function() {
 		return {type:this.type, value:this.value};
 	};
-
+	
 	function Stylesheet() {
 		this.value = [];
 		return this;
 	}
 	Stylesheet.prototype = Object.create(CSSParserRule.prototype);
 	Stylesheet.prototype.type = "STYLESHEET";
-
+	
 	function AtRule(name) {
 		this.name = name;
 		this.prelude = [];
 		this.value = null;
 		return this;
 	}
 	AtRule.prototype = Object.create(CSSParserRule.prototype);
 	AtRule.prototype.type = "AT-RULE";
 	AtRule.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.name = this.name;
 		json.prelude = this.prelude;
 		return json;
 	};
-
+	
 	function QualifiedRule() {
 		this.prelude = [];
 		this.value = [];
 		return this;
 	}
 	QualifiedRule.prototype = Object.create(CSSParserRule.prototype);
 	QualifiedRule.prototype.type = "QUALIFIED-RULE";
 	QualifiedRule.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.prelude = this.prelude;
 		return json;
 	};
-
+	
 	function Declaration(name) {
 		this.name = name;
 		this.value = [];
 		this.important = false;
 		return this;
 	}
 	Declaration.prototype = Object.create(CSSParserRule.prototype);
 	Declaration.prototype.type = "DECLARATION";
 	Declaration.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.name = this.name;
 		json.important = this.important;
 		return json;
 	};
-
+	
 	function SimpleBlock(type) {
 		this.name = type;
 		this.value = [];
 		return this;
 	}
 	SimpleBlock.prototype = Object.create(CSSParserRule.prototype);
 	SimpleBlock.prototype.type = "BLOCK";
 	SimpleBlock.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.name = this.name;
 		return json;
 	};
-
+	
 	function Func(name) {
 		this.name = name;
 		this.value = [];
 		return this;
 	}
 	Func.prototype = Object.create(CSSParserRule.prototype);
 	Func.prototype.type = "FUNCTION";
 	Func.prototype.toJSON = function() {
 		var json = this.constructor.prototype.constructor.prototype.toJSON.call(this);
 		json.name = this.name;
 		return json;
 	};
-
+	
 	function CSSLexer(text) {
 		this.stream = tokenize(text, {
 			loc: true,
 			offsets: true,
 			keepComments: true
 		});
 		this.lineNumber = 0;
 		this.columnNumber = 0;
 		return this;
 	}
-
+	
 	CSSLexer.prototype.performEOFFixup = function(input, preserveBackslash) {
 		// Just lie for now.
 		return "";
 	};
-
+	
 	CSSLexer.prototype.nextToken = function() {
 		if (!this.stream) {
 			return null;
 		}
 		let v = this.stream.next();
 		if (v.done || v.value.tokenType === "EOF") {
 			this.stream = null;
 			return null;
 		}
 		this.lineNumber = v.value.loc.start.line;
 		this.columnNumber = v.value.loc.start.column;
 		return v.value;
 	};
-
+	
 	// Exportation.
 	exports.CSSParserRule = CSSParserRule;
 	exports.Stylesheet = Stylesheet;
 	exports.AtRule = AtRule;
 	exports.QualifiedRule = QualifiedRule;
 	exports.Declaration = Declaration;
 	exports.SimpleBlock = SimpleBlock;
 	exports.Func = Func;
@@ -4341,17 +4319,17 @@ var Debugger =
 	exports.parseAListOfRules = parseAListOfRules;
 	exports.parseARule = parseARule;
 	exports.parseADeclaration = parseADeclaration;
 	exports.parseAListOfDeclarations = parseAListOfDeclarations;
 	exports.parseAComponentValue = parseAComponentValue;
 	exports.parseAListOfComponentValues = parseAListOfComponentValues;
 	exports.parseACommaSeparatedListOfComponentValues = parseACommaSeparatedListOfComponentValues;
 	exports.CSSLexer = CSSLexer;
-
+	
 	}));
 
 
 /***/ },
 /* 38 */
 /***/ function(module, exports) {
 
 	// auto-generated from nsColorNameList.h
@@ -6649,67 +6627,67 @@ var Debugger =
 
 /***/ },
 /* 40 */
 /***/ function(module, exports) {
 
 	/*
 	 * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/Promise.jsm
 	 */
-
+	
 	/**
 	 * Promise.jsm is mostly the Promise web API with a `defer` method. Just drop this in here,
 	 * and use the native web API (although building with webpack/babel, it may replace this
 	 * with it's own version if we want to target environments that do not have `Promise`.
 	 */
-
+	
 	let p = typeof window != "undefined" ?  window.Promise : Promise;
 	p.defer = function defer() {
 	  var resolve, reject;
 	  var promise = new Promise(function() {
 	    resolve = arguments[0];
 	    reject = arguments[1];
 	  });
 	  return {
 	    resolve: resolve,
 	    reject: reject,
 	    promise: promise
 	  };
 	}
-
+	
 	module.exports = p;
 
 
 /***/ },
 /* 41 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* eslint-env browser */
 	/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 	/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	// TODO: Get rid of this code once the marionette server loads transport.js as
 	// an SDK module (see bug 1000814)
-
+	
 	"use strict";
-
+	
 	const DevToolsUtils = __webpack_require__(42);
 	const { dumpn, dumpv } = DevToolsUtils;
 	const StreamUtils = __webpack_require__(48);
 	const { Packet, JSONPacket, BulkPacket } =
 	  __webpack_require__(49);
 	const promise = __webpack_require__(40);
 	const EventEmitter = __webpack_require__(34);
 	const utf8 = __webpack_require__(52);
-
+	
 	const PACKET_HEADER_MAX = 200;
-
+	
 	/**
 	 * An adapter that handles data transfers between the debugger client and
 	 * server. It can work with both nsIPipe and nsIServerSocket transports so
 	 * long as the properly created input and output streams are specified.
 	 * (However, for intra-process connections, LocalDebuggerTransport, below,
 	 * is more efficient than using an nsIPipe pair with DebuggerTransport.)
 	 *
 	 * @param input nsIAsyncInputStream
@@ -6759,54 +6737,54 @@ var Debugger =
 	 *   an optional nsresult or object, typically passed when the transport is
 	 *   closed due to some error in a underlying stream.
 	 *
 	 * See ./packets.js and the Remote Debugging Protocol specification for more
 	 * details on the format of these packets.
 	 */
 	function DebuggerTransport(socket) {
 	  EventEmitter.decorate(this);
-
+	
 	  this._socket = socket;
-
+	
 	  // The current incoming (possibly partial) header, which will determine which
 	  // type of Packet |_incoming| below will become.
 	  this._incomingHeader = "";
 	  // The current incoming Packet object
 	  this._incoming = null;
 	  // A queue of outgoing Packet objects
 	  this._outgoing = [];
-
+	
 	  this.hooks = null;
 	  this.active = false;
-
+	
 	  this._incomingEnabled = true;
 	  this._outgoingEnabled = true;
-
+	
 	  this.close = this.close.bind(this);
 	}
-
+	
 	DebuggerTransport.prototype = {
 	  /**
 	   * Transmit an object as a JSON packet.
 	   *
 	   * This method returns immediately, without waiting for the entire
 	   * packet to be transmitted, registering event handlers as needed to
 	   * transmit the entire packet. Packets are transmitted in the order
 	   * they are passed to this method.
 	   */
 	  send: function(object) {
 	    this.emit("send", object);
-
+	
 	    let packet = new JSONPacket(this);
 	    packet.object = object;
 	    this._outgoing.push(packet);
 	    this._flushOutgoing();
 	  },
-
+	
 	  /**
 	   * Transmit streaming data via a bulk packet.
 	   *
 	   * This method initiates the bulk send process by queuing up the header data.
 	   * The caller receives eventual access to a stream for writing.
 	   *
 	   * N.B.: Do *not* attempt to close the stream handed to you, as it will
 	   * continue to be used by this transport afterwards.  Most users should
@@ -6840,180 +6818,180 @@ var Debugger =
 	   *             @return Promise
 	   *                     The promise is resolved when copying completes or
 	   *                     rejected if any (unexpected) errors occur.
 	   *                     This object also emits "progress" events for each chunk
 	   *                     that is copied.  See stream-utils.js.
 	   */
 	  startBulkSend: function(header) {
 	    this.emit("startBulkSend", header);
-
+	
 	    let packet = new BulkPacket(this);
 	    packet.header = header;
 	    this._outgoing.push(packet);
 	    this._flushOutgoing();
 	    return packet.streamReadyForWriting;
 	  },
-
+	
 	  /**
 	   * Close the transport.
 	   * @param reason nsresult / object (optional)
 	   *        The status code or error message that corresponds to the reason for
 	   *        closing the transport (likely because a stream closed or failed).
 	   */
 	  close: function(reason) {
 	    this.emit("onClosed", reason);
-
+	
 	    this.active = false;
 	    this._socket.close();
 	    this._destroyIncoming();
 	    this._destroyAllOutgoing();
 	    if (this.hooks) {
 	      this.hooks.onClosed(reason);
 	      this.hooks = null;
 	    }
 	    if (reason) {
 	      dumpn("Transport closed: " + DevToolsUtils.safeErrorString(reason));
 	    } else {
 	      dumpn("Transport closed.");
 	    }
 	  },
-
+	
 	  /**
 	   * The currently outgoing packet (at the top of the queue).
 	   */
 	  get _currentOutgoing() {
 	    return this._outgoing[0];
 	  },
-
+	
 	  /**
 	   * Flush data to the outgoing stream.  Waits until the output stream notifies
 	   * us that it is ready to be written to (via onOutputStreamReady).
 	   */
 	  _flushOutgoing: function() {
 	    if (!this._outgoingEnabled || this._outgoing.length === 0) {
 	      return;
 	    }
-
+	
 	    // If the top of the packet queue has nothing more to send, remove it.
 	    if (this._currentOutgoing.done) {
 	      this._finishCurrentOutgoing();
 	    }
-
+	
 	    if (this._outgoing.length > 0) {
 	      setTimeout(this.onOutputStreamReady.bind(this), 0);
 	    }
 	  },
-
+	
 	  /**
 	   * Pause this transport's attempts to write to the output stream.  This is
 	   * used when we've temporarily handed off our output stream for writing bulk
 	   * data.
 	   */
 	  pauseOutgoing: function() {
 	    this._outgoingEnabled = false;
 	  },
-
+	
 	  /**
 	   * Resume this transport's attempts to write to the output stream.
 	   */
 	  resumeOutgoing: function() {
 	    this._outgoingEnabled = true;
 	    this._flushOutgoing();
 	  },
-
+	
 	  // nsIOutputStreamCallback
 	  /**
 	   * This is called when the output stream is ready for more data to be written.
 	   * The current outgoing packet will attempt to write some amount of data, but
 	   * may not complete.
 	   */
 	  onOutputStreamReady: DevToolsUtils.makeInfallible(function() {
 	    if (!this._outgoingEnabled || this._outgoing.length === 0) {
 	      return;
 	    }
-
+	
 	    try {
 	      this._currentOutgoing.write({
 	        write: data => {
 	          let count = data.length;
 	          this._socket.send(data);
 	          return count;
 	        }
 	      });
 	    } catch(e) {
 	      if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) {
 	        this.close(e.result);
 	        return;
 	      } else {
 	        throw e;
 	      }
 	    }
-
+	
 	    this._flushOutgoing();
 	  }, "DebuggerTransport.prototype.onOutputStreamReady"),
-
+	
 	  /**
 	   * Remove the current outgoing packet from the queue upon completion.
 	   */
 	  _finishCurrentOutgoing: function() {
 	    if (this._currentOutgoing) {
 	      this._currentOutgoing.destroy();
 	      this._outgoing.shift();
 	    }
 	  },
-
+	
 	  /**
 	   * Clear the entire outgoing queue.
 	   */
 	  _destroyAllOutgoing: function() {
 	    for (let packet of this._outgoing) {
 	      packet.destroy();
 	    }
 	    this._outgoing = [];
 	  },
-
+	
 	  /**
 	   * Initialize the input stream for reading. Once this method has been called,
 	   * we watch for packets on the input stream, and pass them to the appropriate
 	   * handlers via this.hooks.
 	   */
 	  ready: function() {
 	    this.active = true;
 	    this._waitForIncoming();
 	  },
-
+	
 	  /**
 	   * Asks the input stream to notify us (via onInputStreamReady) when it is
 	   * ready for reading.
 	   */
 	  _waitForIncoming: function() {
 	    if (this._incomingEnabled && !this._socket.onmessage) {
 	      this._socket.onmessage = this.onInputStreamReady.bind(this);
 	    }
 	  },
-
+	
 	  /**
 	   * Pause this transport's attempts to read from the input stream.  This is
 	   * used when we've temporarily handed off our input stream for reading bulk
 	   * data.
 	   */
 	  pauseIncoming: function() {
 	    this._incomingEnabled = false;
 	  },
-
+	
 	  /**
 	   * Resume this transport's attempts to read from the input stream.
 	   */
 	  resumeIncoming: function() {
 	    this._incomingEnabled = true;
 	    this._flushIncoming();
 	    this._waitForIncoming();
 	  },
-
+	
 	  // nsIInputStreamCallback
 	  /**
 	   * Called when the stream is either readable or closed.
 	   */
 	  onInputStreamReady:
 	  DevToolsUtils.makeInfallible(function(event) {
 	    let data = event.data;
 	    // TODO: ws-tcp-proxy decodes utf-8, but the transport expects to see the
@@ -7024,213 +7002,213 @@ var Debugger =
 	        return data.length;
 	      },
 	      readBytes(count) {
 	        let result = data.slice(0, count);
 	        data = data.slice(count);
 	        return result;
 	      },
 	    };
-
+	
 	    try {
 	      while (data && this._incomingEnabled &&
 	             this._processIncoming(stream, stream.available())) {}
 	      this._waitForIncoming();
 	    } catch(e) {
 	      if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) {
 	        this.close(e.result);
 	      } else {
 	        throw e;
 	      }
 	    }
 	  }, "DebuggerTransport.prototype.onInputStreamReady"),
-
+	
 	  /**
 	   * Process the incoming data.  Will create a new currently incoming Packet if
 	   * needed.  Tells the incoming Packet to read as much data as it can, but
 	   * reading may not complete.  The Packet signals that its data is ready for
 	   * delivery by calling one of this transport's _on*Ready methods (see
 	   * ./packets.js and the _on*Ready methods below).
 	   * @return boolean
 	   *         Whether incoming stream processing should continue for any
 	   *         remaining data.
 	   */
 	  _processIncoming: function(stream, count) {
 	    dumpv("Data available: " + count);
-
+	
 	    if (!count) {
 	      dumpv("Nothing to read, skipping");
 	      return false;
 	    }
-
+	
 	    try {
 	      if (!this._incoming) {
 	        dumpv("Creating a new packet from incoming");
-
+	
 	        if (!this._readHeader(stream)) {
 	          return false; // Not enough data to read packet type
 	        }
-
+	
 	        // Attempt to create a new Packet by trying to parse each possible
 	        // header pattern.
 	        this._incoming = Packet.fromHeader(this._incomingHeader, this);
 	        if (!this._incoming) {
 	          throw new Error("No packet types for header: " +
 	                          this._incomingHeader);
 	        }
 	      }
-
+	
 	      if (!this._incoming.done) {
 	        // We have an incomplete packet, keep reading it.
 	        dumpv("Existing packet incomplete, keep reading");
 	        this._incoming.read(stream);
 	      }
 	    } catch(e) {
 	      let msg = "Error reading incoming packet: (" + e + " - " + e.stack + ")";
 	      dumpn(msg);
-
+	
 	      // Now in an invalid state, shut down the transport.
 	      this.close();
 	      return false;
 	    }
-
+	
 	    if (!this._incoming.done) {
 	      // Still not complete, we'll wait for more data.
 	      dumpv("Packet not done, wait for more");
 	      return true;
 	    }
-
+	
 	    // Ready for next packet
 	    this._flushIncoming();
 	    return true;
 	  },
-
+	
 	  /**
 	   * Read as far as we can into the incoming data, attempting to build up a
 	   * complete packet header (which terminates with ":").  We'll only read up to
 	   * PACKET_HEADER_MAX characters.
 	   * @return boolean
 	   *         True if we now have a complete header.
 	   */
 	  _readHeader: function(stream) {
 	    let amountToRead = PACKET_HEADER_MAX - this._incomingHeader.length;
 	    this._incomingHeader +=
 	      StreamUtils.delimitedRead(stream, ":", amountToRead);
 	    if (dumpv.wantVerbose) {
 	      dumpv("Header read: " + this._incomingHeader);
 	    }
-
+	
 	    if (this._incomingHeader.endsWith(":")) {
 	      if (dumpv.wantVerbose) {
 	        dumpv("Found packet header successfully: " + this._incomingHeader);
 	      }
 	      return true;
 	    }
-
+	
 	    if (this._incomingHeader.length >= PACKET_HEADER_MAX) {
 	      throw new Error("Failed to parse packet header!");
 	    }
-
+	
 	    // Not enough data yet.
 	    return false;
 	  },
-
+	
 	  /**
 	   * If the incoming packet is done, log it as needed and clear the buffer.
 	   */
 	  _flushIncoming: function() {
 	    if (!this._incoming.done) {
 	      return;
 	    }
 	    if (dumpn.wantLogging) {
 	      dumpn("Got: " + this._incoming);
 	    }
 	    this._destroyIncoming();
 	  },
-
+	
 	  /**
 	   * Handler triggered by an incoming JSONPacket completing it's |read| method.
 	   * Delivers the packet to this.hooks.onPacket.
 	   */
 	  _onJSONObjectReady: function(object) {
 	    DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => {
 	      // Ensure the transport is still alive by the time this runs.
 	      if (this.active) {
 	        this.emit("onPacket", object);
 	        this.hooks.onPacket(object);
 	      }
 	    }, "DebuggerTransport instance's this.hooks.onPacket"));
 	  },
-
+	
 	  /**
 	   * Handler triggered by an incoming BulkPacket entering the |read| phase for
 	   * the stream portion of the packet.  Delivers info about the incoming
 	   * streaming data to this.hooks.onBulkPacket.  See the main comment on the
 	   * transport at the top of this file for more details.
 	   */
 	  _onBulkReadReady: function(...args) {
 	    DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => {
 	      // Ensure the transport is still alive by the time this runs.
 	      if (this.active) {
 	        this.emit("onBulkPacket", ...args);
 	        this.hooks.onBulkPacket(...args);
 	      }
 	    }, "DebuggerTransport instance's this.hooks.onBulkPacket"));
 	  },
-
+	
 	  /**
 	   * Remove all handlers and references related to the current incoming packet,
 	   * either because it is now complete or because the transport is closing.
 	   */
 	  _destroyIncoming: function() {
 	    if (this._incoming) {
 	      this._incoming.destroy();
 	    }
 	    this._incomingHeader = "";
 	    this._incoming = null;
 	  }
-
-	};
-
+	
+	};
+	
 	exports.DebuggerTransport = DebuggerTransport;
-
+	
 	/**
 	 * An adapter that handles data transfers between the debugger client and
 	 * server when they both run in the same process. It presents the same API as
 	 * DebuggerTransport, but instead of transmitting serialized messages across a
 	 * connection it merely calls the packet dispatcher of the other side.
 	 *
 	 * @param other LocalDebuggerTransport
 	 *        The other endpoint for this debugger connection.
 	 *
 	 * @see DebuggerTransport
 	 */
 	function LocalDebuggerTransport(other) {
 	  EventEmitter.decorate(this);
-
+	
 	  this.other = other;
 	  this.hooks = null;
-
+	
 	  /*
 	   * A packet number, shared between this and this.other. This isn't used
 	   * by the protocol at all, but it makes the packet traces a lot easier to
 	   * follow.
 	   */
 	  this._serial = this.other ? this.other._serial : { count: 0 };
 	  this.close = this.close.bind(this);
 	}
-
+	
 	LocalDebuggerTransport.prototype = {
 	  /**
 	   * Transmit a message by directly calling the onPacket handler of the other
 	   * endpoint.
 	   */
 	  send: function(packet) {
 	    this.emit("send", packet);
-
+	
 	    let serial = this._serial.count++;
 	    if (dumpn.wantLogging) {
 	      /* Check 'from' first, as 'echo' packets have both. */
 	      if (packet.from) {
 	        dumpn("Packet " + serial + " sent from " + uneval(packet.from));
 	      } else if (packet.to) {
 	        dumpn("Packet " + serial + " sent to " + uneval(packet.to));
 	      }
@@ -7245,121 +7223,121 @@ var Debugger =
 	        }
 	        if (other.hooks) {
 	          other.emit("onPacket", packet);
 	          other.hooks.onPacket(packet);
 	        }
 	      }, "LocalDebuggerTransport instance's this.other.hooks.onPacket"));
 	    }
 	  },
-
+	
 	  /**
 	   * Send a streaming bulk packet directly to the onBulkPacket handler of the
 	   * other endpoint.
 	   *
 	   * This case is much simpler than the full DebuggerTransport, since there is
 	   * no primary stream we have to worry about managing while we hand it off to
 	   * others temporarily.  Instead, we can just make a single use pipe and be
 	   * done with it.
 	   */
 	  startBulkSend: function({actor, type, length}) {
 	    this.emit("startBulkSend", {actor, type, length});
-
+	
 	    let serial = this._serial.count++;
-
+	
 	    dumpn("Sent bulk packet " + serial + " for actor " + actor);
 	    if (!this.other) {
 	      return;
 	    }
-
+	
 	    let pipe = new Pipe(true, true, 0, 0, null);
-
+	
 	    DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => {
 	      dumpn("Received bulk packet " + serial);
 	      if (!this.other.hooks) {
 	        return;
 	      }
-
+	
 	      // Receiver
 	      let deferred = promise.defer();
 	      let packet = {
 	        actor: actor,
 	        type: type,
 	        length: length,
 	        copyTo: (output) => {
 	          let copying =
 	            StreamUtils.copyStream(pipe.inputStream, output, length);
 	          deferred.resolve(copying);
 	          return copying;
 	        },
 	        stream: pipe.inputStream,
 	        done: deferred
 	      };
-
+	
 	      this.other.emit("onBulkPacket", packet);
 	      this.other.hooks.onBulkPacket(packet);
-
+	
 	      // Await the result of reading from the stream
 	      deferred.promise.then(() => pipe.inputStream.close(), this.close);
 	    }, "LocalDebuggerTransport instance's this.other.hooks.onBulkPacket"));
-
+	
 	    // Sender
 	    let sendDeferred = promise.defer();
-
+	
 	    // The remote transport is not capable of resolving immediately here, so we
 	    // shouldn't be able to either.
 	    DevToolsUtils.executeSoon(() => {
 	      let copyDeferred = promise.defer();
-
+	
 	      sendDeferred.resolve({
 	        copyFrom: (input) => {
 	          let copying =
 	            StreamUtils.copyStream(input, pipe.outputStream, length);
 	          copyDeferred.resolve(copying);
 	          return copying;
 	        },
 	        stream: pipe.outputStream,
 	        done: copyDeferred
 	      });
-
+	
 	      // Await the result of writing to the stream
 	      copyDeferred.promise.then(() => pipe.outputStream.close(), this.close);
 	    });
-
+	
 	    return sendDeferred.promise;
 	  },
-
+	
 	  /**
 	   * Close the transport.
 	   */
 	  close: function() {
 	    this.emit("close");
-
+	
 	    if (this.other) {
 	      // Remove the reference to the other endpoint before calling close(), to
 	      // avoid infinite recursion.
 	      let other = this.other;
 	      this.other = null;
 	      other.close();
 	    }
 	    if (this.hooks) {
 	      try {
 	        this.hooks.onClosed();
 	      } catch(ex) {
 	        console.error(ex);
 	      }
 	      this.hooks = null;
 	    }
 	  },
-
+	
 	  /**
 	   * An empty method for emulating the DebuggerTransport API.
 	   */
 	  ready: function() {},
-
+	
 	  /**
 	   * Helper function that makes an object fully immutable.
 	   */
 	  _deepFreeze: function(object) {
 	    Object.freeze(object);
 	    for (let prop in object) {
 	      // Freeze the properties that are objects, not on the prototype, and not
 	      // already frozen. Note that this might leave an unfrozen reference
@@ -7367,209 +7345,209 @@ var Debugger =
 	      // an unfrozen object.
 	      if (object.hasOwnProperty(prop) && typeof object === "object" &&
 	          !Object.isFrozen(object)) {
 	        this._deepFreeze(o[prop]);
 	      }
 	    }
 	  }
 	};
-
+	
 	exports.LocalDebuggerTransport = LocalDebuggerTransport;
-
+	
 	/**
 	 * A transport for the debugging protocol that uses nsIMessageSenders to
 	 * exchange packets with servers running in child processes.
 	 *
 	 * In the parent process, |sender| should be the nsIMessageSender for the
 	 * child process. In a child process, |sender| should be the child process
 	 * message manager, which sends packets to the parent.
 	 *
 	 * |prefix| is a string included in the message names, to distinguish
 	 * multiple servers running in the same child process.
 	 *
 	 * This transport exchanges messages named 'debug:<prefix>:packet', where
 	 * <prefix> is |prefix|, whose data is the protocol packet.
 	 */
 	function ChildDebuggerTransport(sender, prefix) {
 	  EventEmitter.decorate(this);
-
+	
 	  this._sender = sender.QueryInterface(Ci.nsIMessageSender);
 	  this._messageName = "debug:" + prefix + ":packet";
 	}
-
+	
 	/*
 	 * To avoid confusion, we use 'message' to mean something that
 	 * nsIMessageSender conveys, and 'packet' to mean a remote debugging
 	 * protocol packet.
 	 */
 	ChildDebuggerTransport.prototype = {
 	  constructor: ChildDebuggerTransport,
-
+	
 	  hooks: null,
-
+	
 	  ready: function () {
 	    this._sender.addMessageListener(this._messageName, this);
 	  },
-
+	
 	  close: function () {
 	    this._sender.removeMessageListener(this._messageName, this);
 	    this.emit("onClosed");
 	    this.hooks.onClosed();
 	  },
-
+	
 	  receiveMessage: function ({data}) {
 	    this.emit("onPacket", data);
 	    this.hooks.onPacket(data);
 	  },
-
+	
 	  send: function (packet) {
 	    this.emit("send", packet);
 	    this._sender.sendAsyncMessage(this._messageName, packet);
 	  },
-
+	
 	  startBulkSend: function() {
 	    throw new Error("Can't send bulk data to child processes.");
 	  }
 	};
-
+	
 	exports.ChildDebuggerTransport = ChildDebuggerTransport;
-
+	
 	// WorkerDebuggerTransport is defined differently depending on whether we are
 	// on the main thread or a worker thread. In the former case, we are required
 	// by the devtools loader, and isWorker will be false. Otherwise, we are
 	// required by the worker loader, and isWorker will be true.
 	//
 	// Each worker debugger supports only a single connection to the main thread.
 	// However, its theoretically possible for multiple servers to connect to the
 	// same worker. Consequently, each transport has a connection id, to allow
 	// messages from multiple connections to be multiplexed on a single channel.
-
+	
 	if (typeof WorkerGlobalScope === 'undefined') { // i.e. not in a worker
 	  (function () { // Main thread
 	    /**
 	     * A transport that uses a WorkerDebugger to send packets from the main
 	     * thread to a worker thread.
 	     */
 	    function WorkerDebuggerTransport(dbg, id) {
 	      this._dbg = dbg;
 	      this._id = id;
 	      this.onMessage = this._onMessage.bind(this);
 	    }
-
+	
 	    WorkerDebuggerTransport.prototype = {
 	      constructor: WorkerDebuggerTransport,
-
+	
 	      ready: function () {
 	        this._dbg.addListener(this);
 	      },
-
+	
 	      close: function () {
 	        this._dbg.removeListener(this);
 	        if (this.hooks) {
 	          this.hooks.onClosed();
 	        }
 	      },
-
+	
 	      send: function (packet) {
 	        this._dbg.postMessage(JSON.stringify({
 	          type: "message",
 	          id: this._id,
 	          message: packet
 	        }));
 	      },
-
+	
 	      startBulkSend: function () {
 	        throw new Error("Can't send bulk data from worker threads!");
 	      },
-
+	
 	      _onMessage: function (message) {
 	        let packet = JSON.parse(message);
 	        if (packet.type !== "message" || packet.id !== this._id) {
 	          return;
 	        }
-
+	
 	        if (this.hooks) {
 	          this.hooks.onPacket(packet.message);
 	        }
 	      }
 	    };
-
+	
 	    exports.WorkerDebuggerTransport = WorkerDebuggerTransport;
 	  }).call(this);
 	} else {
 	  (function () { // Worker thread
 	    /*
 	     * A transport that uses a WorkerDebuggerGlobalScope to send packets from a
 	     * worker thread to the main thread.
 	     */
 	    function WorkerDebuggerTransport(scope, id) {
 	      this._scope = scope;
 	      this._id = id;
 	      this._onMessage = this._onMessage.bind(this);
 	    }
-
+	
 	    WorkerDebuggerTransport.prototype = {
 	      constructor: WorkerDebuggerTransport,
-
+	
 	      ready: function () {
 	        this._scope.addEventListener("message", this._onMessage);
 	      },
-
+	
 	      close: function () {
 	        this._scope.removeEventListener("message", this._onMessage);
 	        if (this.hooks) {
 	          this.hooks.onClosed();
 	        }
 	      },
-
+	
 	      send: function (packet) {
 	        this._scope.postMessage(JSON.stringify({
 	          type: "message",
 	          id: this._id,
 	          message: packet
 	        }));
 	      },
-
+	
 	      startBulkSend: function () {
 	        throw new Error("Can't send bulk data from worker threads!");
 	      },
-
+	
 	      _onMessage: function (event) {
 	        let packet = JSON.parse(event.data);
 	        if (packet.type !== "message" || packet.id !== this._id) {
 	          return;
 	        }
-
+	
 	        if (this.hooks) {
 	          this.hooks.onPacket(packet.message);
 	        }
 	      }
 	    };
-
+	
 	    exports.WorkerDebuggerTransport = WorkerDebuggerTransport;
 	  }).call(this);
 	}
 
 
 /***/ },
 /* 42 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	/* General utilities used throughout devtools. */
 	var { Ci, Cu, Cc, components } = __webpack_require__(35);
 	const { Services } = __webpack_require__(28);
 	var promise = __webpack_require__(40);
-
+	
 	const { FileUtils } = __webpack_require__(43);
-
+	
 	/**
 	 * Turn the error |aError| into a string, without fail.
 	 */
 	exports.safeErrorString = function safeErrorString(aError) {
 	  try {
 	    let errorString = aError.toString();
 	    if (typeof errorString == "string") {
 	      // Attempt to attach a stack to |errorString|. If it throws an error, or
@@ -7577,49 +7555,49 @@ var Debugger =
 	      try {
 	        if (aError.stack) {
 	          let stack = aError.stack.toString();
 	          if (typeof stack == "string") {
 	            errorString += "\nStack: " + stack;
 	          }
 	        }
 	      } catch (ee) { }
-
+	
 	      // Append additional line and column number information to the output,
 	      // since it might not be part of the stringified error.
 	      if (typeof aError.lineNumber == "number" && typeof aError.columnNumber == "number") {
 	        errorString += "Line: " + aError.lineNumber + ", column: " + aError.columnNumber;
 	      }
-
+	
 	      return errorString;
 	    }
 	  } catch (ee) { }
-
+	
 	  // We failed to find a good error description, so do the next best thing.
 	  return Object.prototype.toString.call(aError);
 	};
-
+	
 	/**
 	 * Report that |aWho| threw an exception, |aException|.
 	 */
 	exports.reportException = function reportException(aWho, aException) {
 	  let msg = aWho + " threw an exception: " + exports.safeErrorString(aException);
-
+	
 	  console.log(msg);
-
+	
 	//  if (Cu && console.error) {
 	//    /*
 	//     * Note that the xpcshell test harness registers an observer for
 	//     * console messages, so when we're running tests, this will cause
 	//     * the test to quit.
 	//     */
 	//    console.error(msg);
 	//  }
 	};
-
+	
 	/**
 	 * Given a handler function that may throw, return an infallible handler
 	 * function that calls the fallible handler, and logs any exceptions it
 	 * throws.
 	 *
 	 * @param aHandler function
 	 *      A handler function, which may throw.
 	 * @param aName string
@@ -7627,63 +7605,63 @@ var Debugger =
 	 *      aHandler.name.
 	 *
 	 * (SpiderMonkey does generate good names for anonymous functions, but we
 	 * don't have a way to get at them from JavaScript at the moment.)
 	 */
 	exports.makeInfallible = function makeInfallible(aHandler, aName) {
 	  if (!aName)
 	    aName = aHandler.name;
-
+	
 	  return function(/* arguments */) {
 	    // try {
 	    return aHandler.apply(this, arguments);
 	    // } catch (ex) {
 	    //   let who = "Handler function";
 	    //   if (aName) {
 	    //     who += " " + aName;
 	    //   }
 	    //   return exports.reportException(who, ex);
 	    // }
 	  };
 	};
-
+	
 	/**
 	 * Waits for the next tick in the event loop to execute a callback.
 	 */
 	exports.executeSoon = function executeSoon(aFn) {
 	  setTimeout(aFn, 0);
 	};
-
+	
 	/**
 	 * Waits for the next tick in the event loop.
 	 *
 	 * @return Promise
 	 *         A promise that is resolved after the next tick in the event loop.
 	 */
 	exports.waitForTick = function waitForTick() {
 	  let deferred = promise.defer();
 	  exports.executeSoon(deferred.resolve);
 	  return deferred.promise;
 	};
-
+	
 	/**
 	 * Waits for the specified amount of time to pass.
 	 *
 	 * @param number aDelay
 	 *        The amount of time to wait, in milliseconds.
 	 * @return Promise
 	 *         A promise that is resolved after the specified amount of time passes.
 	 */
 	exports.waitForTime = function waitForTime(aDelay) {
 	  let deferred = promise.defer();
 	  setTimeout(deferred.resolve, aDelay);
 	  return deferred.promise;
 	};
-
+	
 	/**
 	 * Like Array.prototype.forEach, but doesn't cause jankiness when iterating over
 	 * very large arrays by yielding to the browser and continuing execution on the
 	 * next tick.
 	 *
 	 * @param Array aArray
 	 *        The array being iterated over.
 	 * @param Function aFn
@@ -7691,48 +7669,48 @@ var Debugger =
 	 *        returned by this function, iterating over the array will be paused
 	 *        until the respective promise is resolved.
 	 * @returns Promise
 	 *          A promise that is resolved once the whole array has been iterated
 	 *          over, and all promises returned by the aFn callback are resolved.
 	 */
 	exports.yieldingEach = function yieldingEach(aArray, aFn) {
 	  const deferred = promise.defer();
-
+	
 	  let i = 0;
 	  let len = aArray.length;
 	  let outstanding = [deferred.promise];
-
+	
 	  (function loop() {
 	    const start = Date.now();
-
+	
 	    while (i < len) {
 	      // Don't block the main thread for longer than 16 ms at a time. To
 	      // maintain 60fps, you have to render every frame in at least 16ms; we
 	      // aren't including time spent in non-JS here, but this is Good
 	      // Enough(tm).
 	      if (Date.now() - start > 16) {
 	        exports.executeSoon(loop);
 	        return;
 	      }
-
+	
 	      try {
 	        outstanding.push(aFn(aArray[i], i++));
 	      } catch (e) {
 	        deferred.reject(e);
 	        return;
 	      }
 	    }
-
+	
 	    deferred.resolve();
 	  }());
-
+	
 	  return promise.all(outstanding);
 	};
-
+	
 	/**
 	 * Like XPCOMUtils.defineLazyGetter, but with a |this| sensitive getter that
 	 * allows the lazy getter to be defined on a prototype and work correctly with
 	 * instances.
 	 *
 	 * @param Object aObject
 	 *        The prototype object to define the lazy getter on.
 	 * @param String aKey
@@ -7742,28 +7720,28 @@ var Debugger =
 	 *        called with the |this| value of the current instance.
 	 */
 	exports.defineLazyPrototypeGetter =
 	function defineLazyPrototypeGetter(aObject, aKey, aCallback) {
 	  Object.defineProperty(aObject, aKey, {
 	    configurable: true,
 	    get: function() {
 	      const value = aCallback.call(this);
-
+	
 	      Object.defineProperty(this, aKey, {
 	        configurable: true,
 	        writable: true,
 	        value: value
 	      });
-
+	
 	      return value;
 	    }
 	  });
 	};
-
+	
 	/**
 	 * Safely get the property value from a Debugger.Object for a given key. Walks
 	 * the prototype chain until the property is found.
 	 *
 	 * @param Debugger.Object aObject
 	 *        The Debugger.Object to get the value from.
 	 * @param String aKey
 	 *        The key to look for.
@@ -7784,17 +7762,17 @@ var Debugger =
 	      aObj = aObj.proto;
 	    } while (aObj);
 	  } catch (e) {
 	    // If anything goes wrong report the error and return undefined.
 	    exports.reportException("getProperty", e);
 	  }
 	  return undefined;
 	};
-
+	
 	/**
 	 * Determines if a descriptor has a getter which doesn't call into JavaScript.
 	 *
 	 * @param Object aDesc
 	 *        The descriptor to check for a safe getter.
 	 * @return Boolean
 	 *         Whether a safe getter was found.
 	 */
@@ -7804,17 +7782,17 @@ var Debugger =
 	  try {
 	    let fn = aDesc.get.unwrap();
 	    return fn && fn.callable && fn.class == "Function" && fn.script === undefined;
 	  } catch (e) {
 	    // Avoid exception 'Object in compartment marked as invisible to Debugger'
 	    return false;
 	  }
 	};
-
+	
 	/**
 	 * Check if it is safe to read properties and execute methods from the given JS
 	 * object. Safety is defined as being protected from unintended code execution
 	 * from content scripts (or cross-compartment code).
 	 *
 	 * See bugs 945920 and 946752 for discussion.
 	 *
 	 * @type Object aObj
@@ -7823,87 +7801,87 @@ var Debugger =
 	 *         True if it is safe to read properties from aObj, or false otherwise.
 	 */
 	exports.isSafeJSObject = function isSafeJSObject(aObj) {
 	  // If we are running on a worker thread, Cu is not available. In this case,
 	  // we always return false, just to be on the safe side.
 	  if (isWorker) {
 	    return false;
 	  }
-
+	
 	  if (Cu.getGlobalForObject(aObj) ==
 	      Cu.getGlobalForObject(exports.isSafeJSObject)) {
 	    return true; // aObj is not a cross-compartment wrapper.
 	  }
-
+	
 	  let principal = Cu.getObjectPrincipal(aObj);
 	  if (Services.scriptSecurityManager.isSystemPrincipal(principal)) {
 	    return true; // allow chrome objects
 	  }
-
+	
 	  return Cu.isXrayWrapper(aObj);
 	};
-
+	
 	exports.dumpn = function dumpn(str) {
 	  if (exports.dumpn.wantLogging) {
 	    console.log("DBG-SERVER: " + str + "\n");
 	  }
 	};
-
+	
 	// We want wantLogging to be writable. The exports object is frozen by the
 	// loader, so define it on dumpn instead.
 	exports.dumpn.wantLogging = false;
-
+	
 	/**
 	 * A verbose logger for low-level tracing.
 	 */
 	exports.dumpv = function(msg) {
 	  if (exports.dumpv.wantVerbose) {
 	    exports.dumpn(msg);
 	  }
 	};
-
+	
 	// We want wantLogging to be writable. The exports object is frozen by the
 	// loader, so define it on dumpn instead.
 	exports.dumpv.wantVerbose = false;
-
+	
 	/**
 	 * Utility function for updating an object with the properties of
 	 * other objects.
 	 *
 	 * @param aTarget Object
 	 *        The object being updated.
 	 * @param aNewAttrs Object
 	 *        The rest params are objects to update aTarget with. You
 	 *        can pass as many as you like.
 	 */
 	exports.update = function update(aTarget, ...aArgs) {
 	  for (let attrs of aArgs) {
 	    for (let key in attrs) {
 	      let desc = Object.getOwnPropertyDescriptor(attrs, key);
-
+	
 	      if (desc) {
 	        Object.defineProperty(aTarget, key, desc);
 	      }
 	    }
 	  }
-
+	
 	  return aTarget;
 	};
-
+	
 	/**
 	 * Utility function for getting the values from an object as an array
 	 *
 	 * @param aObject Object
 	 *        The object to iterate over
 	 */
 	exports.values = function values(aObject) {
 	  return Object.keys(aObject).map(k => aObject[k]);
 	};
-
+	
 	/**
 	 * Defines a getter on a specified object that will be created upon first use.
 	 *
 	 * @param aObject
 	 *        The object to define the lazy getter on.
 	 * @param aName
 	 *        The name of the getter to define on aObject.
 	 * @param aLambda
@@ -7915,50 +7893,50 @@ var Debugger =
 	    get: function() {
 	      delete aObject[aName];
 	      return aObject[aName] = aLambda.apply(aObject);
 	    },
 	    configurable: true,
 	    enumerable: true
 	  });
 	};
-
+	
 	// DEPRECATED: use DevToolsUtils.assert(condition, message) instead!
 	let haveLoggedDeprecationMessage = false;
 	exports.dbg_assert = function dbg_assert(cond, e) {
 	  if (!haveLoggedDeprecationMessage) {
 	    haveLoggedDeprecationMessage = true;
 	    const deprecationMessage = "DevToolsUtils.dbg_assert is deprecated! Use DevToolsUtils.assert instead!"
 	          + Error().stack;
 	    console.log(deprecationMessage);
 	    if (typeof console === "object" && console && console.warn) {
 	      console.warn(deprecationMessage);
 	    }
 	  }
-
+	
 	  if (!cond) {
 	    return e;
 	  }
 	};
-
+	
 	const { AppConstants } = __webpack_require__(44);
-
+	
 	/**
 	 * No operation. The empty function.
 	 */
 	exports.noop = function() { };
-
+	
 	function reallyAssert(condition, message) {
 	  if (!condition) {
 	    const err = new Error("Assertion failure: " + message);
 	    exports.reportException("DevToolsUtils.assert", err);
 	    throw err;
 	  }
 	}
-
+	
 	/**
 	 * DevToolsUtils.assert(condition, message)
 	 *
 	 * @param Boolean condition
 	 * @param String message
 	 *
 	 * Assertions are enabled when any of the following are true:
 	 *   - This is a DEBUG_JS_MODULES build
@@ -7973,17 +7951,17 @@ var Debugger =
 	 * This is an improvement over `dbg_assert`, which doesn't actually cause any
 	 * fatal behavior, and is therefore much easier to accidentally ignore.
 	 */
 	Object.defineProperty(exports, "assert", {
 	  get: () => (AppConstants.DEBUG || AppConstants.DEBUG_JS_MODULES || this.testing)
 	    ? reallyAssert
 	    : exports.noop,
 	});
-
+	
 	/**
 	 * Defines a getter on a specified object for a module.  The module will not
 	 * be imported until first use.
 	 *
 	 * @param aObject
 	 *        The object to define the lazy getter on.
 	 * @param aName
 	 *        The name of the getter to define on aObject for the module.
@@ -7998,23 +7976,23 @@ var Debugger =
 	                                                                 aSymbol)
 	{
 	  this.defineLazyGetter(aObject, aName, function XPCU_moduleLambda() {
 	    var temp = {};
 	    Cu.import(aResource, temp);
 	    return temp[aSymbol || aName];
 	  });
 	};
-
+	
 	const { NetUtil } = __webpack_require__(45);
-
+	
 	const { TextDecoder, OS } = __webpack_require__(46);
-
+	
 	const NetworkHelper = __webpack_require__(47);
-
+	
 	/**
 	 * Performs a request to load the desired URL and returns a promise.
 	 *
 	 * @param aURL String
 	 *        The URL we will request.
 	 * @param aOptions Object
 	 *        An object with the following optional properties:
 	 *        - loadFromCache: if false, will bypass the cache and
@@ -8040,138 +8018,138 @@ var Debugger =
 	  // Create a channel.
 	  let url = aURL.split(" -> ").pop();
 	  let channel;
 	  try {
 	    channel = newChannelForURL(url, aOptions);
 	  } catch (ex) {
 	    return promise.reject(ex);
 	  }
-
+	
 	  // Set the channel options.
 	  channel.loadFlags = aOptions.loadFromCache
 	    ? channel.LOAD_FROM_CACHE
 	    : channel.LOAD_BYPASS_CACHE;
-
+	
 	  if (aOptions.window) {
 	    // Respect private browsing.
 	    channel.loadGroup = aOptions.window.QueryInterface(Ci.nsIInterfaceRequestor)
 	                          .getInterface(Ci.nsIWebNavigation)
 	                          .QueryInterface(Ci.nsIDocumentLoader)
 	                          .loadGroup;
 	  }
-
+	
 	  let deferred = promise.defer();
 	  let onResponse = (stream, status, request) => {
 	    if (!components.isSuccessCode(status)) {
 	      deferred.reject(new Error(`Failed to fetch ${url}. Code ${status}.`));
 	      return;
 	    }
-
+	
 	    try {
 	      // We cannot use NetUtil to do the charset conversion as if charset
 	      // information is not available and our default guess is wrong the method
 	      // might fail and we lose the stream data. This means we can't fall back
 	      // to using the locale default encoding (bug 1181345).
-
+	
 	      // Read and decode the data according to the locale default encoding.
 	      let available = stream.available();
 	      let source = NetUtil.readInputStreamToString(stream, available);
 	      stream.close();
-
+	
 	      // If the channel or the caller has correct charset information, the
 	      // content will be decoded correctly. If we have to fall back to UTF-8 and
 	      // the guess is wrong, the conversion fails and convertToUnicode returns
 	      // the input unmodified. Essentially we try to decode the data as UTF-8
 	      // and if that fails, we use the locale specific default encoding. This is
 	      // the best we can do if the source does not provide charset info.
 	      let charset = channel.contentCharset || aOptions.charset || "UTF-8";
 	      let unicodeSource = NetworkHelper.convertToUnicode(source, charset);
-
+	
 	      deferred.resolve({
 	        content: unicodeSource,
 	        contentType: request.contentType
 	      });
 	    } catch (ex) {
 	      let uri = request.originalURI;
 	      if (ex.name === "NS_BASE_STREAM_CLOSED" && uri instanceof Ci.nsIFileURL) {
 	        // Empty files cause NS_BASE_STREAM_CLOSED exception. Use OS.File to
 	        // differentiate between empty files and other errors (bug 1170864).
 	        // This can be removed when bug 982654 is fixed.
-
+	
 	        uri.QueryInterface(Ci.nsIFileURL);
 	        let result = OS.File.read(uri.file.path).then(bytes => {
 	          // Convert the bytearray to a String.
 	          let decoder = new TextDecoder();
 	          let content = decoder.decode(bytes);
-
+	
 	          // We can't detect the contentType without opening a channel
 	          // and that failed already. This is the best we can do here.
 	          return {
 	            content,
 	            contentType: "text/plain"
 	          };
 	        });
-
+	
 	        deferred.resolve(result);
 	      } else {
 	        deferred.reject(ex);
 	      }
 	    }
 	  };
-
+	
 	  // Open the channel
 	  try {
 	    NetUtil.asyncFetch(channel, onResponse);
 	  } catch (ex) {
 	    return promise.reject(ex);
 	  }
-
+	
 	  return deferred.promise;
 	}
-
+	
 	/**
 	 * Opens a channel for given URL. Tries a bit harder than NetUtil.newChannel.
 	 *
 	 * @param {String} url - The URL to open a channel for.
 	 * @param {Object} options - The options object passed to @method fetch.
 	 * @return {nsIChannel} - The newly created channel. Throws on failure.
 	 */
 	function newChannelForURL(url, { policy }) {
 	  let channelOptions = {
 	    contentPolicyType: policy,
 	    loadUsingSystemPrincipal: true,
 	    uri: url
 	  };
-
+	
 	  try {
 	    return NetUtil.newChannel(channelOptions);
 	  } catch (e) {
 	    // In the xpcshell tests, the script url is the absolute path of the test
 	    // file, which will make a malformed URI error be thrown. Add the file
 	    // scheme to see if it helps.
 	    channelOptions.uri = "file://" + url;
-
+	
 	    return NetUtil.newChannel(channelOptions);
 	  }
 	}
-
+	
 	// Fetch is defined differently depending on whether we are on the main thread
 	// or a worker thread.
 	if (typeof WorkerGlobalScope === "undefined") { // i.e. not in a worker
 	  exports.fetch = mainThreadFetch;
 	} else {
 	  // Services is not available in worker threads, nor is there any other way
 	  // to fetch a URL. We need to enlist the help from the main thread here, by
 	  // issuing an rpc request, to fetch the URL on our behalf.
 	  exports.fetch = function(url, options) {
 	    return rpc("fetch", url, options);
 	  };
 	}
-
+	
 	/**
 	 * Returns a promise that is resolved or rejected when all promises have settled
 	 * (resolved or rejected).
 	 *
 	 * This differs from Promise.all, which will reject immediately after the first
 	 * rejection, instead of waiting for the remaining promises to settle.
 	 *
 	 * @param values
@@ -8184,81 +8162,81 @@ var Debugger =
 	 *         resolved values in the given order, or undefined if values is an
 	 *         empty array. The reject reason will be forwarded from the first
 	 *         promise in the list of given promises to be rejected.
 	 */
 	exports.settleAll = values => {
 	  if (values === null || typeof (values[Symbol.iterator]) != "function") {
 	    throw new Error("settleAll() expects an iterable.");
 	  }
-
+	
 	  let deferred = promise.defer();
-
+	
 	  values = Array.isArray(values) ? values : [...values];
 	  let countdown = values.length;
 	  let resolutionValues = new Array(countdown);
 	  let rejectionValue;
 	  let rejectionOccurred = false;
-
+	
 	  if (!countdown) {
 	    deferred.resolve(resolutionValues);
 	    return deferred.promise;
 	  }
-
+	
 	  function checkForCompletion() {
 	    if (--countdown > 0) {
 	      return;
 	    }
 	    if (!rejectionOccurred) {
 	      deferred.resolve(resolutionValues);
 	    } else {
 	      deferred.reject(rejectionValue);
 	    }
 	  }
-
+	
 	  for (let i = 0; i < values.length; i++) {
 	    let index = i;
 	    let value = values[i];
 	    let resolver = result => {
 	      resolutionValues[index] = result;
 	      checkForCompletion();
 	    };
 	    let rejecter = error => {
 	      if (!rejectionOccurred) {
 	        rejectionValue = error;
 	        rejectionOccurred = true;
 	      }
 	      checkForCompletion();
 	    };
-
+	
 	    if (value && typeof (value.then) == "function") {
 	      value.then(resolver, rejecter);
 	    } else {
 	      // Given value is not a promise, forward it as a resolution value.
 	      resolver(value);
 	    }
 	  }
-
+	
 	  return deferred.promise;
 	};
-
+	
 	/**
 	 * When the testing flag is set, various behaviors may be altered from
 	 * production mode, typically to enable easier testing or enhanced debugging.
 	 */
 	var testing = false;
 	Object.defineProperty(exports, "testing", {
 	  get: function() {
 	    return testing;
 	  },
 	  set: function(state) {
 	    testing = state;
 	  }
 	});
-
+	
 	/**
 	 * Open the file at the given path for reading.
 	 *
 	 * @param {String} filePath
 	 *
 	 * @returns Promise<nsIInputStream>
 	 */
 	exports.openFileStream = function(filePath) {
@@ -8266,42 +8244,42 @@ var Debugger =
 	    const uri = NetUtil.newURI(new FileUtils.File(filePath));
 	    NetUtil.asyncFetch(
 	      { uri, loadUsingSystemPrincipal: true },
 	      (stream, result) => {
 	        if (!components.isSuccessCode(result)) {
 	          reject(new Error(`Could not open "${filePath}": result = ${result}`));
 	          return;
 	        }
-
+	
 	        resolve(stream);
 	      }
 	    );
 	  });
 	};
-
+	
 	exports.isGenerator = function(fn) {
 	  if (typeof fn !== "function") {
 	    return false;
 	  }
 	  let proto = Object.getPrototypeOf(fn);
 	  if (!proto) {
 	    return false;
 	  }
 	  let ctor = proto.constructor;
 	  if (!ctor) {
 	    return false;
 	  }
 	  return ctor.name == "GeneratorFunction";
 	};
-
+	
 	exports.isPromise = function(p) {
 	  return p && typeof p.then === "function";
 	};
-
+	
 	/**
 	 * Return true if `thing` is a SavedFrame, false otherwise.
 	 */
 	exports.isSavedFrame = function(thing) {
 	  return Object.prototype.toString.call(thing) === "[object SavedFrame]";
 	};
 
 
@@ -8316,17 +8294,17 @@ var Debugger =
 
 /***/ },
 /* 44 */
 /***/ function(module, exports) {
 
 	/*
 	 * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/AppConstants.jsm
 	 */
-
+	
 	module.exports = { AppConstants: {} };
 
 
 /***/ },
 /* 45 */
 /***/ function(module, exports) {
 
 	/*
@@ -8375,17 +8353,17 @@ var Debugger =
 	 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 	 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 	 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 	 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 	 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 	 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 	 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	 */
-
+	
 	/*
 	 * Creator:
 	 *  Joe Hewitt
 	 * Contributors
 	 *  John J. Barton (IBM Almaden)
 	 *  Jan Odvarko (Mozilla Corp.)
 	 *  Max Stepanov (Aptana Inc.)
 	 *  Rob Campbell (Mozilla Corp.)
@@ -8395,26 +8373,26 @@ var Debugger =
 	 *  Kevin Decker
 	 *  Mike Ratcliffe (Comartis AG)
 	 *  Hernan Rodríguez Colmeiro
 	 *  Austin Andrews
 	 *  Christoph Dorn
 	 *  Steven Roussey (AppCenter Inc, Network54)
 	 *  Mihai Sucan (Mozilla Corp.)
 	 */
-
+	
 	"use strict";
-
+	
 	const {components, Cc, Ci, Cu} = __webpack_require__(35);
 	const { NetUtil } = __webpack_require__(45);
 	const DevToolsUtils = __webpack_require__(42);
-
+	
 	// The cache used in the `nsIURL` function.
 	const gNSURLStore = new Map();
-
+	
 	/**
 	 * Helper object for networking stuff.
 	 *
 	 * Most of the following functions have been taken from the Firebug source. They
 	 * have been modified to match the Firefox coding rules.
 	 */
 	var NetworkHelper = {
 	  /**
@@ -8434,17 +8412,17 @@ var Debugger =
 	    try {
 	      conv.charset = aCharset || "UTF-8";
 	      return conv.ConvertToUnicode(aText);
 	    }
 	    catch (ex) {
 	      return aText;
 	    }
 	  },
-
+	
 	  /**
 	   * Reads all available bytes from aStream and converts them to aCharset.
 	   *
 	   * @param nsIInputStream aStream
 	   * @param string aCharset
 	   * @returns string
 	   *          UTF-16 encoded string based on the content of aStream and aCharset.
 	   */
@@ -8454,115 +8432,115 @@ var Debugger =
 	    try {
 	      text = NetUtil.readInputStreamToString(aStream, aStream.available())
 	      return this.convertToUnicode(text, aCharset);
 	    }
 	    catch (err) {
 	      return text;
 	    }
 	  },
-
+	
 	   /**
 	   * Reads the posted text from aRequest.
 	   *
 	   * @param nsIHttpChannel aRequest
 	   * @param string aCharset
 	   *        The content document charset, used when reading the POSTed data.
 	   * @returns string or null
 	   *          Returns the posted string if it was possible to read from aRequest
 	   *          otherwise null.
 	   */
 	  readPostTextFromRequest: function NH_readPostTextFromRequest(aRequest, aCharset)
 	  {
 	    if (aRequest instanceof Ci.nsIUploadChannel) {
 	      let iStream = aRequest.uploadStream;
-
+	
 	      let isSeekableStream = false;
 	      if (iStream instanceof Ci.nsISeekableStream) {
 	        isSeekableStream = true;
 	      }
-
+	
 	      let prevOffset;
 	      if (isSeekableStream) {
 	        prevOffset = iStream.tell();
 	        iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
 	      }
-
+	
 	      // Read data from the stream.
 	      let text = this.readAndConvertFromStream(iStream, aCharset);
-
+	
 	      // Seek locks the file, so seek to the beginning only if necko hasn't
 	      // read it yet, since necko doesn't seek to 0 before reading (at lest
 	      // not till 459384 is fixed).
 	      if (isSeekableStream && prevOffset == 0) {
 	        iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
 	      }
 	      return text;
 	    }
 	    return null;
 	  },
-
+	
 	  /**
 	   * Reads the posted text from the page's cache.
 	   *
 	   * @param nsIDocShell aDocShell
 	   * @param string aCharset
 	   * @returns string or null
 	   *          Returns the posted string if it was possible to read from
 	   *          aDocShell otherwise null.
 	   */
 	  readPostTextFromPage: function NH_readPostTextFromPage(aDocShell, aCharset)
 	  {
 	    let webNav = aDocShell.QueryInterface(Ci.nsIWebNavigation);
 	    return this.readPostTextFromPageViaWebNav(webNav, aCharset);
 	  },
-
+	
 	  /**
 	   * Reads the posted text from the page's cache, given an nsIWebNavigation
 	   * object.
 	   *
 	   * @param nsIWebNavigation aWebNav
 	   * @param string aCharset
 	   * @returns string or null
 	   *          Returns the posted string if it was possible to read from
 	   *          aWebNav, otherwise null.
 	   */
 	  readPostTextFromPageViaWebNav:
 	  function NH_readPostTextFromPageViaWebNav(aWebNav, aCharset)
 	  {
 	    if (aWebNav instanceof Ci.nsIWebPageDescriptor) {
 	      let descriptor = aWebNav.currentDescriptor;
-
+	
 	      if (descriptor instanceof Ci.nsISHEntry && descriptor.postData &&
 	          descriptor instanceof Ci.nsISeekableStream) {
 	        descriptor.seek(NS_SEEK_SET, 0);
-
+	
 	        return this.readAndConvertFromStream(descriptor, aCharset);
 	      }
 	    }
 	    return null;
 	  },
-
+	
 	  /**
 	   * Gets the web appId that is associated with aRequest.
 	   *
 	   * @param nsIHttpChannel aRequest
 	   * @returns number|null
 	   *          The appId for the given request, if available.
 	   */
 	  getAppIdForRequest: function NH_getAppIdForRequest(aRequest)
 	  {
 	    try {
 	      return this.getRequestLoadContext(aRequest).appId;
 	    } catch (ex) {
 	      // request loadContent is not always available.
 	    }
 	    return null;
 	  },
-
+	
 	  /**
 	   * Gets the topFrameElement that is associated with aRequest. This
 	   * works in single-process and multiprocess contexts. It may cross
 	   * the content/chrome boundary.
 	   *
 	   * @param nsIHttpChannel aRequest
 	   * @returns nsIDOMElement|null
 	   *          The top frame element for the given request.
@@ -8571,158 +8549,158 @@ var Debugger =
 	  {
 	    try {
 	      return this.getRequestLoadContext(aRequest).topFrameElement;
 	    } catch (ex) {
 	      // request loadContent is not always available.
 	    }
 	    return null;
 	  },
-
+	
 	  /**
 	   * Gets the nsIDOMWindow that is associated with aRequest.
 	   *
 	   * @param nsIHttpChannel aRequest
 	   * @returns nsIDOMWindow or null
 	   */
 	  getWindowForRequest: function NH_getWindowForRequest(aRequest)
 	  {
 	    try {
 	      return this.getRequestLoadContext(aRequest).associatedWindow;
 	    } catch (ex) {
 	      // TODO: bug 802246 - getWindowForRequest() throws on b2g: there is no
 	      // associatedWindow property.
 	    }
 	    return null;
 	  },
-
+	
 	  /**
 	   * Gets the nsILoadContext that is associated with aRequest.
 	   *
 	   * @param nsIHttpChannel aRequest
 	   * @returns nsILoadContext or null
 	   */
 	  getRequestLoadContext: function NH_getRequestLoadContext(aRequest)
 	  {
 	    try {
 	      return aRequest.notificationCallbacks.getInterface(Ci.nsILoadContext);
 	    } catch (ex) { }
-
+	
 	    try {
 	      return aRequest.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
 	    } catch (ex) { }
-
+	
 	    return null;
 	  },
-
+	
 	  /**
 	   * Determines whether the request has been made for the top level document.
 	   *
 	   * @param nsIHttpChannel aRequest
 	   * @returns Boolean True if the request represents the top level document.
 	   */
 	  isTopLevelLoad: function(aRequest)
 	  {
 	    if (aRequest instanceof Ci.nsIChannel) {
 	      let loadInfo = aRequest.loadInfo;
 	      if (loadInfo && loadInfo.parentOuterWindowID == loadInfo.outerWindowID) {
 	        return (aRequest.loadFlags & Ci.nsIChannel.LOAD_DOCUMENT_URI);
 	      }
 	    }
-
+	
 	    return false;
 	  },
-
+	
 	  /**
 	   * Loads the content of aUrl from the cache.
 	   *
 	   * @param string aUrl
 	   *        URL to load the cached content for.
 	   * @param string aCharset
 	   *        Assumed charset of the cached content. Used if there is no charset
 	   *        on the channel directly.
 	   * @param function aCallback
 	   *        Callback that is called with the loaded cached content if available
 	   *        or null if something failed while getting the cached content.
 	   */
 	  loadFromCache: function NH_loadFromCache(aUrl, aCharset, aCallback)
 	  {
 	    let channel = NetUtil.newChannel({uri: aUrl, loadUsingSystemPrincipal: true});
-
+	
 	    // Ensure that we only read from the cache and not the server.
 	    channel.loadFlags = Ci.nsIRequest.LOAD_FROM_CACHE |
 	      Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE |
 	      Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
-
+	
 	    NetUtil.asyncFetch(
 	      channel,
 	      (aInputStream, aStatusCode, aRequest) => {
 	        if (!components.isSuccessCode(aStatusCode)) {
 	          aCallback(null);
 	          return;
 	        }
-
+	
 	        // Try to get the encoding from the channel. If there is none, then use
 	        // the passed assumed aCharset.
 	        let aChannel = aRequest.QueryInterface(Ci.nsIChannel);
 	        let contentCharset = aChannel.contentCharset || aCharset;
-
+	
 	        // Read the content of the stream using contentCharset as encoding.
 	        aCallback(this.readAndConvertFromStream(aInputStream, contentCharset));
 	      });
 	  },
-
+	
 	  /**
 	   * Parse a raw Cookie header value.
 	   *
 	   * @param string aHeader
 	   *        The raw Cookie header value.
 	   * @return array
 	   *         Array holding an object for each cookie. Each object holds the
 	   *         following properties: name and value.
 	   */
 	  parseCookieHeader: function NH_parseCookieHeader(aHeader)
 	  {
 	    let cookies = aHeader.split(";");
 	    let result = [];
-
+	
 	    cookies.forEach(function(aCookie) {
 	      let equal = aCookie.indexOf("=");
 	      let name = aCookie.substr(0, equal);
 	      let value = aCookie.substr(equal + 1);
 	      result.push({name: unescape(name.trim()),
 	                   value: unescape(value.trim())});
 	    });
-
+	
 	    return result;
 	  },
-
+	
 	  /**
 	   * Parse a raw Set-Cookie header value.
 	   *
 	   * @param string aHeader
 	   *        The raw Set-Cookie header value.
 	   * @return array
 	   *         Array holding an object for each cookie. Each object holds the
 	   *         following properties: name, value, secure (boolean), httpOnly
 	   *         (boolean), path, domain and expires (ISO date string).
 	   */
 	  parseSetCookieHeader: function NH_parseSetCookieHeader(aHeader)
 	  {
 	    let rawCookies = aHeader.split(/\r\n|\n|\r/);
 	    let cookies = [];
-
+	
 	    rawCookies.forEach(function(aCookie) {
 	      let equal = aCookie.indexOf("=");
 	      let name = unescape(aCookie.substr(0, equal).trim());
 	      let parts = aCookie.substr(equal + 1).split(";");
 	      let value = unescape(parts.shift().trim());
-
+	
 	      let cookie = {name: name, value: value};
-
+	
 	      parts.forEach(function(aPart) {
 	        let part = aPart.trim();
 	        if (part.toLowerCase() == "secure") {
 	          cookie.secure = true;
 	        }
 	        else if (part.toLowerCase() == "httponly") {
 	          cookie.httpOnly = true;
 	        }
@@ -8736,23 +8714,23 @@ var Debugger =
 	            try {
 	              pair[1] = pair[1].replace(/-/g, ' ');
 	              cookie.expires = new Date(pair[1]).toISOString();
 	            }
 	            catch (ex) { }
 	          }
 	        }
 	      });
-
+	
 	      cookies.push(cookie);
 	    });
-
+	
 	    return cookies;
 	  },
-
+	
 	  // This is a list of all the mime category maps jviereck could find in the
 	  // firebug code base.
 	  mimeCategoryMap: {
 	    "text/plain": "txt",
 	    "text/html": "html",
 	    "text/xml": "xml",
 	    "text/xsl": "txt",
 	    "text/xul": "txt",
@@ -8814,53 +8792,53 @@ var Debugger =
 	    "audio/wav": "media",
 	    "audio/x-wav": "media",
 	    "text/json": "json",
 	    "application/x-json": "json",
 	    "application/json-rpc": "json",
 	    "application/x-web-app-manifest+json": "json",
 	    "application/manifest+json": "json"
 	  },
-
+	
 	  /**
 	   * Check if the given MIME type is a text-only MIME type.
 	   *
 	   * @param string aMimeType
 	   * @return boolean
 	   */
 	  isTextMimeType: function NH_isTextMimeType(aMimeType)
 	  {
 	    if (aMimeType.indexOf("text/") == 0) {
 	      return true;
 	    }
-
+	
 	    // XML and JSON often come with custom MIME types, so in addition to the
 	    // standard "application/xml" and "application/json", we also look for
 	    // variants like "application/x-bigcorp+xml". For JSON we allow "+json" and
 	    // "-json" as suffixes.
 	    if (/^application\/\w+(?:[\.-]\w+)*(?:\+xml|[-+]json)$/.test(aMimeType)) {
 	      return true;
 	    }
-
+	
 	    let category = this.mimeCategoryMap[aMimeType] || null;
 	    switch (category) {
 	      case "txt":
 	      case "js":
 	      case "json":
 	      case "css":
 	      case "html":
 	      case "svg":
 	      case "xml":
 	        return true;
-
+	
 	      default:
 	        return false;
 	    }
 	  },
-
+	
 	  /**
 	   * Takes a securityInfo object of nsIRequest, the nsIRequest itself and
 	   * extracts security information from them.
 	   *
 	   * @param object securityInfo
 	   *        The securityInfo object of a request. If null channel is assumed
 	   *        to be insecure.
 	   * @param object httpActivity
@@ -8887,22 +8865,22 @@ var Debugger =
 	   *          If state == weak: Same as state == secure and
 	   *            - weaknessReasons: list of reasons that cause the request to be
 	   *                               considered weak. See getReasonsForWeakness.
 	   */
 	  parseSecurityInfo: function NH_parseSecurityInfo(securityInfo, httpActivity) {
 	    const info = {
 	      state: "insecure",
 	    };
-
+	
 	    // The request did not contain any security info.
 	    if (!securityInfo) {
 	      return info;
 	    }
-
+	
 	    /**
 	     * Different scenarios to consider here and how they are handled:
 	     * - request is HTTP, the connection is not secure
 	     *   => securityInfo is null
 	     *      => state === "insecure"
 	     *
 	     * - request is HTTPS, the connection is secure
 	     *   => .securityState has STATE_IS_SECURE flag
@@ -8924,27 +8902,27 @@ var Debugger =
 	     *   http://hg.mozilla.org/mozilla-central/annotate/def6ed9d1c1a/
 	     *   security/manager/ssl/nsNSSCallbacks.cpp#l1233
 	     * - request is mixed content (which makes no sense whatsoever)
 	     *   => .securityState has STATE_IS_BROKEN flag
 	     *   => .errorCode is NOT an NSS error code
 	     *   => .errorMessage is not available
 	     *      => state === "weak"
 	     */
-
+	
 	    securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
 	    securityInfo.QueryInterface(Ci.nsISSLStatusProvider);
-
+	
 	    const wpl = Ci.nsIWebProgressListener;
 	    const NSSErrorsService = Cc['@mozilla.org/nss_errors_service;1']
 	                               .getService(Ci.nsINSSErrorsService);
 	    const SSLStatus = securityInfo.SSLStatus;
 	    if (!NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
 	      const state = securityInfo.securityState;
-
+	
 	      let uri = null;
 	      if (httpActivity.channel && httpActivity.channel.URI) {
 	        uri = httpActivity.channel.URI;
 	      }
 	      if (uri && !uri.schemeIs("https") && !uri.schemeIs("wss")) {
 	        // it is not enough to look at the transport security info - schemes other than
 	        // https and wss are subject to downgrade/etc at the scheme level and should
 	        // always be considered insecure
@@ -8961,58 +8939,58 @@ var Debugger =
 	        // This was most likely an https request that was aborted before
 	        // validation. Return info as info.state = insecure.
 	        return info;
 	      } else {
 	        DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo",
 	          "Security state " + state + " has no known STATE_IS_* flags.");
 	        return info;
 	      }
-
+	
 	      // Cipher suite.
 	      info.cipherSuite = SSLStatus.cipherName;
-
+	
 	      // Protocol version.
 	      info.protocolVersion = this.formatSecurityProtocol(SSLStatus.protocolVersion);
-
+	
 	      // Certificate.
 	      info.cert = this.parseCertificateInfo(SSLStatus.serverCert);
-
+	
 	      // HSTS and HPKP if available.
 	      if (httpActivity.hostname) {
 	        const sss = Cc("@mozilla.org/ssservice;1")
 	                      .getService(Ci.nsISiteSecurityService);
-
-
+	
+	
 	        // SiteSecurityService uses different storage if the channel is
 	        // private. Thus we must give isSecureHost correct flags or we
 	        // might get incorrect results.
 	        let flags = (httpActivity.private) ?
 	                      Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
-
+	
 	        let host = httpActivity.hostname;
-
+	
 	        info.hsts = sss.isSecureHost(sss.HEADER_HSTS, host, flags);
 	        info.hpkp = sss.isSecureHost(sss.HEADER_HPKP, host, flags);
 	      } else {
 	        DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo",
 	          "Could not get HSTS/HPKP status as hostname is not available.");
 	        info.hsts = false;
 	        info.hpkp = false;
 	      }
-
+	
 	    } else {
 	      // The connection failed.
 	      info.state = "broken";
 	      info.errorMessage = securityInfo.errorMessage;
 	    }
-
+	
 	    return info;
 	  },
-
+	
 	  /**
 	   * Takes an nsIX509Cert and returns an object with certificate information.
 	   *
 	   * @param nsIX509Cert cert
 	   *        The certificate to extract the information from.
 	   * @return object
 	   *         An object with following format:
 	   *           {
@@ -9025,40 +9003,40 @@ var Debugger =
 	  parseCertificateInfo: function NH_parseCertifificateInfo(cert) {
 	    let info = {};
 	    if (cert) {
 	      info.subject = {
 	        commonName: cert.commonName,
 	        organization: cert.organization,
 	        organizationalUnit: cert.organizationalUnit,
 	      };
-
+	
 	      info.issuer = {
 	        commonName: cert.issuerCommonName,
 	        organization: cert.issuerOrganization,
 	        organizationUnit: cert.issuerOrganizationUnit,
 	      };
-
+	
 	      info.validity = {
 	        start: cert.validity.notBeforeLocalDay,
 	        end: cert.validity.notAfterLocalDay,
 	      };
-
+	
 	      info.fingerprint = {
 	        sha1: cert.sha1Fingerprint,
 	        sha256: cert.sha256Fingerprint,
 	      };
 	    } else {
 	      DevToolsUtils.reportException("NetworkHelper.parseCertificateInfo",
 	        "Secure connection established without certificate.");
 	    }
-
+	
 	    return info;
 	  },
-
+	
 	  /**
 	   * Takes protocolVersion of SSLStatus object and returns human readable
 	   * description.
 	   *
 	   * @param Number version
 	   *        One of nsISSLStatus version constants.
 	   * @return string
 	   *         One of TLSv1, TLSv1.1, TLSv1.2 if @param version is valid,
@@ -9073,119 +9051,119 @@ var Debugger =
 	      case Ci.nsISSLStatus.TLS_VERSION_1_2:
 	        return "TLSv1.2";
 	      default:
 	        DevToolsUtils.reportException("NetworkHelper.formatSecurityProtocol",
 	          "protocolVersion " + version + " is unknown.");
 	        return "Unknown";
 	    }
 	  },
-
+	
 	  /**
 	   * Takes the securityState bitfield and returns reasons for weak connection
 	   * as an array of strings.
 	   *
 	   * @param Number state
 	   *        nsITransportSecurityInfo.securityState.
 	   *
 	   * @return Array[String]
 	   *         List of weakness reasons. A subset of { cipher } where
 	   *         * cipher: The cipher suite is consireded to be weak (RC4).
 	   */
 	  getReasonsForWeakness: function NH_getReasonsForWeakness(state) {
 	    const wpl = Ci.nsIWebProgressListener;
-
+	
 	    // If there's non-fatal security issues the request has STATE_IS_BROKEN
 	    // flag set. See http://hg.mozilla.org/mozilla-central/file/44344099d119
 	    // /security/manager/ssl/nsNSSCallbacks.cpp#l1233
 	    let reasons = [];
-
+	
 	    if (state & wpl.STATE_IS_BROKEN) {
 	      let isCipher = state & wpl.STATE_USES_WEAK_CRYPTO;
-
+	
 	      if (isCipher) {
 	        reasons.push("cipher");
 	      }
-
+	
 	      if (!isCipher) {
 	        DevToolsUtils.reportException("NetworkHelper.getReasonsForWeakness",
 	          "STATE_IS_BROKEN without a known reason. Full state was: " + state);
 	      }
 	    }
-
+	
 	    return reasons;
 	  },
-
+	
 	  /**
 	   * Parse a url's query string into its components
 	   *
 	   * @param string aQueryString
 	   *        The query part of a url
 	   * @return array
 	   *         Array of query params {name, value}
 	   */
 	  parseQueryString: function(aQueryString) {
 	    // Make sure there's at least one param available.
 	    // Be careful here, params don't necessarily need to have values, so
 	    // no need to verify the existence of a "=".
 	    if (!aQueryString) {
 	      return;
 	    }
-
+	
 	    // Turn the params string into an array containing { name: value } tuples.
 	    let paramsArray = aQueryString.replace(/^[?&]/, "").split("&").map(e => {
 	      let param = e.split("=");
 	      return {
 	        name: param[0] ? NetworkHelper.convertToUnicode(unescape(param[0])) : "",
 	        value: param[1] ? NetworkHelper.convertToUnicode(unescape(param[1])) : ""
 	      }});
-
+	
 	    return paramsArray;
 	  },
-
+	
 	  /**
 	   * Helper for getting an nsIURL instance out of a string.
 	   */
 	  nsIURL: function(aUrl, aStore = gNSURLStore) {
 	    if (aStore.has(aUrl)) {
 	      return aStore.get(aUrl);
 	    }
-
+	
 	    var uri = Services.io.newURI(aUrl).QueryInterface(Ci.nsIURL);
 	    aStore.set(aUrl, uri);
 	    return uri;
 	  }
 	};
-
+	
 	for (let prop of Object.getOwnPropertyNames(NetworkHelper)) {
 	  exports[prop] = NetworkHelper[prop];
 	}
 
 
 /***/ },
 /* 48 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	const { Ci, Cc, Cr, CC } = __webpack_require__(35);
 	const { Services } = __webpack_require__(28);
 	const { dumpv } = __webpack_require__(42);
 	const EventEmitter = __webpack_require__(34);
 	const promise = __webpack_require__(40);
-
+	
 	const IOUtil = Cc("@mozilla.org/io-util;1").getService(Ci.nsIIOUtil);
-
+	
 	const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
 	          "nsIScriptableInputStream", "init");
-
+	
 	const BUFFER_SIZE = 0x8000;
-
+	
 	/**
 	 * This helper function (and its companion object) are used by bulk senders and
 	 * receivers to read and write data in and out of other streams.  Functions that
 	 * make use of this tool are passed to callers when it is time to read or write
 	 * bulk data.  It is highly recommended to use these copier functions instead of
 	 * the stream directly because the copier enforces the agreed upon length.
 	 * Since bulk mode reuses an existing stream, the sender and receiver must write
 	 * and read exactly the agreed upon amount of data, or else the entire transport
@@ -9213,107 +9191,107 @@ var Debugger =
 	 * @return Promise
 	 *         The promise is resolved when copying completes or rejected if any
 	 *         (unexpected) errors occur.
 	 */
 	function copyStream(input, output, length) {
 	  let copier = new StreamCopier(input, output, length);
 	  return copier.copy();
 	}
-
+	
 	function StreamCopier(input, output, length) {
 	  EventEmitter.decorate(this);
 	  this._id = StreamCopier._nextId++;
 	  this.input = input;
 	  // Save off the base output stream, since we know it's async as we've required
 	  this.baseAsyncOutput = output;
 	  if (IOUtil.outputStreamIsBuffered(output)) {
 	    this.output = output;
 	  } else {
 	    this.output = Cc("@mozilla.org/network/buffered-output-stream;1")
 	                  .createInstance(Ci.nsIBufferedOutputStream);
 	    this.output.init(output, BUFFER_SIZE);
 	  }
 	  this._length = length;
 	  this._amountLeft = length;
 	  this._deferred = promise.defer();
-
+	
 	  this._copy = this._copy.bind(this);
 	  this._flush = this._flush.bind(this);
 	  this._destroy = this._destroy.bind(this);
-
+	
 	  // Copy promise's then method up to this object.
 	  // Allows the copier to offer a promise interface for the simple succeed or
 	  // fail scenarios, but also emit events (due to the EventEmitter) for other
 	  // states, like progress.
 	  this.then = this._deferred.promise.then.bind(this._deferred.promise);
 	  this.then(this._destroy, this._destroy);
-
+	
 	  // Stream ready callback starts as |_copy|, but may switch to |_flush| at end
 	  // if flushing would block the output stream.
 	  this._streamReadyCallback = this._copy;
 	}
 	StreamCopier._nextId = 0;
-
+	
 	StreamCopier.prototype = {
-
+	
 	  copy: function() {
 	    // Dispatch to the next tick so that it's possible to attach a progress
 	    // event listener, even for extremely fast copies (like when testing).
 	    Services.tm.currentThread.dispatch(() => {
 	      try {
 	        this._copy();
 	      } catch (e) {
 	        this._deferred.reject(e);
 	      }
 	    }, 0);
 	    return this;
 	  },
-
+	
 	  _copy: function() {
 	    let bytesAvailable = this.input.available();
 	    let amountToCopy = Math.min(bytesAvailable, this._amountLeft);
 	    this._debug("Trying to copy: " + amountToCopy);
-
+	
 	    let bytesCopied;
 	    try {
 	      bytesCopied = this.output.writeFrom(this.input, amountToCopy);
 	    } catch (e) {
 	      if (e.result == Cr.NS_BASE_STREAM_WOULD_BLOCK) {
 	        this._debug("Base stream would block, will retry");
 	        this._debug("Waiting for output stream");
 	        this.baseAsyncOutput.asyncWait(this, 0, 0, Services.tm.currentThread);
 	        return;
 	      } else {
 	        throw e;
 	      }
 	    }
-
+	
 	    this._amountLeft -= bytesCopied;
 	    this._debug("Copied: " + bytesCopied +
 	                ", Left: " + this._amountLeft);
 	    this._emitProgress();
-
+	
 	    if (this._amountLeft === 0) {
 	      this._debug("Copy done!");
 	      this._flush();
 	      return;
 	    }
-
+	
 	    this._debug("Waiting for input stream");
 	    this.input.asyncWait(this, 0, 0, Services.tm.currentThread);
 	  },
-
+	
 	  _emitProgress: function() {
 	    this.emit("progress", {
 	      bytesSent: this._length - this._amountLeft,
 	      totalBytes: this._length
 	    });
 	  },
-
+	
 	  _flush: function() {
 	    try {
 	      this.output.flush();
 	    } catch (e) {
 	      if (e.result == Cr.NS_BASE_STREAM_WOULD_BLOCK ||
 	          e.result == Cr.NS_ERROR_FAILURE) {
 	        this._debug("Flush would block, will retry");
 	        this._streamReadyCallback = this._flush;
@@ -9321,43 +9299,43 @@ var Debugger =
 	        this.baseAsyncOutput.asyncWait(this, 0, 0, Services.tm.currentThread);
 	        return;
 	      } else {
 	        throw e;
 	      }
 	    }
 	    this._deferred.resolve();
 	  },
-
+	
 	  _destroy: function() {
 	    this._destroy = null;
 	    this._copy = null;
 	    this._flush = null;
 	    this.input = null;
 	    this.output = null;
 	  },
-
+	
 	  // nsIInputStreamCallback
 	  onInputStreamReady: function() {
 	    this._streamReadyCallback();
 	  },
-
+	
 	  // nsIOutputStreamCallback
 	  onOutputStreamReady: function() {
 	    this._streamReadyCallback();
 	  },
-
+	
 	  _debug: function(msg) {
 	    // Prefix logs with the copier ID, which makes logs much easier to
 	    // understand when several copiers are running simultaneously
 	    dumpv("Copier: " + this._id + " " + msg);
 	  }
-
-	};
-
+	
+	};
+	
 	/**
 	 * Read from a stream, one byte at a time, up to the next |delimiter|
 	 * character, but stopping if we've read |count| without finding it.  Reading
 	 * also terminates early if there are less than |count| bytes available on the
 	 * stream.  In that case, we only read as many bytes as the stream currently has
 	 * to offer.
 	 * TODO: This implementation could be removed if bug 984651 is fixed, which
 	 *       provides a native version of the same idea.
@@ -9369,59 +9347,59 @@ var Debugger =
 	 *        The max number of characters to read while searching.
 	 * @return string
 	 *         The data collected.  If the delimiter was found, this string will
 	 *         end with it.
 	 */
 	function delimitedRead(stream, delimiter, count) {
 	  dumpv("Starting delimited read for " + delimiter + " up to " +
 	        count + " bytes");
-
+	
 	  let scriptableStream;
 	  if (stream.readBytes) {
 	    scriptableStream = stream;
 	  } else {
 	    scriptableStream = new ScriptableInputStream(stream);
 	  }
-
+	
 	  let data = "";
-
+	
 	  // Don't exceed what's available on the stream
 	  count = Math.min(count, stream.available());
-
+	
 	  if (count <= 0) {
 	    return data;
 	  }
-
+	
 	  let char;
 	  while (char !== delimiter && count > 0) {
 	    char = scriptableStream.readBytes(1);
 	    count--;
 	    data += char;
 	  }
-
+	
 	  return data;
 	}
-
+	
 	module.exports = {
 	  copyStream: copyStream,
 	  delimitedRead: delimitedRead
 	};
 
 
 /***/ },
 /* 49 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	"use strict";
-
+	
 	/**
 	 * Packets contain read / write functionality for the different packet types
 	 * supported by the debugging protocol, so that a transport can focus on
 	 * delivery and queue management without worrying too much about the specific
 	 * packet types.
 	 *
 	 * They are intended to be "one use only", so a new packet should be
 	 * instantiated for each incoming or outgoing packet.
@@ -9431,206 +9409,206 @@ var Debugger =
 	 *     Called when the input stream has data to read
 	 *   * write(stream)
 	 *     Called when the output stream is ready to write
 	 *   * get done()
 	 *     Returns true once the packet is done being read / written
 	 *   * destroy()
 	 *     Called to clean up at the end of use
 	 */
-
+	
 	const { Cc, Ci, Cu } = __webpack_require__(35);
 	const DevToolsUtils = __webpack_require__(42);
 	const { dumpn, dumpv } = DevToolsUtils;
 	const StreamUtils = __webpack_require__(48);
 	const promise = __webpack_require__(40);
-
+	
 	/*DevToolsUtils.defineLazyGetter(this, "unicodeConverter", () => {
 	  const unicodeConverter = Cc("@mozilla.org/intl/scriptableunicodeconverter")
 	                           .createInstance(Ci.nsIScriptableUnicodeConverter);
 	  unicodeConverter.charset = "UTF-8";
 	  return unicodeConverter;
 	});*/
 	const utf8 = __webpack_require__(50);
-
+	
 	// The transport's previous check ensured the header length did not exceed 20
 	// characters.  Here, we opt for the somewhat smaller, but still large limit of
 	// 1 TiB.
 	const PACKET_LENGTH_MAX = Math.pow(2, 40);
-
+	
 	/**
 	 * A generic Packet processing object (extended by two subtypes below).
 	 */
 	function Packet(transport) {
 	  this._transport = transport;
 	  this._length = 0;
 	}
-
+	
 	/**
 	 * Attempt to initialize a new Packet based on the incoming packet header we've
 	 * received so far.  We try each of the types in succession, trying JSON packets
 	 * first since they are much more common.
 	 * @param header string
 	 *        The packet header string to attempt parsing.
 	 * @param transport DebuggerTransport
 	 *        The transport instance that will own the packet.
 	 * @return Packet
 	 *         The parsed packet of the matching type, or null if no types matched.
 	 */
 	Packet.fromHeader = function(header, transport) {
 	  return JSONPacket.fromHeader(header, transport) ||
 	         BulkPacket.fromHeader(header, transport);
 	};
-
+	
 	Packet.prototype = {
-
+	
 	  get length() {
 	    return this._length;
 	  },
-
+	
 	  set length(length) {
 	    if (length > PACKET_LENGTH_MAX) {
 	      throw Error("Packet length " + length + " exceeds the max length of " +
 	                  PACKET_LENGTH_MAX);
 	    }
 	    this._length = length;
 	  },
-
+	
 	  destroy: function() {
 	    this._transport = null;
 	  }
-
-	};
-
+	
+	};
+	
 	exports.Packet = Packet;
-
+	
 	/**
 	 * With a JSON packet (the typical packet type sent via the transport), data is
 	 * transferred as a JSON packet serialized into a string, with the string length
 	 * prepended to the packet, followed by a colon ([length]:[packet]). The
 	 * contents of the JSON packet are specified in the Remote Debugging Protocol
 	 * specification.
 	 * @param transport DebuggerTransport
 	 *        The transport instance that will own the packet.
 	 */
 	function JSONPacket(transport) {
 	  Packet.call(this, transport);
 	  this._data = "";
 	  this._done = false;
 	}
-
+	
 	/**
 	 * Attempt to initialize a new JSONPacket based on the incoming packet header
 	 * we've received so far.
 	 * @param header string
 	 *        The packet header string to attempt parsing.
 	 * @param transport DebuggerTransport
 	 *        The transport instance that will own the packet.
 	 * @return JSONPacket
 	 *         The parsed packet, or null if it's not a match.
 	 */
 	JSONPacket.fromHeader = function(header, transport) {
 	  let match = this.HEADER_PATTERN.exec(header);
-
+	
 	  if (!match) {
 	    return null;
 	  }
-
+	
 	  dumpv("Header matches JSON packet");
 	  let packet = new JSONPacket(transport);
 	  packet.length = +match[1];
 	  return packet;
 	};
-
+	
 	JSONPacket.HEADER_PATTERN = /^(\d+):$/;
-
+	
 	JSONPacket.prototype = Object.create(Packet.prototype);
-
+	
 	Object.defineProperty(JSONPacket.prototype, "object", {
 	  /**
 	   * Gets the object (not the serialized string) being read or written.
 	   */
 	  get: function() { return this._object; },
-
+	
 	  /**
 	   * Sets the object to be sent when write() is called.
 	   */
 	  set: function(object) {
 	    this._object = object;
 	    let data = JSON.stringify(object);
 	    this._data = data;
 	    this.length = this._data.length;
 	  }
 	});
-
+	
 	JSONPacket.prototype.read = function(stream, scriptableStream) {
 	  dumpv("Reading JSON packet");
-
+	
 	  // Read in more packet data.
 	  this._readData(stream, scriptableStream);
-
+	
 	  if (!this.done) {
 	    // Don't have a complete packet yet.
 	    return;
 	  }
-
+	
 	  let json = this._data;
 	  try {
 	    json = utf8.decode(json);
 	    this._object = JSON.parse(json);
 	  } catch(e) {
 	    let msg = "Error parsing incoming packet: " + json + " (" + e +
 	              " - " + e.stack + ")";
 	    if (console.error) {
 	      console.error(msg);
 	    }
 	    dumpn(msg);
 	    return;
 	  }
-
+	
 	  this._transport._onJSONObjectReady(this._object);
 	}
-
+	
 	JSONPacket.prototype._readData = function(stream, scriptableStream) {
 	  if (!scriptableStream) {
 	    scriptableStream = stream;
 	  }
 	  if (dumpv.wantVerbose) {
 	    dumpv("Reading JSON data: _l: " + this.length + " dL: " +
 	          this._data.length + " sA: " + stream.available());
 	  }
 	  let bytesToRead = Math.min(this.length - this._data.length,
 	                             stream.available());
 	  this._data += scriptableStream.readBytes(bytesToRead);
 	  this._done = this._data.length === this.length;
 	}
-
+	
 	JSONPacket.prototype.write = function(stream) {
 	  dumpv("Writing JSON packet");
-
+	
 	  if (this._outgoing === undefined) {
 	    // Format the serialized packet to a buffer
 	    this._outgoing = this.length + ":" + this._data;
 	  }
-
+	
 	  let written = stream.write(this._outgoing, this._outgoing.length);
 	  this._outgoing = this._outgoing.slice(written);
 	  this._done = !this._outgoing.length;
 	}
-
+	
 	Object.defineProperty(JSONPacket.prototype, "done", {
 	  get: function() { return this._done; }
 	});
-
+	
 	JSONPacket.prototype.toString = function() {
 	  return JSON.stringify(this._object, null, 2);
 	}
-
+	
 	exports.JSONPacket = JSONPacket;
-
+	
 	/**
 	 * With a bulk packet, data is transferred by temporarily handing over the
 	 * transport's input or output stream to the application layer for writing data
 	 * directly.  This can be much faster for large data sets, and avoids various
 	 * stages of copies and data duplication inherent in the JSON packet type.  The
 	 * bulk packet looks like:
 	 *
 	 * bulk [actor] [type] [length]:[data]
@@ -9641,226 +9619,226 @@ var Debugger =
 	 * @param transport DebuggerTransport
 	 *        The transport instance that will own the packet.
 	 */
 	function BulkPacket(transport) {
 	  Packet.call(this, transport);
 	  this._done = false;
 	  this._readyForWriting = promise.defer();
 	}
-
+	
 	/**
 	 * Attempt to initialize a new BulkPacket based on the incoming packet header
 	 * we've received so far.
 	 * @param header string
 	 *        The packet header string to attempt parsing.
 	 * @param transport DebuggerTransport
 	 *        The transport instance that will own the packet.
 	 * @return BulkPacket
 	 *         The parsed packet, or null if it's not a match.
 	 */
 	BulkPacket.fromHeader = function(header, transport) {
 	  let match = this.HEADER_PATTERN.exec(header);
-
+	
 	  if (!match) {
 	    return null;
 	  }
-
+	
 	  dumpv("Header matches bulk packet");
 	  let packet = new BulkPacket(transport);
 	  packet.header = {
 	    actor: match[1],
 	    type: match[2],
 	    length: +match[3]
 	  };
 	  return packet;
 	};
-
+	
 	BulkPacket.HEADER_PATTERN = /^bulk ([^: ]+) ([^: ]+) (\d+):$/;
-
+	
 	BulkPacket.prototype = Object.create(Packet.prototype);
-
+	
 	BulkPacket.prototype.read = function(stream) {
 	  dumpv("Reading bulk packet, handing off input stream");
-
+	
 	  // Temporarily pause monitoring of the input stream
 	  this._transport.pauseIncoming();
-
+	
 	  let deferred = promise.defer();
-
+	
 	  this._transport._onBulkReadReady({
 	    actor: this.actor,
 	    type: this.type,
 	    length: this.length,
 	    copyTo: (output) => {
 	      dumpv("CT length: " + this.length);
 	      let copying = StreamUtils.copyStream(stream, output, this.length);
 	      deferred.resolve(copying);
 	      return copying;
 	    },
 	    stream: stream,
 	    done: deferred
 	  });
-
+	
 	  // Await the result of reading from the stream
 	  deferred.promise.then(() => {
 	    dumpv("onReadDone called, ending bulk mode");
 	    this._done = true;
 	    this._transport.resumeIncoming();
 	  }, this._transport.close);
-
+	
 	  // Ensure this is only done once
 	  this.read = () => {
 	    throw new Error("Tried to read() a BulkPacket's stream multiple times.");
 	  };
 	}
-
+	
 	BulkPacket.prototype.write = function(stream) {
 	  dumpv("Writing bulk packet");
-
+	
 	  if (this._outgoingHeader === undefined) {
 	    dumpv("Serializing bulk packet header");
 	    // Format the serialized packet header to a buffer
 	    this._outgoingHeader = "bulk " + this.actor + " " + this.type + " " +
 	                           this.length + ":";
 	  }
-
+	
 	  // Write the header, or whatever's left of it to write.
 	  if (this._outgoingHeader.length) {
 	    dumpv("Writing bulk packet header");
 	    let written = stream.write(this._outgoingHeader,
 	                               this._outgoingHeader.length);
 	    this._outgoingHeader = this._outgoingHeader.slice(written);
 	    return;
 	  }
-
+	
 	  dumpv("Handing off output stream");
-
+	
 	  // Temporarily pause the monitoring of the output stream
 	  this._transport.pauseOutgoing();
-
+	
 	  let deferred = promise.defer();
-
+	
 	  this._readyForWriting.resolve({
 	    copyFrom: (input) => {
 	      dumpv("CF length: " + this.length);
 	      let copying = StreamUtils.copyStream(input, stream, this.length);
 	      deferred.resolve(copying);
 	      return copying;
 	    },
 	    stream: stream,
 	    done: deferred
 	  });
-
+	
 	  // Await the result of writing to the stream
 	  deferred.promise.then(() => {
 	    dumpv("onWriteDone called, ending bulk mode");
 	    this._done = true;
 	    this._transport.resumeOutgoing();
 	  }, this._transport.close);
-
+	
 	  // Ensure this is only done once
 	  this.write = () => {
 	    throw new Error("Tried to write() a BulkPacket's stream multiple times.");
 	  };
 	}
-
+	
 	Object.defineProperty(BulkPacket.prototype, "streamReadyForWriting", {
 	  get: function() {
 	    return this._readyForWriting.promise;
 	  }
 	});
-
+	
 	Object.defineProperty(BulkPacket.prototype, "header", {
 	  get: function() {
 	    return {
 	      actor: this.actor,
 	      type: this.type,
 	      length: this.length
 	    };
 	  },
-
+	
 	  set: function(header) {
 	    this.actor = header.actor;
 	    this.type = header.type;
 	    this.length = header.length;
 	  },
 	});
-
+	
 	Object.defineProperty(BulkPacket.prototype, "done", {
 	  get: function() { return this._done; },
 	});
-
-
+	
+	
 	BulkPacket.prototype.toString = function() {
 	  return "Bulk: " + JSON.stringify(this.header, null, 2);
 	}
-
+	
 	exports.BulkPacket = BulkPacket;
-
+	
 	/**
 	 * RawPacket is used to test the transport's error handling of malformed
 	 * packets, by writing data directly onto the stream.
 	 * @param transport DebuggerTransport
 	 *        The transport instance that will own the packet.
 	 * @param data string
 	 *        The raw string to send out onto the stream.
 	 */
 	function RawPacket(transport, data) {
 	  Packet.call(this, transport);
 	  this._data = data;
 	  this.length = data.length;
 	  this._done = false;
 	}
-
+	
 	RawPacket.prototype = Object.create(Packet.prototype);
-
+	
 	RawPacket.prototype.read = function(stream) {
 	  // This hasn't yet been needed for testing.
 	  throw Error("Not implmented.");
 	}
-
+	
 	RawPacket.prototype.write = function(stream) {
 	  let written = stream.write(this._data, this._data.length);
 	  this._data = this._data.slice(written);
 	  this._done = !this._data.length;
 	}
-
+	
 	Object.defineProperty(RawPacket.prototype, "done", {
 	  get: function() { return this._done; }
 	});
-
+	
 	exports.RawPacket = RawPacket;
 
 
 /***/ },
 /* 50 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/utf8js v2.0.0 by @mathias */
 	;(function(root) {
-
+	
 		// Detect free variables `exports`
 		var freeExports = typeof exports == 'object' && exports;
-
+	
 		// Detect free variable `module`
 		var freeModule = typeof module == 'object' && module &&
 			module.exports == freeExports && module;
-
+	
 		// Detect free variable `global`, from Node.js or Browserified code,
 		// and use it as `root`
 		var freeGlobal = typeof global == 'object' && global;
 		if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
 			root = freeGlobal;
 		}
-
+	
 		/*--------------------------------------------------------------------------*/
-
+	
 		var stringFromCharCode = String.fromCharCode;
-
+	
 		// Taken from https://mths.be/punycode
 		function ucs2decode(string) {
 			var output = [];
 			var counter = 0;
 			var length = string.length;
 			var value;
 			var extra;
 			while (counter < length) {
@@ -9877,17 +9855,17 @@ var Debugger =
 						counter--;
 					}
 				} else {
 					output.push(value);
 				}
 			}
 			return output;
 		}
-
+	
 		// Taken from https://mths.be/punycode
 		function ucs2encode(array) {
 			var length = array.length;
 			var index = -1;
 			var value;
 			var output = '';
 			while (++index < length) {
 				value = array[index];
@@ -9895,31 +9873,31 @@ var Debugger =
 					value -= 0x10000;
 					output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
 					value = 0xDC00 | value & 0x3FF;
 				}
 				output += stringFromCharCode(value);
 			}
 			return output;
 		}
-
+	
 		function checkScalarValue(codePoint) {
 			if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
 				throw Error(
 					'Lone surrogate U+' + codePoint.toString(16).toUpperCase() +
 					' is not a scalar value'
 				);
 			}
 		}
 		/*--------------------------------------------------------------------------*/
-
+	
 		function createByte(codePoint, shift) {
 			return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
 		}
-
+	
 		function encodeCodePoint(codePoint) {
 			if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
 				return stringFromCharCode(codePoint);
 			}
 			var symbol = '';
 			if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
 				symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
 			}
@@ -9931,134 +9909,134 @@ var Debugger =
 			else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
 				symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
 				symbol += createByte(codePoint, 12);
 				symbol += createByte(codePoint, 6);
 			}
 			symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
 			return symbol;
 		}
-
+	
 		function utf8encode(string) {
 			var codePoints = ucs2decode(string);
 			var length = codePoints.length;
 			var index = -1;
 			var codePoint;
 			var byteString = '';
 			while (++index < length) {
 				codePoint = codePoints[index];
 				byteString += encodeCodePoint(codePoint);
 			}
 			return byteString;
 		}
-
+	
 		/*--------------------------------------------------------------------------*/
-
+	
 		function readContinuationByte() {
 			if (byteIndex >= byteCount) {
 				throw Error('Invalid byte index');
 			}
-
+	
 			var continuationByte = byteArray[byteIndex] & 0xFF;
 			byteIndex++;
-
+	
 			if ((continuationByte & 0xC0) == 0x80) {
 				return continuationByte & 0x3F;
 			}
-
+	
 			// If we end up here, it’s not a continuation byte
 			throw Error('Invalid continuation byte');
 		}
-
+	
 		function decodeSymbol() {
 			var byte1;
 			var byte2;
 			var byte3;
 			var byte4;
 			var codePoint;
-
+	
 			if (byteIndex > byteCount) {
 				throw Error('Invalid byte index');
 			}
-
+	
 			if (byteIndex == byteCount) {
 				return false;
 			}
-
+	
 			// Read first byte
 			byte1 = byteArray[byteIndex] & 0xFF;
 			byteIndex++;
-
+	
 			// 1-byte sequence (no continuation bytes)
 			if ((byte1 & 0x80) == 0) {
 				return byte1;
 			}
-
+	
 			// 2-byte sequence
 			if ((byte1 & 0xE0) == 0xC0) {
 				var byte2 = readContinuationByte();
 				codePoint = ((byte1 & 0x1F) << 6) | byte2;
 				if (codePoint >= 0x80) {
 					return codePoint;
 				} else {
 					throw Error('Invalid continuation byte');
 				}
 			}
-
+	
 			// 3-byte sequence (may include unpaired surrogates)
 			if ((byte1 & 0xF0) == 0xE0) {
 				byte2 = readContinuationByte();
 				byte3 = readContinuationByte();
 				codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
 				if (codePoint >= 0x0800) {
 					checkScalarValue(codePoint);
 					return codePoint;
 				} else {
 					throw Error('Invalid continuation byte');
 				}
 			}
-
+	
 			// 4-byte sequence
 			if ((byte1 & 0xF8) == 0xF0) {
 				byte2 = readContinuationByte();
 				byte3 = readContinuationByte();
 				byte4 = readContinuationByte();
 				codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |
 					(byte3 << 0x06) | byte4;
 				if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
 					return codePoint;
 				}
 			}
-
+	
 			throw Error('Invalid UTF-8 detected');
 		}
-
+	
 		var byteArray;
 		var byteCount;
 		var byteIndex;
 		function utf8decode(byteString) {
 			byteArray = ucs2decode(byteString);
 			byteCount = byteArray.length;
 			byteIndex = 0;
 			var codePoints = [];
 			var tmp;
 			while ((tmp = decodeSymbol()) !== false) {
 				codePoints.push(tmp);
 			}
 			return ucs2encode(codePoints);
 		}
-
+	
 		/*--------------------------------------------------------------------------*/
-
+	
 		var utf8 = {
 			'version': '2.0.0',
 			'encode': utf8encode,
 			'decode': utf8decode
 		};
-
+	
 		// Some AMD build optimizers, like r.js, check for specific condition patterns
 		// like the following:
 		if (
 			true
 		) {
 			!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
 				return utf8;
 			}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
@@ -10070,62 +10048,62 @@ var Debugger =
 				var hasOwnProperty = object.hasOwnProperty;
 				for (var key in utf8) {
 					hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);
 				}
 			}
 		} else { // in Rhino or a web browser
 			root.utf8 = utf8;
 		}
-
+	
 	}(this));
-
+	
 	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(51)(module), (function() { return this; }())))
 
 /***/ },
 /* 51 */
 /***/ function(module, exports) {
 
-	module.exports = function(module) {
-		if(!module.webpackPolyfill) {
-			module.deprecate = function() {};
-			module.paths = [];
-			// module.parent = undefined by default
-			module.children = [];
-			module.webpackPolyfill = 1;
-		}
-		return module;
-	}
+	module.exports = function(module) {
+		if(!module.webpackPolyfill) {
+			module.deprecate = function() {};
+			module.paths = [];
+			// module.parent = undefined by default
+			module.children = [];
+			module.webpackPolyfill = 1;
+		}
+		return module;
+	}
 
 
 /***/ },
 /* 52 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/utf8js v2.0.0 by @mathias */
 	;(function(root) {
-
+	
 		// Detect free variables `exports`
 		var freeExports = typeof exports == 'object' && exports;
-
+	
 		// Detect free variable `module`
 		var freeModule = typeof module == 'object' && module &&
 			module.exports == freeExports && module;
-
+	
 		// Detect free variable `global`, from Node.js or Browserified code,
 		// and use it as `root`
 		var freeGlobal = typeof global == 'object' && global;
 		if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
 			root = freeGlobal;
 		}
-
+	
 		/*--------------------------------------------------------------------------*/
-
+	
 		var stringFromCharCode = String.fromCharCode;
-
+	
 		// Taken from https://mths.be/punycode
 		function ucs2decode(string) {
 			var output = [];
 			var counter = 0;
 			var length = string.length;
 			var value;
 			var extra;
 			while (counter < length) {
@@ -10142,17 +10120,17 @@ var Debugger =
 						counter--;
 					}
 				} else {
 					output.push(value);
 				}
 			}
 			return output;
 		}
-
+	
 		// Taken from https://mths.be/punycode
 		function ucs2encode(array) {
 			var length = array.length;
 			var index = -1;
 			var value;
 			var output = '';
 			while (++index < length) {
 				value = array[index];
@@ -10160,31 +10138,31 @@ var Debugger =
 					value -= 0x10000;
 					output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
 					value = 0xDC00 | value & 0x3FF;
 				}
 				output += stringFromCharCode(value);
 			}
 			return output;
 		}
-
+	
 		function checkScalarValue(codePoint) {
 			if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
 				throw Error(
 					'Lone surrogate U+' + codePoint.toString(16).toUpperCase() +
 					' is not a scalar value'
 				);
 			}
 		}
 		/*--------------------------------------------------------------------------*/
-
+	
 		function createByte(codePoint, shift) {
 			return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
 		}
-
+	
 		function encodeCodePoint(codePoint) {
 			if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
 				return stringFromCharCode(codePoint);
 			}
 			var symbol = '';
 			if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
 				symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
 			}
@@ -10196,134 +10174,134 @@ var Debugger =
 			else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
 				symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
 				symbol += createByte(codePoint, 12);
 				symbol += createByte(codePoint, 6);
 			}
 			symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
 			return symbol;
 		}
-
+	
 		function utf8encode(string) {
 			var codePoints = ucs2decode(string);
 			var length = codePoints.length;
 			var index = -1;
 			var codePoint;
 			var byteString = '';
 			while (++index < length) {
 				codePoint = codePoints[index];
 				byteString += encodeCodePoint(codePoint);
 			}
 			return byteString;
 		}
-
+	
 		/*--------------------------------------------------------------------------*/
-
+	
 		function readContinuationByte() {
 			if (byteIndex >= byteCount) {
 				throw Error('Invalid byte index');
 			}
-
+	
 			var continuationByte = byteArray[byteIndex] & 0xFF;
 			byteIndex++;
-
+	
 			if ((continuationByte & 0xC0) == 0x80) {
 				return continuationByte & 0x3F;
 			}
-
+	
 			// If we end up here, it’s not a continuation byte
 			throw Error('Invalid continuation byte');
 		}
-
+	
 		function decodeSymbol() {
 			var byte1;
 			var byte2;
 			var byte3;
 			var byte4;
 			var codePoint;
-
+	
 			if (byteIndex > byteCount) {
 				throw Error('Invalid byte index');
 			}
-
+	
 			if (byteIndex == byteCount) {
 				return false;
 			}
-
+	
 			// Read first byte
 			byte1 = byteArray[byteIndex] & 0xFF;
 			byteIndex++;
-
+	
 			// 1-byte sequence (no continuation bytes)
 			if ((byte1 & 0x80) == 0) {
 				return byte1;
 			}
-
+	
 			// 2-byte sequence
 			if ((byte1 & 0xE0) == 0xC0) {
 				var byte2 = readContinuationByte();
 				codePoint = ((byte1 & 0x1F) << 6) | byte2;
 				if (codePoint >= 0x80) {
 					return codePoint;
 				} else {
 					throw Error('Invalid continuation byte');
 				}
 			}
-
+	
 			// 3-byte sequence (may include unpaired surrogates)
 			if ((byte1 & 0xF0) == 0xE0) {
 				byte2 = readContinuationByte();
 				byte3 = readContinuationByte();
 				codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
 				if (codePoint >= 0x0800) {
 					checkScalarValue(codePoint);
 					return codePoint;
 				} else {
 					throw Error('Invalid continuation byte');
 				}
 			}
-
+	
 			// 4-byte sequence
 			if ((byte1 & 0xF8) == 0xF0) {
 				byte2 = readContinuationByte();
 				byte3 = readContinuationByte();
 				byte4 = readContinuationByte();
 				codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |
 					(byte3 << 0x06) | byte4;
 				if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
 					return codePoint;
 				}
 			}
-
+	
 			throw Error('Invalid UTF-8 detected');
 		}
-
+	
 		var byteArray;
 		var byteCount;
 		var byteIndex;
 		function utf8decode(byteString) {
 			byteArray = ucs2decode(byteString);
 			byteCount = byteArray.length;
 			byteIndex = 0;
 			var codePoints = [];
 			var tmp;
 			while ((tmp = decodeSymbol()) !== false) {
 				codePoints.push(tmp);
 			}
 			return ucs2encode(codePoints);
 		}
-
+	
 		/*--------------------------------------------------------------------------*/
-
+	
 		var utf8 = {
 			'version': '2.0.0',
 			'encode': utf8encode,
 			'decode': utf8decode
 		};
-
+	
 		// Some AMD build optimizers, like r.js, check for specific condition patterns
 		// like the following:
 		if (
 			true
 		) {
 			!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
 				return utf8;
 			}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
@@ -10335,46 +10313,46 @@ var Debugger =
 				var hasOwnProperty = object.hasOwnProperty;
 				for (var key in utf8) {
 					hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);
 				}
 			}
 		} else { // in Rhino or a web browser
 			root.utf8 = utf8;
 		}
-
+	
 	}(this));
-
+	
 	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(51)(module), (function() { return this; }())))
 
 /***/ },
 /* 53 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 	/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 	/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+	
 	const { Ci, Cu, components } = __webpack_require__(35);
 	const { Services } = __webpack_require__(28);
 	const DevToolsUtils = __webpack_require__(42);
-
+	
 	// WARNING I swapped the sync one for the async one here
 	// const promise = require("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise;
 	const promise = __webpack_require__(40);
-
+	
 	const events = __webpack_require__(54);
 	const { WebConsoleClient } = __webpack_require__(56);
 	/* const { DebuggerSocket } = require("../shared/security/socket");*/
 	/* const Authentication = require("../shared/security/auth");*/
-
+	
 	const noop = () => {};
-
+	
 	/**
 	 * TODO: Get rid of this API in favor of EventTarget (bug 1042642)
 	 *
 	 * Add simple event notification to a prototype object. Any object that has
 	 * some use for event notifications or the observer pattern in general can be
 	 * augmented with the necessary facilities by passing its prototype to this
 	 * function.
 	 *
@@ -10391,118 +10369,118 @@ var Debugger =
 	   *        Called when the event is fired. If the same listener
 	   *        is added more than once, it will be called once per
 	   *        addListener call.
 	   */
 	  aProto.addListener = function(aName, aListener) {
 	    if (typeof aListener != "function") {
 	      throw TypeError("Listeners must be functions.");
 	    }
-
+	
 	    if (!this._listeners) {
 	      this._listeners = {};
 	    }
-
+	
 	    this._getListeners(aName).push(aListener);
 	  };
-
+	
 	  /**
 	   * Add a listener to the event source for a given event. The
 	   * listener will be removed after it is called for the first time.
 	   *
 	   * @param aName string
 	   *        The event to listen for.
 	   * @param aListener function
 	   *        Called when the event is fired.
 	   */
 	  aProto.addOneTimeListener = function(aName, aListener) {
 	    let l = (...args) => {
 	      this.removeListener(aName, l);
 	      aListener.apply(null, args);
 	    };
 	    this.addListener(aName, l);
 	  };
-
+	
 	  /**
 	   * Remove a listener from the event source previously added with
 	   * addListener().
 	   *
 	   * @param aName string
 	   *        The event name used during addListener to add the listener.
 	   * @param aListener function
 	   *        The callback to remove. If addListener was called multiple
 	   *        times, all instances will be removed.
 	   */
 	  aProto.removeListener = function(aName, aListener) {
 	    if (!this._listeners || (aListener && !this._listeners[aName])) {
 	      return;
 	    }
-
+	
 	    if (!aListener) {
 	      this._listeners[aName] = [];
 	    }
 	    else {
 	      this._listeners[aName] =
 	        this._listeners[aName].filter(function(l) { return l != aListener; });
 	    }
 	  };
-
+	
 	  /**
 	   * Returns the listeners for the specified event name. If none are defined it
 	   * initializes an empty list and returns that.
 	   *
 	   * @param aName string
 	   *        The event name.
 	   */
 	  aProto._getListeners = function(aName) {
 	    if (aName in this._listeners) {
 	      return this._listeners[aName];
 	    }
 	    this._listeners[aName] = [];
 	    return this._listeners[aName];
 	  };
-
+	
 	  /**
 	   * Notify listeners of an event.
 	   *
 	   * @param aName string
 	   *        The event to fire.
 	   * @param arguments
 	   *        All arguments will be passed along to the listeners,
 	   *        including the name argument.
 	   */
 	  aProto.emit = function() {
 	    if (!this._listeners) {
 	      return;
 	    }
-
+	
 	    let name = arguments[0];
 	    let listeners = this._getListeners(name).slice(0);
-
+	
 	    for (let listener of listeners) {
 	      try {
 	        listener.apply(null, arguments);
 	      } catch (e) {
 	        // Prevent a bad listener from interfering with the others.
 	        DevToolsUtils.reportException("notify event '" + name + "'", e);
 	      }
 	    }
 	  };
 	}
-
+	
 	/**
 	 * Set of protocol messages that affect thread state, and the
 	 * state the actor is in after each message.
 	 */
 	const ThreadStateTypes = {
 	  "paused": "paused",
 	  "resumed": "attached",
 	  "detached": "detached"
 	};
-
+	
 	/**
 	 * Set of protocol messages that are sent by the server without a prior request
 	 * by the client.
 	 */
 	const UnsolicitedNotifications = {
 	  "consoleAPICall": "consoleAPICall",
 	  "eventNotification": "eventNotification",
 	  "fileActivity": "fileActivity",
@@ -10527,63 +10505,63 @@ var Debugger =
 	  "appOpen": "appOpen",
 	  "appClose": "appClose",
 	  "appInstall": "appInstall",
 	  "appUninstall": "appUninstall",
 	  "evaluationResult": "evaluationResult",
 	  "newSource": "newSource",
 	  "updatedSource": "updatedSource",
 	};
-
+	
 	/**
 	 * Set of pause types that are sent by the server and not as an immediate
 	 * response to a client request.
 	 */
 	const UnsolicitedPauses = {
 	  "resumeLimit": "resumeLimit",
 	  "debuggerStatement": "debuggerStatement",
 	  "breakpoint": "breakpoint",
 	  "DOMEvent": "DOMEvent",
 	  "watchpoint": "watchpoint",
 	  "exception": "exception"
 	};
-
+	
 	/**
 	 * Creates a client for the remote debugging protocol server. This client
 	 * provides the means to communicate with the server and exchange the messages
 	 * required by the protocol in a traditional JavaScript API.
 	 */
 	const DebuggerClient = exports.DebuggerClient = function(aTransport)
 	{
 	  this._transport = aTransport;
 	  this._transport.hooks = this;
-
+	
 	  // Map actor ID to client instance for each actor type.
 	  this._clients = new Map();
-
+	
 	  this._pendingRequests = new Map();
 	  this._activeRequests = new Map();
 	  this._eventsEnabled = true;
-
+	
 	  this.traits = {};
-
+	
 	  this.request = this.request.bind(this);
 	  this.localTransport = this._transport.onOutputStreamReady === undefined;
-
+	
 	  /*
 	   * As the first thing on the connection, expect a greeting packet from
 	   * the connection's root actor.
 	   */
 	  this.mainRoot = null;
 	  this.expectReply("root", (aPacket) => {
 	    this.mainRoot = new RootClient(this, aPacket);
 	    this.emit("connected", aPacket.applicationType, aPacket.traits);
 	  });
 	};
-
+	
 	/**
 	 * A declarative helper for defining methods that send requests to the server.
 	 *
 	 * @param aPacketSkeleton
 	 *        The form of the packet to send. Can specify fields to be filled from
 	 *        the parameters by using the |args| function.
 	 * @param telemetry
 	 *        The unique suffix of the telemetry histogram id.
@@ -10611,81 +10589,81 @@ var Debugger =
 	      let histogramId = "DEVTOOLS_DEBUGGER_RDP_"
 	        + transportType + telemetry + "_MS";
 	      histogram = Services.telemetry.getHistogramById(histogramId);
 	      startTime = +new Date();
 	    }
 	    let outgoingPacket = {
 	      to: aPacketSkeleton.to || this.actor
 	    };
-
+	
 	    let maxPosition = -1;
 	    for (let k of Object.keys(aPacketSkeleton)) {
 	      if (aPacketSkeleton[k] instanceof DebuggerClient.Argument) {
 	        let { position } = aPacketSkeleton[k];
 	        outgoingPacket[k] = aPacketSkeleton[k].getArgument(args);
 	        maxPosition = Math.max(position, maxPosition);
 	      } else {
 	        outgoingPacket[k] = aPacketSkeleton[k];
 	      }
 	    }
-
+	
 	    if (before) {
 	      outgoingPacket = before.call(this, outgoingPacket);
 	    }
-
+	
 	    return this.request(outgoingPacket, DevToolsUtils.makeInfallible((aResponse) => {
 	      if (after) {
 	        let { from } = aResponse;
 	        aResponse = after.call(this, aResponse);
 	        if (!aResponse.from) {
 	          aResponse.from = from;
 	        }
 	      }
-
+	
 	      // The callback is always the last parameter.
 	      let thisCallback = args[maxPosition + 1];
 	      if (thisCallback) {
 	        thisCallback(aResponse);
 	      }
-
+	
 	      if (histogram) {
 	        histogram.add(+new Date() - startTime);
 	      }
 	    }, "DebuggerClient.requester request callback"));
 	  }, "DebuggerClient.requester");
 	};
-
+	
 	function args(aPos) {
 	  return new DebuggerClient.Argument(aPos);
 	}
-
+	
 	DebuggerClient.Argument = function(aPosition) {
 	  this.position = aPosition;
 	};
-
+	
 	DebuggerClient.Argument.prototype.getArgument = function(aParams) {
 	  if (!(this.position in aParams)) {
 	    throw new Error("Bad index into params: " + this.position);
 	  }
 	  return aParams[this.position];
 	};
-
+	
 	// Expose these to save callers the trouble of importing DebuggerSocket
 	DebuggerClient.socketConnect = function(options) {
 	  // Defined here instead of just copying the function to allow lazy-load
 	  return DebuggerSocket.connect(options);
 	};
 	DevToolsUtils.defineLazyGetter(DebuggerClient, "Authenticators", () => {
 	  return Authentication.Authenticators;
 	});
 	DevToolsUtils.defineLazyGetter(DebuggerClient, "AuthenticationResult", () => {
 	  return Authentication.AuthenticationResult;
 	});
-
+	
 	DebuggerClient.prototype = {
 	  /**
 	   * Connect to the server and start exchanging protocol messages.
 	   *
 	   * @param aOnConnected function
 	   *        If specified, will be called when the greeting packet is
 	   *        received from the debugging server.
 	   *
@@ -10694,71 +10672,71 @@ var Debugger =
 	   *         is the application type, by default "browser", and the second
 	   *         element is the traits object (help figure out the features
 	   *         and behaviors of the server we connect to. See RootActor).
 	   */
 	  connect: function(aOnConnected) {
 	    return Promise.race([
 	      new Promise((resolve, reject) => {
 	        this.emit("connect");
-
+	
 	        // Also emit the event on the |DebuggerClient| object (not on the instance),
 	        // so it's possible to track all instances.
 	        events.emit(DebuggerClient, "connect", this);
-
+	
 	        this.addOneTimeListener("connected", (aName, aApplicationType, aTraits) => {
 	          this.traits = aTraits;
 	          if (aOnConnected) {
 	            aOnConnected(aApplicationType, aTraits);
 	          }
 	          resolve([aApplicationType, aTraits]);
 	        });
-
+	
 	        this._transport.ready();
 	      }),
 	      new Promise((resolve, reject) => {
 	        setTimeout(() => reject(new Error("Connect timeout error")), 6000);
 	      })
 	    ]);
 	  },
-
+	
 	  /**
 	   * Shut down communication with the debugging server.
 	   *
 	   * @param aOnClosed function
 	   *        If specified, will be called when the debugging connection
 	   *        has been closed.
 	   */
 	  close: function(aOnClosed) {
 	    // Disable detach event notifications, because event handlers will be in a
 	    // cleared scope by the time they run.
 	    this._eventsEnabled = false;
-
+	
 	    let cleanup = () => {
 	      this._transport.close();
 	      this._transport = null;
 	    };
-
+	
 	    // If the connection is already closed,
 	    // there is no need to detach client
 	    // as we won't be able to send any message.
 	    if (this._closed) {
 	      cleanup();
 	      if (aOnClosed) {
 	        aOnClosed();
 	      }
 	      return;
 	    }
-
+	
 	    if (aOnClosed) {
 	      this.addOneTimeListener("closed", function(aEvent) {
 	        aOnClosed();
 	      });
 	    }
-
+	
 	    // Call each client's `detach` method by calling
 	    // lastly registered ones first to give a chance
 	    // to detach child clients first.
 	    let clients = [...this._clients.values()];
 	    this._clients.clear();
 	    const detachClients = () => {
 	      let client = clients.pop();
 	      if (!client) {
@@ -10769,31 +10747,31 @@ var Debugger =
 	      if (client.detach) {
 	        client.detach(detachClients);
 	        return;
 	      }
 	      detachClients();
 	    };
 	    detachClients();
 	  },
-
+	
 	  /*
 	   * This function exists only to preserve DebuggerClient's interface;
 	   * new code should say 'client.mainRoot.listTabs()'.
 	   */
 	  listTabs: function(aOnResponse) { return this.mainRoot.listTabs(aOnResponse); },
-
+	
 	  /*
 	   * This function exists only to preserve DebuggerClient's interface;
 	   * new code should say 'client.mainRoot.listAddons()'.
 	   */
 	  listAddons: function(aOnResponse) { return this.mainRoot.listAddons(aOnResponse); },
-
+	
 	  getTab: function(aFilter) { return this.mainRoot.getTab(aFilter); },
-
+	
 	  /**
 	   * Attach to a tab actor.
 	   *
 	   * @param string aTabActor
 	   *        The actor ID for the tab to attach.
 	   * @param function aOnResponse
 	   *        Called with the response packet and a TabClient
 	   *        (which will be undefined on error).
@@ -10804,57 +10782,57 @@ var Debugger =
 	      let cachedResponse = {
 	        cacheDisabled: cachedTab.cacheDisabled,
 	        javascriptEnabled: cachedTab.javascriptEnabled,
 	        traits: cachedTab.traits,
 	      };
 	      DevToolsUtils.executeSoon(() => aOnResponse(cachedResponse, cachedTab));
 	      return promise.resolve([cachedResponse, cachedTab]);
 	    }
-
+	
 	    let packet = {
 	      to: aTabActor,
 	      type: "attach"
 	    };
 	    return this.request(packet).then(aResponse => {
 	      let tabClient;
 	      if (!aResponse.error) {
 	        tabClient = new TabClient(this, aResponse);
 	        this.registerClient(tabClient);
 	      }
 	      aOnResponse(aResponse, tabClient);
 	      return [aResponse, tabClient];
 	    });
 	  },
-
+	
 	  attachWorker: function DC_attachWorker(aWorkerActor, aOnResponse = noop) {
 	    let workerClient = this._clients.get(aWorkerActor);
 	    if (workerClient !== undefined) {
 	      let response = {
 	        from: workerClient.actor,
 	        type: "attached",
 	        url: workerClient.url
 	      };
 	      DevToolsUtils.executeSoon(() => aOnResponse(response, workerClient));
 	      return promise.resolve([response, workerClient]);
 	    }
-
+	
 	    return this.request({ to: aWorkerActor, type: "attach" }).then(aResponse => {
 	      if (aResponse.error) {
 	        aOnResponse(aResponse, null);
 	        return [aResponse, null];
 	      }
-
+	
 	      let workerClient = new WorkerClient(this, aResponse);
 	      this.registerClient(workerClient);
 	      aOnResponse(aResponse, workerClient);
 	      return [aResponse, workerClient];
 	    });
 	  },
-
+	
 	  /**
 	   * Attach to an addon actor.
 	   *
 	   * @param string aAddonActor
 	   *        The actor ID for the addon to attach.
 	   * @param function aOnResponse
 	   *        Called with the response packet and a AddonClient
 	   *        (which will be undefined on error).
@@ -10870,17 +10848,17 @@ var Debugger =
 	        addonClient = new AddonClient(this, aAddonActor);
 	        this.registerClient(addonClient);
 	        this.activeAddon = addonClient;
 	      }
 	      aOnResponse(aResponse, addonClient);
 	      return [aResponse, addonClient];
 	    });
 	  },
-
+	
 	  /**
 	   * Attach to a Web Console actor.
 	   *
 	   * @param string aConsoleActor
 	   *        The ID for the console actor to attach to.
 	   * @param array aListeners
 	   *        The console listeners you want to start.
 	   * @param function aOnResponse
@@ -10889,32 +10867,32 @@ var Debugger =
 	   */
 	  attachConsole:
 	  function(aConsoleActor, aListeners, aOnResponse = noop) {
 	    let packet = {
 	      to: aConsoleActor,
 	      type: "startListeners",
 	      listeners: aListeners,
 	    };
-
+	
 	    return this.request(packet).then(aResponse => {
 	      let consoleClient;
 	      if (!aResponse.error) {
 	        if (this._clients.has(aConsoleActor)) {
 	          consoleClient = this._clients.get(aConsoleActor);
 	        } else {
 	          consoleClient = new WebConsoleClient(this, aResponse);
 	          this.registerClient(consoleClient);
 	        }
 	      }
 	      aOnResponse(aResponse, consoleClient);
 	      return [aResponse, consoleClient];
 	    });
 	  },
-
+	
 	  /**
 	   * Attach to a global-scoped thread actor for chrome debugging.
 	   *
 	   * @param string aThreadActor
 	   *        The actor ID for the thread to attach.
 	   * @param function aOnResponse
 	   *        Called with the response packet and a ThreadClient
 	   *        (which will be undefined on error).
@@ -10923,62 +10901,62 @@ var Debugger =
 	   *        - useSourceMaps: whether to use source maps or not.
 	   */
 	  attachThread: function(aThreadActor, aOnResponse = noop, aOptions = {}) {
 	    if (this._clients.has(aThreadActor)) {
 	      let client = this._clients.get(aThreadActor);
 	      DevToolsUtils.executeSoon(() => aOnResponse({}, client));
 	      return promise.resolve([{}, client]);
 	    }
-
+	
 	    let packet = {
 	      to: aThreadActor,
 	      type: "attach",
 	      options: aOptions
 	    };
 	    return this.request(packet).then(aResponse => {
 	      if (!aResponse.error) {
 	        var threadClient = new ThreadClient(this, aThreadActor);
 	        this.registerClient(threadClient);
 	      }
 	      aOnResponse(aResponse, threadClient);
 	      return [aResponse, threadClient];
 	    });
 	  },
-
+	
 	  /**
 	   * Attach to a trace actor.
 	   *
 	   * @param string aTraceActor
 	   *        The actor ID for the tracer to attach.
 	   * @param function aOnResponse
 	   *        Called with the response packet and a TraceClient
 	   *        (which will be undefined on error).
 	   */
 	  attachTracer: function(aTraceActor, aOnResponse = noop) {
 	    if (this._clients.has(aTraceActor)) {
 	      let client = this._clients.get(aTraceActor);
 	      DevToolsUtils.executeSoon(() => aOnResponse({}, client));
 	      return promise.resolve([{}, client]);
 	    }
-
+	
 	    let packet = {
 	      to: aTraceActor,
 	      type: "attach"
 	    };
 	    return this.request(packet).then(aResponse => {
 	      if (!aResponse.error) {
 	        var traceClient = new TraceClient(this, aTraceActor);
 	        this.registerClient(traceClient);
 	      }
 	      aOnResponse(aResponse, traceClient);
 	      return [aResponse, traceClient];
 	    });
 	  },
-
+	
 	  /**
 	   * Fetch the ChromeActor for the main process or ChildProcessActor for a
 	   * a given child process ID.
 	   *
 	   * @param number aId
 	   *        The ID for the process to attach (returned by `listProcesses`).
 	   *        Connected to the main process if omitted, or is 0.
 	   */
@@ -10987,33 +10965,33 @@ var Debugger =
 	      to: "root",
 	      type: "getProcess"
 	    };
 	    if (typeof (aId) == "number") {
 	      packet.id = aId;
 	    }
 	    return this.request(packet);
 	  },
-
+	
 	  /**
 	   * Release an object actor.
 	   *
 	   * @param string aActor
 	   *        The actor ID to send the request to.
 	   * @param aOnResponse function
 	   *        If specified, will be called with the response packet when
 	   *        debugging server responds.
 	   */
 	  release: DebuggerClient.requester({
 	    to: args(0),
 	    type: "release"
 	  }, {
 	    telemetry: "RELEASE"
 	  }),
-
+	
 	  /**
 	   * Send a request to the debugging server.
 	   *
 	   * @param aRequest object
 	   *        A JSON packet to send to the debugging server.
 	   * @param aOnResponse function
 	   *        If specified, will be called with the JSON response packet when
 	   *        debugging server responds.
@@ -11069,26 +11047,26 @@ var Debugger =
 	                "'" + aRequest.to + "' " +
 	               "can't be sent as the connection is closed.";
 	      let resp = { error: "connectionClosed", message: msg };
 	      if (aOnResponse) {
 	        aOnResponse(resp);
 	      }
 	      return promise.reject(resp);
 	    }
-
+	
 	    let request = new Request(aRequest);
 	    request.format = "json";
 	    request.stack = components.stack;
 	    if (aOnResponse) {
 	      request.on("json-reply", aOnResponse);
 	    }
-
+	
 	    this._sendOrQueueRequest(request);
-
+	
 	    // Implement a Promise like API on the returned object
 	    // that resolves/rejects on request response
 	    let deferred = promise.defer();
 	    function listenerJson(resp) {
 	      request.off("json-reply", listenerJson);
 	      request.off("bulk-reply", listenerBulk);
 	      if (resp.error) {
 	        deferred.reject(resp);
@@ -11099,20 +11077,20 @@ var Debugger =
 	    function listenerBulk(resp) {
 	      request.off("json-reply", listenerJson);
 	      request.off("bulk-reply", listenerBulk);
 	      deferred.resolve(resp);
 	    }
 	    request.on("json-reply", listenerJson);
 	    request.on("bulk-reply", listenerBulk);
 	    request.then = deferred.promise.then.bind(deferred.promise);
-
+	
 	    return request;
 	  },
-
+	
 	  /**
 	   * Transmit streaming data via a bulk request.
 	   *
 	   * This method initiates the bulk send process by queuing up the header data.
 	   * The caller receives eventual access to a stream for writing.
 	   *
 	   * Since this opens up more options for how the server might respond (it could
 	   * send back either JSON or bulk data), and the returned Request object emits
@@ -11192,67 +11170,67 @@ var Debugger =
 	      throw Error("Bulk packet is missing the required 'type' field.");
 	    }
 	    if (!request.actor) {
 	      throw Error("'" + request.type + "' bulk packet has no destination.");
 	    }
 	    if (!request.length) {
 	      throw Error("'" + request.type + "' bulk packet has no length.");
 	    }
-
+	
 	    request = new Request(request);
 	    request.format = "bulk";
-
+	
 	    this._sendOrQueueRequest(request);
-
+	
 	    return request;
 	  },
-
+	
 	  /**
 	   * If a new request can be sent immediately, do so.  Otherwise, queue it.
 	   */
 	  _sendOrQueueRequest(request) {
 	    let actor = request.actor;
 	    if (!this._activeRequests.has(actor)) {
 	      this._sendRequest(request);
 	    } else {
 	      this._queueRequest(request);
 	    }
 	  },
-
+	
 	  /**
 	   * Send a request.
 	   * @throws Error if there is already an active request in flight for the same
 	   *         actor.
 	   */
 	  _sendRequest(request) {
 	    let actor = request.actor;
 	    this.expectReply(actor, request);
-
+	
 	    if (request.format === "json") {
 	      this._transport.send(request.request);
 	      return false;
 	    }
-
+	
 	    this._transport.startBulkSend(request.request).then((...args) => {
 	      request.emit("bulk-send-ready", ...args);
 	    });
 	  },
-
+	
 	  /**
 	   * Queue a request to be sent later.  Queues are only drained when an in
 	   * flight request to a given actor completes.
 	   */
 	  _queueRequest(request) {
 	    let actor = request.actor;
 	    let queue = this._pendingRequests.get(actor) || [];
 	    queue.push(request);
 	    this._pendingRequests.set(actor, queue);
 	  },
-
+	
 	  /**
 	   * Attempt the next request to a given actor (if any).
 	   */
 	  _attemptNextRequest(actor) {
 	    if (this._activeRequests.has(actor)) {
 	      return;
 	    }
 	    let queue = this._pendingRequests.get(actor);
@@ -11260,132 +11238,132 @@ var Debugger =
 	      return;
 	    }
 	    let request = queue.shift();
 	    if (queue.length === 0) {
 	      this._pendingRequests.delete(actor);
 	    }
 	    this._sendRequest(request);
 	  },
-
+	
 	  /**
 	   * Arrange to hand the next reply from |aActor| to the handler bound to
 	   * |aRequest|.
 	   *
 	   * DebuggerClient.prototype.request / startBulkRequest usually takes care of
 	   * establishing the handler for a given request, but in rare cases (well,
 	   * greetings from new root actors, is the only case at the moment) we must be
 	   * prepared for a "reply" that doesn't correspond to any request we sent.
 	   */
 	  expectReply: function(aActor, aRequest) {
 	    if (this._activeRequests.has(aActor)) {
 	      throw Error("clashing handlers for next reply from " + uneval(aActor));
 	    }
-
+	
 	    // If a handler is passed directly (as it is with the handler for the root
 	    // actor greeting), create a dummy request to bind this to.
 	    if (typeof aRequest === "function") {
 	      let handler = aRequest;
 	      aRequest = new Request();
 	      aRequest.on("json-reply", handler);
 	    }
-
+	
 	    this._activeRequests.set(aActor, aRequest);
 	  },
-
+	
 	  // Transport hooks.
-
+	
 	  /**
 	   * Called by DebuggerTransport to dispatch incoming packets as appropriate.
 	   *
 	   * @param aPacket object
 	   *        The incoming packet.
 	   */
 	  onPacket: function(aPacket) {
 	    if (!aPacket.from) {
 	      DevToolsUtils.reportException(
 	        "onPacket",
 	        new Error("Server did not specify an actor, dropping packet: " +
 	                  JSON.stringify(aPacket)));
 	      return;
 	    }
-
+	
 	    // If we have a registered Front for this actor, let it handle the packet
 	    // and skip all the rest of this unpleasantness.
 	    let front = this.getActor(aPacket.from);
 	    if (front) {
 	      front.onPacket(aPacket);
 	      return;
 	    }
-
+	
 	    if (this._clients.has(aPacket.from) && aPacket.type) {
 	      let client = this._clients.get(aPacket.from);
 	      let type = aPacket.type;
 	      if (client.events.indexOf(type) != -1) {
 	        client.emit(type, aPacket);
 	        // we ignore the rest, as the client is expected to handle this packet.
 	        return;
 	      }
 	    }
-
+	
 	    let activeRequest;
 	    // See if we have a handler function waiting for a reply from this
 	    // actor. (Don't count unsolicited notifications or pauses as
 	    // replies.)
 	    if (this._activeRequests.has(aPacket.from) &&
 	        !(aPacket.type in UnsolicitedNotifications) &&
 	        !(aPacket.type == ThreadStateTypes.paused &&
 	          aPacket.why.type in UnsolicitedPauses)) {
 	      activeRequest = this._activeRequests.get(aPacket.from);
 	      this._activeRequests.delete(aPacket.from);
 	    }
-
+	
 	    // If there is a subsequent request for the same actor, hand it off to the
 	    // transport.  Delivery of packets on the other end is always async, even
 	    // in the local transport case.
 	    this._attemptNextRequest(aPacket.from);
-
+	
 	    // Packets that indicate thread state changes get special treatment.
 	    if (aPacket.type in ThreadStateTypes &&
 	        this._clients.has(aPacket.from) &&
 	        typeof this._clients.get(aPacket.from)._onThreadState == "function") {
 	      this._clients.get(aPacket.from)._onThreadState(aPacket);
 	    }
-
+	
 	    // TODO: Bug 1151156 - Remove once Gecko 40 is on b2g-stable.
 	    if (!this.traits.noNeedToFakeResumptionOnNavigation) {
 	      // On navigation the server resumes, so the client must resume as well.
 	      // We achieve that by generating a fake resumption packet that triggers
 	      // the client's thread state change listeners.
 	      if (aPacket.type == UnsolicitedNotifications.tabNavigated &&
 	          this._clients.has(aPacket.from) &&
 	          this._clients.get(aPacket.from).thread) {
 	        let thread = this._clients.get(aPacket.from).thread;
 	        let resumption = { from: thread._actor, type: "resumed" };
 	        thread._onThreadState(resumption);
 	      }
 	    }
-
+	
 	    // Only try to notify listeners on events, not responses to requests
 	    // that lack a packet type.
 	    if (aPacket.type) {
 	      this.emit(aPacket.type, aPacket);
 	    }
-
+	
 	    if (activeRequest) {
 	      let emitReply = () => activeRequest.emit("json-reply", aPacket);
 	      if (activeRequest.stack) {
 	        Cu.callFunctionWithAsyncStack(emitReply, activeRequest.stack,
 	                                      "DevTools RDP");
 	      } else {
 	        emitReply();
 	      }
 	    }
 	  },
-
+	
 	  /**
 	   * Called by the DebuggerTransport to dispatch incoming bulk packets as
 	   * appropriate.
 	   *
 	   * @param packet object
 	   *        The incoming packet, which contains:
 	   *        * actor:  Name of actor that will receive the packet
 	   *        * type:   Name of actor's method that should be called on receipt
@@ -11408,79 +11386,79 @@ var Debugger =
 	   *          @return Promise
 	   *                  The promise is resolved when copying completes or rejected
 	   *                  if any (unexpected) errors occur.
 	   *                  This object also emits "progress" events for each chunk
 	   *                  that is copied.  See stream-utils.js.
 	   */
 	  onBulkPacket: function(packet) {
 	    let { actor, type, length } = packet;
-
+	
 	    if (!actor) {
 	      DevToolsUtils.reportException(
 	        "onBulkPacket",
 	        new Error("Server did not specify an actor, dropping bulk packet: " +
 	                  JSON.stringify(packet)));
 	      return;
 	    }
-
+	
 	    // See if we have a handler function waiting for a reply from this
 	    // actor.
 	    if (!this._activeRequests.has(actor)) {
 	      return;
 	    }
-
+	
 	    let activeRequest = this._activeRequests.get(actor);
 	    this._activeRequests.delete(actor);
-
+	
 	    // If there is a subsequent request for the same actor, hand it off to the
 	    // transport.  Delivery of packets on the other end is always async, even
 	    // in the local transport case.
 	    this._attemptNextRequest(actor);
-
+	
 	    activeRequest.emit("bulk-reply", packet);
 	  },
-
+	
 	  /**
 	   * Called by DebuggerTransport when the underlying stream is closed.
 	   *
 	   * @param aStatus nsresult
 	   *        The status code that corresponds to the reason for closing
 	   *        the stream.
 	   */
 	  onClosed: function(aStatus) {
 	    this._closed = true;
 	    this.emit("closed");
-
+	
 	    // Reject all pending and active requests
 	    let reject = function(type, request, actor) {
 	      // Server can send packets on its own and client only pass a callback
 	      // to expectReply, so that there is no request object.
 	      let msg;
 	      if (request.request) {
 	        msg = "'" + request.request.type + "' " + type + " request packet" +
 	              " to '" + actor + "' " +
 	              "can't be sent as the connection just closed.";
 	      } else {
 	        msg = "server side packet from '" + actor + "' can't be received " +
 	              "as the connection just closed.";
 	      }
 	      let packet = { error: "connectionClosed", message: msg };
 	      request.emit("json-reply", packet);
 	    };
-
+	
 	    let pendingRequests = new Map(this._pendingRequests);
 	    this._pendingRequests.clear();
 	    pendingRequests.forEach((list, actor) => {
 	      list.forEach(request => reject("pending", request, actor));
 	    });
 	    let activeRequests = new Map(this._activeRequests);
 	    this._activeRequests.clear();
 	    activeRequests.forEach(reject.bind(null, "active"));
-
+	
 	    // The |_pools| array on the client-side currently is used only by
 	    // protocol.js to store active fronts, mirroring the actor pools found in
 	    // the server.  So, read all usages of "pool" as "protocol.js front".
 	    //
 	    // In the normal case where we shutdown cleanly, the toolbox tells each tool
 	    // to close, and they each call |destroy| on any fronts they were using.
 	    // When |destroy| or |cleanup| is called on a protocol.js front, it also
 	    // removes itself from the |_pools| array.  Once the toolbox has shutdown,
@@ -11492,17 +11470,17 @@ var Debugger =
 	    // on them clear their state, reject pending requests, and remove themselves
 	    // from |_pools|.  This saves the toolbox from hanging indefinitely, in case
 	    // it waits for some server response before shutdown that will now never
 	    // arrive.
 	    for (let pool of this._pools) {
 	      pool.cleanup();
 	    }
 	  },
-
+	
 	  registerClient: function(client) {
 	    let actorID = client.actor;
 	    if (!actorID) {
 	      throw new Error("DebuggerServer.registerClient expects " +
 	                      "a client instance with an `actor` attribute.");
 	    }
 	    if (!Array.isArray(client.events)) {
 	      throw new Error("DebuggerServer.registerClient expects " +
@@ -11515,90 +11493,90 @@ var Debugger =
 	                      "have an `emit` function.");
 	    }
 	    if (this._clients.has(actorID)) {
 	      throw new Error("DebuggerServer.registerClient already registered " +
 	                      "a client for this actor.");
 	    }
 	    this._clients.set(actorID, client);
 	  },
-
+	
 	  unregisterClient: function(client) {
 	    let actorID = client.actor;
 	    if (!actorID) {
 	      throw new Error("DebuggerServer.unregisterClient expects " +
 	                      "a Client instance with a `actor` attribute.");
 	    }
 	    this._clients.delete(actorID);
 	  },
-
+	
 	  /**
 	   * Actor lifetime management, echos the server's actor pools.
 	   */
 	  __pools: null,
 	  get _pools() {
 	    if (this.__pools) {
 	      return this.__pools;
 	    }
 	    this.__pools = new Set();
 	    return this.__pools;
 	  },
-
+	
 	  addActorPool: function(pool) {
 	    this._pools.add(pool);
 	  },
 	  removeActorPool: function(pool) {
 	    this._pools.delete(pool);
 	  },
 	  getActor: function(actorID) {
 	    let pool = this.poolFor(actorID);
 	    return pool ? pool.get(actorID) : null;
 	  },
-
+	
 	  poolFor: function(actorID) {
 	    for (let pool of this._pools) {
 	      if (pool.has(actorID)) return pool;
 	    }
 	    return null;
 	  },
-
+	
 	  /**
 	   * Currently attached addon.
 	   */
 	  activeAddon: null
 	};
-
+	
 	eventSource(DebuggerClient.prototype);
-
+	
 	function Request(request) {
 	  this.request = request;
 	}
-
+	
 	Request.prototype = {
-
+	
 	  on: function(type, listener) {
 	    events.on(this, type, listener);
 	  },
-
+	
 	  off: function(type, listener) {
 	    events.off(this, type, listener);
 	  },
-
+	
 	  once: function(type, listener) {
 	    events.once(this, type, listener);
 	  },
-
+	
 	  emit: function(type, ...args) {
 	    events.emit(this, type, ...args);
 	  },
-
+	
 	  get actor() { return this.request.to || this.request.actor; }
-
-	};
-
+	
+	};
+	
 	/**
 	 * Creates a tab client for the remote debugging protocol server. This client
 	 * is a front to the tab actor created in the server side, hiding the protocol
 	 * details in a traditional JavaScript API.
 	 *
 	 * @param aClient DebuggerClient
 	 *        The debugger client parent.
 	 * @param aForm object
@@ -11610,52 +11588,52 @@ var Debugger =
 	  this._threadActor = aForm.threadActor;
 	  this.javascriptEnabled = aForm.javascriptEnabled;
 	  this.cacheDisabled = aForm.cacheDisabled;
 	  this.thread = null;
 	  this.request = this.client.request;
 	  this.traits = aForm.traits || {};
 	  this.events = ["workerListChanged"];
 	}
-
+	
 	TabClient.prototype = {
 	  get actor() { return this._actor; },
 	  get _transport() { return this.client._transport; },
-
+	
 	  /**
 	   * Attach to a thread actor.
 	   *
 	   * @param object aOptions
 	   *        Configuration options.
 	   *        - useSourceMaps: whether to use source maps or not.
 	   * @param function aOnResponse
 	   *        Called with the response packet and a ThreadClient
 	   *        (which will be undefined on error).
 	   */
 	  attachThread: function(aOptions = {}, aOnResponse = noop) {
 	    if (this.thread) {
 	      DevToolsUtils.executeSoon(() => aOnResponse({}, this.thread));
 	      return promise.resolve([{}, this.thread]);
 	    }
-
+	
 	    let packet = {
 	      to: this._threadActor,
 	      type: "attach",
 	      options: aOptions
 	    };
 	    return this.request(packet).then(aResponse => {
 	      if (!aResponse.error) {
 	        this.thread = new ThreadClient(this, this._threadActor);
 	        this.client.registerClient(this.thread);
 	      }
 	      aOnResponse(aResponse, this.thread);
 	      return [aResponse, this.thread];
 	    });
 	  },
-
+	
 	  /**
 	   * Detach the client from the tab actor.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  detach: DebuggerClient.requester({
 	    type: "detach"
@@ -11667,212 +11645,212 @@ var Debugger =
 	      return aPacket;
 	    },
 	    after: function(aResponse) {
 	      this.client.unregisterClient(this);
 	      return aResponse;
 	    },
 	    telemetry: "TABDETACH"
 	  }),
-
+	
 	  /**
 	   * Bring the window to the front.
 	   */
 	  focus: DebuggerClient.requester({
 	    type: "focus"
 	  }, {}),
-
+	
 	  /**
 	   * Reload the page in this tab.
 	   *
 	   * @param [optional] object options
 	   *        An object with a `force` property indicating whether or not
 	   *        this reload should skip the cache
 	   */
 	  reload: function(options = { force: false }) {
 	    return this._reload(options);
 	  },
 	  _reload: DebuggerClient.requester({
 	    type: "reload",
 	    options: args(0)
 	  }, {
 	    telemetry: "RELOAD"
 	  }),
-
+	
 	  /**
 	   * Navigate to another URL.
 	   *
 	   * @param string url
 	   *        The URL to navigate to.
 	   */
 	  navigateTo: DebuggerClient.requester({
 	    type: "navigateTo",
 	    url: args(0)
 	  }, {
 	    telemetry: "NAVIGATETO"
 	  }),
-
+	
 	  /**
 	   * Reconfigure the tab actor.
 	   *
 	   * @param object aOptions
 	   *        A dictionary object of the new options to use in the tab actor.
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  reconfigure: DebuggerClient.requester({
 	    type: "reconfigure",
 	    options: args(0)
 	  }, {
 	    telemetry: "RECONFIGURETAB"
 	  }),
-
+	
 	  listWorkers: DebuggerClient.requester({
 	    type: "listWorkers"
 	  }, {
 	    telemetry: "LISTWORKERS"
 	  }),
-
+	
 	  attachWorker: function(aWorkerActor, aOnResponse) {
 	    this.client.attachWorker(aWorkerActor, aOnResponse);
 	  },
-
+	
 	  /**
 	   * Resolve a location ({ url, line, column }) to its current
 	   * source mapping location.
 	   *
 	   * @param {String} arg[0].url
 	   * @param {Number} arg[0].line
 	   * @param {Number?} arg[0].column
 	   */
 	  resolveLocation: DebuggerClient.requester({
 	    type: "resolveLocation",
 	    location: args(0)
 	  }),
 	};
-
+	
 	eventSource(TabClient.prototype);
-
+	
 	function WorkerClient(aClient, aForm) {
 	  this.client = aClient;
 	  this._actor = aForm.from;
 	  this._isClosed = false;
 	  this._url = aForm.url;
-
+	
 	  this._onClose = this._onClose.bind(this);
-
+	
 	  this.addListener("close", this._onClose);
-
+	
 	  this.traits = {};
 	}
-
+	
 	WorkerClient.prototype = {
 	  get _transport() {
 	    return this.client._transport;
 	  },
-
+	
 	  get request() {
 	    return this.client.request;
 	  },
-
+	
 	  get actor() {
 	    return this._actor;
 	  },
-
+	
 	  get url() {
 	    return this._url;
 	  },
-
+	
 	  get isClosed() {
 	    return this._isClosed;
 	  },
-
+	
 	  detach: DebuggerClient.requester({ type: "detach" }, {
 	    after: function(aResponse) {
 	      if (this.thread) {
 	        this.client.unregisterClient(this.thread);
 	      }
 	      this.client.unregisterClient(this);
 	      return aResponse;
 	    },
-
+	
 	    telemetry: "WORKERDETACH"
 	  }),
-
+	
 	  attachThread: function(aOptions = {}, aOnResponse = noop) {
 	    if (this.thread) {
 	      let response = [{
 	        type: "connected",
 	        threadActor: this.thread._actor,
 	        consoleActor: this.consoleActor,
 	      }, this.thread];
 	      DevToolsUtils.executeSoon(() => aOnResponse(response));
 	      return response;
 	    }
-
+	
 	    // The connect call on server doesn't attach the thread as of version 44.
 	    return this.request({
 	      to: this._actor,
 	      type: "connect",
 	      options: aOptions,
 	    }).then(connectReponse => {
 	      if (connectReponse.error) {
 	        aOnResponse(connectReponse, null);
 	        return [connectResponse, null];
 	      }
-
+	
 	      return this.request({
 	        to: connectReponse.threadActor,
 	        type: "attach",
 	        options: aOptions
 	      }).then(attachResponse => {
 	        if (attachResponse.error) {
 	          aOnResponse(attachResponse, null);
 	        }
-
+	
 	        this.thread = new ThreadClient(this, connectReponse.threadActor);
 	        this.consoleActor = connectReponse.consoleActor;
 	        this.client.registerClient(this.thread);
-
+	
 	        aOnResponse(connectReponse, this.thread);
 	        return [connectResponse, this.thread];
 	      });
 	    });
 	  },
-
+	
 	  _onClose: function() {
 	    this.removeListener("close", this._onClose);
-
+	
 	    if (this.thread) {
 	      this.client.unregisterClient(this.thread);
 	    }
 	    this.client.unregisterClient(this);
 	    this._isClosed = true;
 	  },
-
+	
 	  reconfigure: function() {
 	    return Promise.resolve();
 	  },
-
+	
 	  events: ["close"]
 	};
-
+	
 	eventSource(WorkerClient.prototype);
-
+	
 	function AddonClient(aClient, aActor) {
 	  this._client = aClient;
 	  this._actor = aActor;
 	  this.request = this._client.request;
 	  this.events = [];
 	}
-
+	
 	AddonClient.prototype = {
 	  get actor() { return this._actor; },
 	  get _transport() { return this._client._transport; },
-
+	
 	  /**
 	   * Detach the client from the addon actor.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  detach: DebuggerClient.requester({
 	    type: "detach"
@@ -11882,17 +11860,17 @@ var Debugger =
 	        this._client.activeAddon = null;
 	      }
 	      this._client.unregisterClient(this);
 	      return aResponse;
 	    },
 	    telemetry: "ADDONDETACH"
 	  })
 	};
-
+	
 	/**
 	 * A RootClient object represents a root actor on the server. Each
 	 * DebuggerClient keeps a RootClient instance representing the root actor
 	 * for the initial connection; DebuggerClient's 'listTabs' and
 	 * 'listChildProcesses' methods forward to that root actor.
 	 *
 	 * @param aClient object
 	 *      The client connection to which this actor belongs.
@@ -11910,65 +11888,65 @@ var Debugger =
 	 */
 	function RootClient(aClient, aGreeting) {
 	  this._client = aClient;
 	  this.actor = aGreeting.from;
 	  this.applicationType = aGreeting.applicationType;
 	  this.traits = aGreeting.traits;
 	}
 	exports.RootClient = RootClient;
-
+	
 	RootClient.prototype = {
 	  constructor: RootClient,
-
+	
 	  /**
 	   * List the open tabs.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  listTabs: DebuggerClient.requester({ type: "listTabs" },
 	                                     { telemetry: "LISTTABS" }),
-
+	
 	  /**
 	   * List the installed addons.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  listAddons: DebuggerClient.requester({ type: "listAddons" },
 	                                       { telemetry: "LISTADDONS" }),
-
+	
 	  /**
 	   * List the registered workers.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  listWorkers: DebuggerClient.requester({ type: "listWorkers" },
 	                                        { telemetry: "LISTWORKERS" }),
-
+	
 	  /**
 	   * List the registered service workers.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  listServiceWorkerRegistrations: DebuggerClient.requester({ type: "listServiceWorkerRegistrations" },
 	                                                           { telemetry: "LISTSERVICEWORKERREGISTRATIONS" }),
-
+	
 	  /**
 	   * List the running processes.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  listProcesses: DebuggerClient.requester({ type: "listProcesses" },
 	                                          { telemetry: "LISTPROCESSES" }),
-
+	
 	  /**
 	   * Fetch the TabActor for the currently selected tab, or for a specific
 	   * tab given as first parameter.
 	   *
 	   * @param [optional] object aFilter
 	   *        A dictionary object with following optional attributes:
 	   *         - outerWindowID: used to match tabs in parent process
 	   *         - tabId: used to match tabs in child processes
@@ -11976,17 +11954,17 @@ var Debugger =
 	   *        If nothing is specified, returns the actor for the currently
 	   *        selected tab.
 	   */
 	  getTab: function(aFilter) {
 	    let packet = {
 	      to: this.actor,
 	      type: "getTab"
 	    };
-
+	
 	    if (aFilter) {
 	      if (typeof (aFilter.outerWindowID) == "number") {
 	        packet.outerWindowID = aFilter.outerWindowID;
 	      } else if (typeof (aFilter.tabId) == "number") {
 	        packet.tabId = aFilter.tabId;
 	      } else if ("tab" in aFilter) {
 	        let browser = aFilter.tab.linkedBrowser;
 	        if (browser.frameLoader.tabParent) {
@@ -12000,37 +11978,37 @@ var Debugger =
 	          packet.outerWindowID = windowUtils.outerWindowID;
 	        }
 	      } else {
 	        // Throw if a filter object have been passed but without
 	        // any clearly idenfified filter.
 	        throw new Error("Unsupported argument given to getTab request");
 	      }
 	    }
-
+	
 	    return this.request(packet);
 	  },
-
+	
 	  /**
 	   * Description of protocol's actors and methods.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  protocolDescription: DebuggerClient.requester({ type: "protocolDescription" },
 	                                                 { telemetry: "PROTOCOLDESCRIPTION" }),
-
+	
 	  /*
 	   * Methods constructed by DebuggerClient.requester require these forwards
 	   * on their 'this'.
 	   */
 	  get _transport() { return this._client._transport; },
 	  get request() { return this._client.request; }
 	};
-
+	
 	/**
 	 * Creates a thread client for the remote debugging protocol server. This client
 	 * is a front to the thread actor created in the server side, hiding the
 	 * protocol details in a traditional JavaScript API.
 	 *
 	 * @param aClient DebuggerClient|TabClient
 	 *        The parent of the thread (tab for tab-scoped debuggers, DebuggerClient
 	 *        for chrome debuggers).
@@ -12042,37 +12020,37 @@ var Debugger =
 	  this.client = aClient instanceof DebuggerClient ? aClient : aClient.client;
 	  this._actor = aActor;
 	  this._frameCache = [];
 	  this._scriptCache = {};
 	  this._pauseGrips = {};
 	  this._threadGrips = {};
 	  this.request = this.client.request;
 	}
-
+	
 	ThreadClient.prototype = {
 	  _state: "paused",
 	  get state() { return this._state; },
 	  get paused() { return this._state === "paused"; },
-
+	
 	  _pauseOnExceptions: false,
 	  _ignoreCaughtExceptions: false,
 	  _pauseOnDOMEvents: null,
-
+	
 	  _actor: null,
 	  get actor() { return this._actor; },
-
+	
 	  get _transport() { return this.client._transport; },
-
+	
 	  _assertPaused: function(aCommand) {
 	    if (!this.paused) {
 	      throw Error(aCommand + " command sent while not paused. Currently " + this._state);
 	    }
 	  },
-
+	
 	  /**
 	   * Resume a paused thread. If the optional aLimit parameter is present, then
 	   * the thread will also pause when that limit is reached.
 	   *
 	   * @param [optional] object aLimit
 	   *        An object with a type property set to the appropriate limit (next,
 	   *        step, or finish) per the remote debugging protocol specification.
 	   *        Use null to specify no limit.
@@ -12080,21 +12058,21 @@ var Debugger =
 	   *        Called with the response packet.
 	   */
 	  _doResume: DebuggerClient.requester({
 	    type: "resume",
 	    resumeLimit: args(0)
 	  }, {
 	    before: function(aPacket) {
 	      this._assertPaused("resume");
-
+	
 	      // Put the client in a tentative "resuming" state so we can prevent
 	      // further requests that should only be sent in the paused state.
 	      this._state = "resuming";
-
+	
 	      if (this._pauseOnExceptions) {
 	        aPacket.pauseOnExceptions = this._pauseOnExceptions;
 	      }
 	      if (this._ignoreCaughtExceptions) {
 	        aPacket.ignoreCaughtExceptions = this._ignoreCaughtExceptions;
 	      }
 	      if (this._pauseOnDOMEvents) {
 	        aPacket.pauseOnDOMEvents = this._pauseOnDOMEvents;
@@ -12105,142 +12083,142 @@ var Debugger =
 	      if (aResponse.error) {
 	        // There was an error resuming, back to paused state.
 	        this._state = "paused";
 	      }
 	      return aResponse;
 	    },
 	    telemetry: "RESUME"
 	  }),
-
+	
 	  /**
 	   * Reconfigure the thread actor.
 	   *
 	   * @param object aOptions
 	   *        A dictionary object of the new options to use in the thread actor.
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  reconfigure: DebuggerClient.requester({
 	    type: "reconfigure",
 	    options: args(0)
 	  }, {
 	    telemetry: "RECONFIGURETHREAD"
 	  }),
-
+	
 	  /**
 	   * Resume a paused thread.
 	   */
 	  resume: function(aOnResponse) {
 	    return this._doResume(null, aOnResponse);
 	  },
-
+	
 	  /**
 	   * Resume then pause without stepping.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  resumeThenPause: function(aOnResponse) {
 	    return this._doResume({ type: "break" }, aOnResponse);
 	  },
-
+	
 	  /**
 	   * Step over a function call.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  stepOver: function(aOnResponse) {
 	    return this._doResume({ type: "next" }, aOnResponse);
 	  },
-
+	
 	  /**
 	   * Step into a function call.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  stepIn: function(aOnResponse) {
 	    return this._doResume({ type: "step" }, aOnResponse);
 	  },
-
+	
 	  /**
 	   * Step out of a function call.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  stepOut: function(aOnResponse) {
 	    return this._doResume({ type: "finish" }, aOnResponse);
 	  },
-
+	
 	  /**
 	   * Immediately interrupt a running thread.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  interrupt: function(aOnResponse) {
 	    return this._doInterrupt(null, aOnResponse);
 	  },
-
+	
 	  /**
 	   * Pause execution right before the next JavaScript bytecode is executed.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  breakOnNext: function(aOnResponse) {
 	    return this._doInterrupt("onNext", aOnResponse);
 	  },
-
+	
 	  /**
 	   * Interrupt a running thread.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  _doInterrupt: DebuggerClient.requester({
 	    type: "interrupt",
 	    when: args(0)
 	  }, {
 	    telemetry: "INTERRUPT"
 	  }),
-
+	
 	  /**
 	   * Enable or disable pausing when an exception is thrown.
 	   *
 	   * @param boolean aFlag
 	   *        Enables pausing if true, disables otherwise.
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  pauseOnExceptions: function(aPauseOnExceptions,
 	                               aIgnoreCaughtExceptions,
 	                               aOnResponse = noop) {
 	    this._pauseOnExceptions = aPauseOnExceptions;
 	    this._ignoreCaughtExceptions = aIgnoreCaughtExceptions;
-
+	
 	    // Otherwise send the flag using a standard resume request.
 	    if (!this.paused) {
 	      return this.interrupt(aResponse => {
 	        if (aResponse.error) {
 	          // Can't continue if pausing failed.
 	          aOnResponse(aResponse);
 	          return aResponse;
 	        }
 	        return this.resume(aOnResponse);
 	      });
 	    }
-
+	
 	    aOnResponse();
 	    return promise.resolve();
 	  },
-
+	
 	  /**
 	   * Enable pausing when the specified DOM events are triggered. Disabling
 	   * pausing on an event can be realized by calling this method with the updated
 	   * array of events that doesn't contain it.
 	   *
 	   * @param array|string events
 	   *        An array of strings, representing the DOM event types to pause on,
 	   *        or "*" to pause on all DOM events. Pass an empty array to
@@ -12261,17 +12239,17 @@ var Debugger =
 	      // Can't continue if pausing failed.
 	      if (response.error) {
 	        onResponse(response);
 	        return response;
 	      }
 	      return this.resume(onResponse);
 	    });
 	  },
-
+	
 	  /**
 	   * Send a clientEvaluate packet to the debuggee. Response
 	   * will be a resume packet.
 	   *
 	   * @param string aFrame
 	   *        The actor ID of the frame where the evaluation should take place.
 	   * @param string aExpression
 	   *        The expression that will be evaluated in the scope of the frame
@@ -12295,97 +12273,97 @@ var Debugger =
 	      if (aResponse.error) {
 	        // There was an error resuming, back to paused state.
 	        this._state = "paused";
 	      }
 	      return aResponse;
 	    },
 	    telemetry: "CLIENTEVALUATE"
 	  }),
-
+	
 	  /**
 	   * Detach from the thread actor.
 	   *
 	   * @param function aOnResponse
 	   *        Called with the response packet.
 	   */
 	  detach: DebuggerClient.requester({
 	    type: "detach"
 	  }, {
 	    after: function(aResponse) {
 	      this.client.unregisterClient(this);
 	      this._parent.thread = null;
 	      return aResponse;
 	    },
 	    telemetry: "THREADDETACH"
 	  }),
-
+	
 	  /**
 	   * Release multiple thread-lifetime object actors. If any pause-lifetime
 	   * actors are included in the request, a |notReleasable| error will return,
 	   * but all the thread-lifetime ones will have been released.
 	   *
 	   * @param array actors
 	   *        An array with actor IDs to release.
 	   */
 	  releaseMany: DebuggerClient.requester({
 	    type: "releaseMany",
 	    actors: args(0),
 	  }, {
 	    telemetry: "RELEASEMANY"
 	  }),
-
+	
 	  /**
 	   * Promote multiple pause-lifetime object actors to thread-lifetime ones.
 	   *
 	   * @param array actors
 	   *        An array with actor IDs to promote.
 	   */
 	  threadGrips: DebuggerClient.requester({
 	    type: "threadGrips",
 	    actors: args(0)
 	  }, {
 	    telemetry: "THREADGRIPS"
 	  }),
-
+	
 	  /**
 	   * Return the event listeners defined on the page.
 	   *
 	   * @param aOnResponse Function
 	   *        Called with the thread's response.
 	   */
 	  eventListeners: DebuggerClient.requester({
 	    type: "eventListeners"
 	  }, {
 	    telemetry: "EVENTLISTENERS"
 	  }),
-
+	
 	  /**
 	   * Request the loaded sources for the current thread.
 	   *
 	   * @param aOnResponse Function
 	   *        Called with the thread's response.
 	   */
 	  getSources: DebuggerClient.requester({
 	    type: "sources"
 	  }, {
 	    telemetry: "SOURCES"
 	  }),
-
+	
 	  /**
 	   * Clear the thread's source script cache. A scriptscleared event
 	   * will be sent.
 	   */
 	  _clearScripts: function() {
 	    if (Object.keys(this._scriptCache).length > 0) {
 	      this._scriptCache = {};
 	      this.emit("scriptscleared");
 	    }
 	  },
-
+	
 	  /**
 	   * Request frames from the callstack for the current thread.
 	   *
 	   * @param aStart integer
 	   *        The number of the youngest stack frame to return (the youngest
 	   *        frame is 0).
 	   * @param aCount integer
 	   *        The maximum number of frames to return, or null to return all
@@ -12395,240 +12373,240 @@ var Debugger =
 	   */
 	  getFrames: DebuggerClient.requester({
 	    type: "frames",
 	    start: args(0),
 	    count: args(1)
 	  }, {
 	    telemetry: "FRAMES"
 	  }),
-
+	
 	  /**
 	   * An array of cached frames. Clients can observe the framesadded and
 	   * framescleared event to keep up to date on changes to this cache,
 	   * and can fill it using the fillFrames method.
 	   */
 	  get cachedFrames() { return this._frameCache; },
-
+	
 	  /**
 	   * true if there are more stack frames available on the server.
 	   */
 	  get moreFrames() {
 	    return this.paused && (!this._frameCache || this._frameCache.length == 0
 	          || !this._frameCache[this._frameCache.length - 1].oldest);
 	  },
-
+	
 	  /**
 	   * Ensure that at least aTotal stack frames have been loaded in the
 	   * ThreadClient's stack frame cache. A framesadded event will be
 	   * sent when the stack frame cache is updated.
 	   *
 	   * @param aTotal number
 	   *        The minimum number of stack frames to be included.
 	   * @param aCallback function
 	   *        Optional callback function called when frames have been loaded
 	   * @returns true if a framesadded notification should be expected.
 	   */
 	  fillFrames: function(aTotal, aCallback = noop) {
 	    this._assertPaused("fillFrames");
 	    if (this._frameCache.length >= aTotal) {
 	      return false;
 	    }
-
+	
 	    let numFrames = this._frameCache.length;
-
+	
 	    this.getFrames(numFrames, aTotal - numFrames, (aResponse) => {
 	      if (aResponse.error) {
 	        aCallback(aResponse);
 	        return;
 	      }
-
+	
 	      let threadGrips = DevToolsUtils.values(this._threadGrips);
-
+	
 	      for (let i in aResponse.frames) {
 	        let frame = aResponse.frames[i];
 	        if (!frame.where.source) {
 	          // Older servers use urls instead, so we need to resolve
 	          // them to source actors
 	          for (let grip of threadGrips) {
 	            if (grip instanceof SourceClient && grip.url === frame.url) {
 	              frame.where.source = grip._form;
 	            }
 	          }
 	        }
-
+	
 	        this._frameCache[frame.depth] = frame;
 	      }
-
+	
 	      // If we got as many frames as we asked for, there might be more
 	      // frames available.
 	      this.emit("framesadded");
-
+	
 	      aCallback(aResponse);
 	    });
-
+	
 	    return true;
 	  },
-
+	
 	  /**
 	   * Clear the thread's stack frame cache. A framescleared event
 	   * will be sent.
 	   */
 	  _clearFrames: function() {
 	    if (this._frameCache.length > 0) {
 	      this._frameCache = [];
 	      this.emit("framescleared");
 	    }
 	  },
-
+	
 	  /**
 	   * Return a ObjectClient object for the given object grip.
 	   *
 	   * @param aGrip object
 	   *        A pause-lifetime object grip returned by the protocol.
 	   */
 	  pauseGrip: function(aGrip) {
 	    if (aGrip.actor in this._pauseGrips) {
 	      return this._pauseGrips[aGrip.actor];
 	    }
-
+	
 	    let client = new ObjectClient(this.client, aGrip);
 	    this._pauseGrips[aGrip.actor] = client;
 	    return client;
 	  },
-
+	
 	  /**
 	   * Get or create a long string client, checking the grip client cache if it
 	   * already exists.
 	   *
 	   * @param aGrip Object
 	   *        The long string grip returned by the protocol.
 	   * @param aGripCacheName String
 	   *        The property name of the grip client cache to check for existing
 	   *        clients in.
 	   */
 	  _longString: function(aGrip, aGripCacheName) {
 	    if (aGrip.actor in this[aGripCacheName]) {
 	      return this[aGripCacheName][aGrip.actor];
 	    }
-
+	
 	    let client = new LongStringClient(this.client, aGrip);
 	    this[aGripCacheName][aGrip.actor] = client;
 	    return client;
 	  },
-
+	
 	  /**
 	   * Return an instance of LongStringClient for the given long string grip that
 	   * is scoped to the current pause.
 	   *
 	   * @param aGrip Object
 	   *        The long string grip returned by the protocol.
 	   */
 	  pauseLongString: function(aGrip) {
 	    return this._longString(aGrip, "_pauseGrips");
 	  },
-
+	
 	  /**
 	   * Return an instance of LongStringClient for the given long string grip that
 	   * is scoped to the thread lifetime.
 	   *
 	   * @param aGrip Object
 	   *        The long string grip returned by the protocol.
 	   */
 	  threadLongString: function(aGrip) {
 	    return this._longString(aGrip, "_threadGrips");
 	  },
-
+	
 	  /**
 	   * Clear and invalidate all the grip clients from the given cache.
 	   *
 	   * @param aGripCacheName
 	   *        The property name of the grip cache we want to clear.
 	   */
 	  _clearObjectClients: function(aGripCacheName) {
 	    for (let id in this[aGripCacheName]) {
 	      this[aGripCacheName][id].valid = false;
 	    }
 	    this[aGripCacheName] = {};
 	  },
-
+	
 	  /**
 	   * Invalidate pause-lifetime grip clients and clear the list of current grip
 	   * clients.
 	   */
 	  _clearPauseGrips: function() {
 	    this._clearObjectClients("_pauseGrips");
 	  },
-
+	
 	  /**
 	   * Invalidate thread-lifetime grip clients and clear the list of current grip
 	   * clients.
 	   */
 	  _clearThreadGrips: function() {
 	    this._clearObjectClients("_threadGrips");
 	  },
-
+	
 	  /**
 	   * Handle thread state change by doing necessary cleanup and notifying all
 	   * registered listeners.
 	   */
 	  _onThreadState: function(aPacket) {
 	    this._state = ThreadStateTypes[aPacket.type];
 	    // The debugger UI may not be initialized yet so we want to keep
 	    // the packet around so it knows what to pause state to display
 	    // when it's initialized
 	    this._lastPausePacket = aPacket.type === "resumed" ? null : aPacket;
 	    this._clearFrames();
 	    this._clearPauseGrips();
 	    aPacket.type === ThreadStateTypes.detached && this._clearThreadGrips();
 	    this.client._eventsEnabled && this.emit(aPacket.type, aPacket);
 	  },
-
+	
 	  getLastPausePacket: function() {
 	    return this._lastPausePacket;
 	  },
-
+	
 	  /**
 	   * Return an EnvironmentClient instance for the given environment actor form.
 	   */
 	  environment: function(aForm) {
 	    return new EnvironmentClient(this.client, aForm);
 	  },
-
+	
 	  /**
 	   * Return an instance of SourceClient for the given source actor form.
 	   */
 	  source: function(aForm) {
 	    if (aForm.actor in this._threadGrips) {
 	      return this._threadGrips[aForm.actor];
 	    }
-
+	
 	    return this._threadGrips[aForm.actor] = new SourceClient(this, aForm);
 	  },
-
+	
 	  /**
 	   * Request the prototype and own properties of mutlipleObjects.
 	   *
 	   * @param aOnResponse function
 	   *        Called with the request's response.
 	   * @param actors [string]
 	   *        List of actor ID of the queried objects.
 	   */
 	  getPrototypesAndProperties: DebuggerClient.requester({
 	    type: "prototypesAndProperties",
 	    actors: args(0)
 	  }, {
 	    telemetry: "PROTOTYPESANDPROPERTIES"
 	  }),
-
+	
 	  events: ["newSource"]
 	};
-
+	
 	eventSource(ThreadClient.prototype);
-
+	
 	/**
 	 * Creates a tracing profiler client for the remote debugging protocol
 	 * server. This client is a front to the trace actor created on the
 	 * server side, hiding the protocol details in a traditional
 	 * JavaScript API.
 	 *
 	 * @param aClient DebuggerClient
 	 *        The debugger client parent.
@@ -12639,36 +12617,36 @@ var Debugger =
 	  this._client = aClient;
 	  this._actor = aActor;
 	  this._activeTraces = new Set();
 	  this._waitingPackets = new Map();
 	  this._expectedPacket = 0;
 	  this.request = this._client.request;
 	  this.events = [];
 	}
-
+	
 	TraceClient.prototype = {
 	  get actor() { return this._actor; },
 	  get tracing() { return this._activeTraces.size > 0; },
-
+	
 	  get _transport() { return this._client._transport; },
-
+	
 	  /**
 	   * Detach from the trace actor.
 	   */
 	  detach: DebuggerClient.requester({
 	    type: "detach"
 	  }, {
 	    after: function(aResponse) {
 	      this._client.unregisterClient(this);
 	      return aResponse;
 	    },
 	    telemetry: "TRACERDETACH"
 	  }),
-
+	
 	  /**
 	   * Start a new trace.
 	   *
 	   * @param aTrace [string]
 	   *        An array of trace types to be recorded by the new trace.
 	   *
 	   * @param aName string
 	   *        The name of the new trace.
@@ -12680,28 +12658,28 @@ var Debugger =
 	    type: "startTrace",
 	    name: args(1),
 	    trace: args(0)
 	  }, {
 	    after: function(aResponse) {
 	      if (aResponse.error) {
 	        return aResponse;
 	      }
-
+	
 	      if (!this.tracing) {
 	        this._waitingPackets.clear();
 	        this._expectedPacket = 0;
 	      }
 	      this._activeTraces.add(aResponse.name);
-
+	
 	      return aResponse;
 	    },
 	    telemetry: "STARTTRACE"
 	  }),
-
+	
 	  /**
 	   * End a trace. If a name is provided, stop the named
 	   * trace. Otherwise, stop the most recently started trace.
 	   *
 	   * @param aName string
 	   *        The name of the trace to stop.
 	   *
 	   * @param aOnResponse function
@@ -12710,68 +12688,68 @@ var Debugger =
 	  stopTrace: DebuggerClient.requester({
 	    type: "stopTrace",
 	    name: args(0)
 	  }, {
 	    after: function(aResponse) {
 	      if (aResponse.error) {
 	        return aResponse;
 	      }
-
+	
 	      this._activeTraces.delete(aResponse.name);
-
+	
 	      return aResponse;
 	    },
 	    telemetry: "STOPTRACE"
 	  })
 	};
-
+	
 	/**
 	 * Grip clients are used to retrieve information about the relevant object.
 	 *
 	 * @param aClient DebuggerClient
 	 *        The debugger client parent.
 	 * @param aGrip object
 	 *        A pause-lifetime object grip returned by the protocol.
 	 */
 	function ObjectClient(aClient, aGrip)
 	{
 	  this._grip = aGrip;
 	  this._client = aClient;
 	  this.request = this._client.request;
 	}
 	exports.ObjectClient = ObjectClient;
-
+	
 	ObjectClient.prototype = {
 	  get actor() { return this._grip.actor; },
 	  get _transport() { return this._client._transport; },
-
+	
 	  valid: true,
-
+	
 	  get isFrozen() {
 	    return this._grip.frozen;
 	  },
 	  get isSealed() {
 	    return this._grip.sealed;
 	  },
 	  get isExtensible() {
 	    return this._grip.extensible;
 	  },
-
+	
 	  getDefinitionSite: DebuggerClient.requester({
 	    type: "definitionSite"
 	  }, {
 	    before: function(aPacket) {
 	      if (this._grip.class != "Function") {
 	        throw new Error("getDefinitionSite is only valid for function grips.");
 	      }
 	      return aPacket;
 	    }
 	  }),
-
+	
 	  /**
 	   * Request the names of a function's formal parameters.
 	   *
 	   * @param aOnResponse function
 	   *        Called with an object of the form:
 	   *        { parameterNames:[<parameterName>, ...] }
 	   *        where each <parameterName> is the name of a parameter.
 	   */
@@ -12781,40 +12759,40 @@ var Debugger =
 	    before: function(aPacket) {
 	      if (this._grip.class !== "Function") {
 	        throw new Error("getParameterNames is only valid for function grips.");
 	      }
 	      return aPacket;
 	    },
 	    telemetry: "PARAMETERNAMES"
 	  }),
-
+	
 	  /**
 	   * Request the names of the properties defined on the object and not its
 	   * prototype.
 	   *
 	   * @param aOnResponse function Called with the request's response.
 	   */
 	  getOwnPropertyNames: DebuggerClient.requester({
 	    type: "ownPropertyNames"
 	  }, {
 	    telemetry: "OWNPROPERTYNAMES"
 	  }),
-
+	
 	  /**
 	   * Request the prototype and own properties of the object.
 	   *
 	   * @param aOnResponse function Called with the request's response.
 	   */
 	  getPrototypeAndProperties: DebuggerClient.requester({
 	    type: "prototypeAndProperties"
 	  }, {
 	    telemetry: "PROTOTYPEANDPROPERTIES"
 	  }),
-
+	
 	  /**
 	   * Request a PropertyIteratorClient instance to ease listing
 	   * properties for this object.
 	   *
 	   * @param options Object
 	   *        A dictionary object with various boolean attributes:
 	   *        - ignoreSafeGetters Boolean
 	   *          If true, do not iterate over safe getters.
@@ -12837,17 +12815,17 @@ var Debugger =
 	    after: function(aResponse) {
 	      if (aResponse.iterator) {
 	        return { iterator: new PropertyIteratorClient(this._client, aResponse.iterator) };
 	      }
 	      return aResponse;
 	    },
 	    telemetry: "ENUMPROPERTIES"
 	  }),
-
+	
 	  /**
 	   * Request a PropertyIteratorClient instance to enumerate entries in a
 	   * Map/Set-like object.
 	   *
 	   * @param aOnResponse function Called with the request's response.
 	   */
 	  enumEntries: DebuggerClient.requester({
 	    type: "enumEntries"
@@ -12862,129 +12840,129 @@ var Debugger =
 	      if (response.iterator) {
 	        return {
 	          iterator: new PropertyIteratorClient(this._client, response.iterator)
 	        };
 	      }
 	      return response;
 	    }
 	  }),
-
+	
 	  /**
 	   * Request the property descriptor of the object's specified property.
 	   *
 	   * @param aName string The name of the requested property.
 	   * @param aOnResponse function Called with the request's response.
 	   */
 	  getProperty: DebuggerClient.requester({
 	    type: "property",
 	    name: args(0)
 	  }, {
 	    telemetry: "PROPERTY"
 	  }),
-
+	
 	  /**
 	   * Request the prototype of the object.
 	   *
 	   * @param aOnResponse function Called with the request's response.
 	   */
 	  getPrototype: DebuggerClient.requester({
 	    type: "prototype"
 	  }, {
 	    telemetry: "PROTOTYPE"
 	  }),
-
+	
 	  /**
 	   * Request the display string of the object.
 	   *
 	   * @param aOnResponse function Called with the request's response.
 	   */
 	  getDisplayString: DebuggerClient.requester({
 	    type: "displayString"
 	  }, {
 	    telemetry: "DISPLAYSTRING"
 	  }),
-
+	
 	  /**
 	   * Request the scope of the object.
 	   *
 	   * @param aOnResponse function Called with the request's response.
 	   */
 	  getScope: DebuggerClient.requester({
 	    type: "scope"
 	  }, {
 	    before: function(aPacket) {
 	      if (this._grip.class !== "Function") {
 	        throw new Error("scope is only valid for function grips.");
 	      }
 	      return aPacket;
 	    },
 	    telemetry: "SCOPE"
 	  }),
-
+	
 	  /**
 	   * Request the promises directly depending on the current promise.
 	   */
 	  getDependentPromises: DebuggerClient.requester({
 	    type: "dependentPromises"
 	  }, {
 	    before: function(aPacket) {
 	      if (this._grip.class !== "Promise") {
 	        throw new Error("getDependentPromises is only valid for promise " +
 	          "grips.");
 	      }
 	      return aPacket;
 	    }
 	  }),
-
+	
 	  /**
 	   * Request the stack to the promise's allocation point.
 	   */
 	  getPromiseAllocationStack: DebuggerClient.requester({
 	    type: "allocationStack"
 	  }, {
 	    before: function(aPacket) {
 	      if (this._grip.class !== "Promise") {
 	        throw new Error("getAllocationStack is only valid for promise grips.");
 	      }
 	      return aPacket;
 	    }
 	  }),
-
+	
 	  /**
 	   * Request the stack to the promise's fulfillment point.
 	   */
 	  getPromiseFulfillmentStack: DebuggerClient.requester({
 	    type: "fulfillmentStack"
 	  }, {
 	    before: function(packet) {
 	      if (this._grip.class !== "Promise") {
 	        throw new Error("getPromiseFulfillmentStack is only valid for " +
 	          "promise grips.");
 	      }
 	      return packet;
 	    }
 	  }),
-
+	
 	  /**
 	   * Request the stack to the promise's rejection point.
 	   */
 	  getPromiseRejectionStack: DebuggerClient.requester({
 	    type: "rejectionStack"
 	  }, {
 	    before: function(packet) {
 	      if (this._grip.class !== "Promise") {
 	        throw new Error("getPromiseRejectionStack is only valid for " +
 	          "promise grips.");
 	      }
 	      return packet;
 	    }
 	  })
 	};
-
+	
 	/**
 	 * A PropertyIteratorClient provides a way to access to property names and
 	 * values of an object efficiently, slice by slice.
 	 * Note that the properties can be sorted in the backend,
 	 * this is controled while creating the PropertyIteratorClient
 	 * from ObjectClient.enumProperties.
 	 *
 	 * @param aClient DebuggerClient
@@ -12993,90 +12971,90 @@ var Debugger =
 	 *        A PropertyIteratorActor grip returned by the protocol via
 	 *        TabActor.enumProperties request.
 	 */
 	function PropertyIteratorClient(aClient, aGrip) {
 	  this._grip = aGrip;
 	  this._client = aClient;
 	  this.request = this._client.request;
 	}
-
+	
 	PropertyIteratorClient.prototype = {
 	  get actor() { return this._grip.actor; },
-
+	
 	  /**
 	   * Get the total number of properties available in the iterator.
 	   */
 	  get count() { return this._grip.count; },
-
+	
 	  /**
 	   * Get one or more property names that correspond to the positions in the
 	   * indexes parameter.
 	   *
 	   * @param indexes Array
 	   *        An array of property indexes.
 	   * @param aCallback Function
 	   *        The function called when we receive the property names.
 	   */
 	  names: DebuggerClient.requester({
 	    type: "names",
 	    indexes: args(0)
 	  }, {}),
-
+	
 	  /**
 	   * Get a set of following property value(s).
 	   *
 	   * @param start Number
 	   *        The index of the first property to fetch.
 	   * @param count Number
 	   *        The number of properties to fetch.
 	   * @param aCallback Function
 	   *        The function called when we receive the property values.
 	   */
 	  slice: DebuggerClient.requester({
 	    type: "slice",
 	    start: args(0),
 	    count: args(1)
 	  }, {}),
-
+	
 	  /**
 	   * Get all the property values.
 	   *
 	   * @param aCallback Function
 	   *        The function called when we receive the property values.
 	   */
 	  all: DebuggerClient.requester({
 	    type: "all"
 	  }, {}),
 	};
-
+	
 	/**
 	 * A LongStringClient provides a way to access "very long" strings from the
 	 * debugger server.
 	 *
 	 * @param aClient DebuggerClient
 	 *        The debugger client parent.
 	 * @param aGrip Object
 	 *        A pause-lifetime long string grip returned by the protocol.
 	 */
 	function LongStringClient(aClient, aGrip) {
 	  this._grip = aGrip;
 	  this._client = aClient;
 	  this.request = this._client.request;
 	}
 	exports.LongStringClient = LongStringClient;
-
+	
 	LongStringClient.prototype = {
 	  get actor() { return this._grip.actor; },
 	  get length() { return this._grip.length; },
 	  get initial() { return this._grip.initial; },
 	  get _transport() { return this._client._transport; },
-
+	
 	  valid: true,
-
+	
 	  /**
 	   * Get the substring of this LongString from aStart to aEnd.
 	   *
 	   * @param aStart Number
 	   *        The starting index.
 	   * @param aEnd Number
 	   *        The ending index.
 	   * @param aCallback Function
@@ -13085,33 +13063,33 @@ var Debugger =
 	  substring: DebuggerClient.requester({
 	    type: "substring",
 	    start: args(0),
 	    end: args(1)
 	  }, {
 	    telemetry: "SUBSTRING"
 	  }),
 	};
-
+	
 	/**
 	 * A SourceClient provides a way to access the source text of a script.
 	 *
 	 * @param aClient ThreadClient
 	 *        The thread client parent.
 	 * @param aForm Object
 	 *        The form sent across the remote debugging protocol.
 	 */
 	function SourceClient(aClient, aForm) {
 	  this._form = aForm;
 	  this._isBlackBoxed = aForm.isBlackBoxed;
 	  this._isPrettyPrinted = aForm.isPrettyPrinted;
 	  this._activeThread = aClient;
 	  this._client = aClient.client;
 	}
-
+	
 	SourceClient.prototype = {
 	  get _transport() {
 	    return this._client._transport;
 	  },
 	  get isBlackBoxed() {
 	    return this._isBlackBoxed;
 	  },
 	  get isPrettyPrinted() {
@@ -13121,17 +13099,17 @@ var Debugger =
 	    return this._form.actor;
 	  },
 	  get request() {
 	    return this._client.request;
 	  },
 	  get url() {
 	    return this._form.url;
 	  },
-
+	
 	  /**
 	   * Black box this SourceClient's source.
 	   *
 	   * @param aCallback Function
 	   *        The callback function called when we receive the response from the server.
 	   */
 	  blackBox: DebuggerClient.requester({
 	    type: "blackbox"
@@ -13142,17 +13120,17 @@ var Debugger =
 	        this._isBlackBoxed = true;
 	        if (this._activeThread) {
 	          this._activeThread.emit("blackboxchange", this);
 	        }
 	      }
 	      return aResponse;
 	    }
 	  }),
-
+	
 	  /**
 	   * Un-black box this SourceClient's source.
 	   *
 	   * @param aCallback Function
 	   *        The callback function called when we receive the response from the server.
 	   */
 	  unblackBox: DebuggerClient.requester({
 	    type: "unblackbox"
@@ -13163,48 +13141,48 @@ var Debugger =
 	        this._isBlackBoxed = false;
 	        if (this._activeThread) {
 	          this._activeThread.emit("blackboxchange", this);
 	        }
 	      }
 	      return aResponse;
 	    }
 	  }),
-
+	
 	  /**
 	   * Get Executable Lines from a source
 	   *
 	   * @param aCallback Function
 	   *        The callback function called when we receive the response from the server.
 	   */
 	  getExecutableLines: function(cb = noop) {
 	    let packet = {
 	      to: this._form.actor,
 	      type: "getExecutableLines"
 	    };
-
+	
 	    return this._client.request(packet).then(res => {
 	      cb(res.lines);
 	      return res.lines;
 	    });
 	  },
-
+	
 	  /**
 	   * Get a long string grip for this SourceClient's source.
 	   */
 	  source: function(aCallback = noop) {
 	    let packet = {
 	      to: this._form.actor,
 	      type: "source"
 	    };
 	    return this._client.request(packet).then(aResponse => {
 	      return this._onSourceResponse(aResponse, aCallback);
 	    });
 	  },
-
+	
 	  /**
 	   * Pretty print this source's text.
 	   */
 	  prettyPrint: function(aIndent, aCallback = noop) {
 	    const packet = {
 	      to: this._form.actor,
 	      type: "prettyPrint",
 	      indent: aIndent
@@ -13213,17 +13191,17 @@ var Debugger =
 	      if (!aResponse.error) {
 	        this._isPrettyPrinted = true;
 	        this._activeThread._clearFrames();
 	        this._activeThread.emit("prettyprintchange", this);
 	      }
 	      return this._onSourceResponse(aResponse, aCallback);
 	    });
 	  },
-
+	
 	  /**
 	   * Stop pretty printing this source's text.
 	   */
 	  disablePrettyPrint: function(aCallback = noop) {
 	    const packet = {
 	      to: this._form.actor,
 	      type: "disablePrettyPrint"
 	    };
@@ -13231,45 +13209,45 @@ var Debugger =
 	      if (!aResponse.error) {
 	        this._isPrettyPrinted = false;
 	        this._activeThread._clearFrames();
 	        this._activeThread.emit("prettyprintchange", this);
 	      }
 	      return this._onSourceResponse(aResponse, aCallback);
 	    });
 	  },
-
+	
 	  _onSourceResponse: function(aResponse, aCallback) {
 	    if (aResponse.error) {
 	      aCallback(aResponse);
 	      return aResponse;
 	    }
-
+	
 	    if (typeof aResponse.source === "string") {
 	      aCallback(aResponse);
 	      return aResponse;
 	    }
-
+	
 	    let { contentType, source } = aResponse;
 	    let longString = this._activeThread.threadLongString(source);
 	    return longString.substring(0, longString.length).then(function(aResponse) {
 	      if (aResponse.error) {
 	        aCallback(aResponse);
 	        return aReponse;
 	      }
-
+	
 	      let response = {
 	        source: aResponse.substring,
 	        contentType: contentType
 	      };
 	      aCallback(response);
 	      return response;
 	    });
 	  },
-
+	
 	  /**
 	   * Request to set a breakpoint in the specified location.
 	   *
 	   * @param object aLocation
 	   *        The location and condition of the breakpoint in
 	   *        the form of { line[, column, condition] }.
 	   * @param function aOnResponse
 	   *        Called with the thread's response.
@@ -13277,32 +13255,32 @@ var Debugger =
 	  setBreakpoint: function({ line, column, condition, noSliding }, aOnResponse = noop) {
 	    // A helper function that sets the breakpoint.
 	    let doSetBreakpoint = aCallback => {
 	      let root = this._client.mainRoot;
 	      let location = {
 	        line: line,
 	        column: column
 	      };
-
+	
 	      let packet = {
 	        to: this.actor,
 	        type: "setBreakpoint",
 	        location: location,
 	        condition: condition,
 	        noSliding: noSliding
 	      };
-
+	
 	      // Backwards compatibility: send the breakpoint request to the
 	      // thread if the server doesn't support Debugger.Source actors.
 	      if (!root.traits.debuggerSourceActors) {
 	        packet.to = this._activeThread.actor;
 	        packet.location.url = this.url;
 	      }
-
+	
 	      return this._client.request(packet).then(aResponse => {
 	        // Ignoring errors, since the user may be setting a breakpoint in a
 	        // dead script that will reappear on a page reload.
 	        let bpClient;
 	        if (aResponse.actor) {
 	          bpClient = new BreakpointClient(
 	            this._client,
 	            this,
@@ -13313,39 +13291,39 @@ var Debugger =
 	        }
 	        aOnResponse(aResponse, bpClient);
 	        if (aCallback) {
 	          aCallback();
 	        }
 	        return [aResponse, bpClient];
 	      });
 	    };
-
+	
 	    // If the debuggee is paused, just set the breakpoint.
 	    if (this._activeThread.paused) {
 	      return doSetBreakpoint();
 	    }
 	    // Otherwise, force a pause in order to set the breakpoint.
 	    return this._activeThread.interrupt().then(aResponse => {
 	      if (aResponse.error) {
 	        // Can't set the breakpoint if pausing failed.
 	        aOnResponse(aResponse);
 	        return aResponse;
 	      }
-
+	
 	      const { type, why } = aResponse;
 	      const cleanUp = type == "paused" && why.type == "interrupted"
 	            ? () => this._activeThread.resume()
 	            : noop;
-
+	
 	      return doSetBreakpoint(cleanUp);
 	    });
 	  }
 	};
-
+	
 	/**
 	 * Breakpoint clients are used to remove breakpoints that are no longer used.
 	 *
 	 * @param aClient DebuggerClient
 	 *        The debugger client parent.
 	 * @param aSourceClient SourceClient
 	 *        The source where this breakpoint exists
 	 * @param aActor string
@@ -13359,91 +13337,91 @@ var Debugger =
 	function BreakpointClient(aClient, aSourceClient, aActor, aLocation, aCondition) {
 	  this._client = aClient;
 	  this._actor = aActor;
 	  this.location = aLocation;
 	  this.location.actor = aSourceClient.actor;
 	  this.location.url = aSourceClient.url;
 	  this.source = aSourceClient;
 	  this.request = this._client.request;
-
+	
 	  // The condition property should only exist if it's a truthy value
 	  if (aCondition) {
 	    this.condition = aCondition;
 	  }
 	}
-
+	
 	BreakpointClient.prototype = {
-
+	
 	  _actor: null,
 	  get actor() { return this._actor; },
 	  get _transport() { return this._client._transport; },
-
+	
 	  /**
 	   * Remove the breakpoint from the server.
 	   */
 	  remove: DebuggerClient.requester({
 	    type: "delete"
 	  }, {
 	    telemetry: "DELETE"
 	  }),
-
+	
 	  /**
 	   * Determines if this breakpoint has a condition
 	   */
 	  hasCondition: function() {
 	    let root = this._client.mainRoot;
 	    // XXX bug 990137: We will remove support for client-side handling of
 	    // conditional breakpoints
 	    if (root.traits.conditionalBreakpoints) {
 	      return "condition" in this;
 	    } else {
 	      return "conditionalExpression" in this;
 	    }
 	  },
-
+	
 	  /**
 	   * Get the condition of this breakpoint. Currently we have to
 	   * support locally emulated conditional breakpoints until the
 	   * debugger servers are updated (see bug 990137). We used a
 	   * different property when moving it server-side to ensure that we
 	   * are testing the right code.
 	   */
 	  getCondition: function() {
 	    let root = this._client.mainRoot;
 	    if (root.traits.conditionalBreakpoints) {
 	      return this.condition;
 	    } else {
 	      return this.conditionalExpression;
 	    }
 	  },
-
+	
 	  /**
 	   * Set the condition of this breakpoint
 	   */
 	  setCondition: function(gThreadClient, aCondition, noSliding) {
 	    let root = this._client.mainRoot;
 	    let deferred = promise.defer();
-
+	
 	    if (root.traits.conditionalBreakpoints) {
 	      let info = {
 	        line: this.location.line,
 	        column: this.location.column,
 	        condition: aCondition,
 	        noSliding
 	      };
-
+	
 	      // Remove the current breakpoint and add a new one with the
 	      // condition.
 	      this.remove(aResponse => {
 	        if (aResponse && aResponse.error) {
 	          deferred.reject(aResponse);
 	          return;
 	        }
-
+	
 	        this.source.setBreakpoint(info, (aResponse, aNewBreakpoint) => {
 	          if (aResponse && aResponse.error) {
 	            deferred.reject(aResponse);
 	          } else {
 	            deferred.resolve(aNewBreakpoint);
 	          }
 	        });
 	      });
@@ -13452,126 +13430,126 @@ var Debugger =
 	      if (aCondition === "") {
 	        delete this.conditionalExpression;
 	      }
 	      else {
 	        this.conditionalExpression = aCondition;
 	      }
 	      deferred.resolve(this);
 	    }
-
+	
 	    return deferred.promise;
 	  }
 	};
-
+	
 	eventSource(BreakpointClient.prototype);
-
+	
 	/**
 	 * Environment clients are used to manipulate the lexical environment actors.
 	 *
 	 * @param aClient DebuggerClient
 	 *        The debugger client parent.
 	 * @param aForm Object
 	 *        The form sent across the remote debugging protocol.
 	 */
 	function EnvironmentClient(aClient, aForm) {
 	  this._client = aClient;
 	  this._form = aForm;
 	  this.request = this._client.request;
 	}
 	exports.EnvironmentClient = EnvironmentClient;
-
+	
 	EnvironmentClient.prototype = {
-
+	
 	  get actor() {
 	    return this._form.actor;
 	  },
 	  get _transport() { return this._client._transport; },
-
+	
 	  /**
 	   * Fetches the bindings introduced by this lexical environment.
 	   */
 	  getBindings: DebuggerClient.requester({
 	    type: "bindings"
 	  }, {
 	    telemetry: "BINDINGS"
 	  }),
-
+	
 	  /**
 	   * Changes the value of the identifier whose name is name (a string) to that
 	   * represented by value (a grip).
 	   */
 	  assign: DebuggerClient.requester({
 	    type: "assign",
 	    name: args(0),
 	    value: args(1)
 	  }, {
 	    telemetry: "ASSIGN"
 	  })
 	};
-
+	
 	eventSource(EnvironmentClient.prototype);
 
 
 /***/ },
 /* 54 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* WEBPACK VAR INJECTION */(function(module) {/* This Source Code Form is subject to the terms of the Mozilla Public
 	 * License, v. 2.0. If a copy of the MPL was not distributed with this
 	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 	"use strict";
-
+	
 	module.metadata = {
 	  "stability": "unstable"
 	};
-
+	
 	const UNCAUGHT_ERROR = 'An error event was emitted for which there was no listener.';
 	const BAD_LISTENER = 'The event listener must be a function.';
-
+	
 	const { ns } = __webpack_require__(55);
-
+	
 	const event = ns();
-
+	
 	const EVENT_TYPE_PATTERN = /^on([A-Z]\w+$)/;
 	exports.EVENT_TYPE_PATTERN = EVENT_TYPE_PATTERN;
-
+	
 	// Utility function to access given event `target` object's event listeners for
 	// the specific event `type`. If listeners for this type does not exists they
 	// will be created.
 	const observers = function observers(target, type) {
 	  if (!target) throw TypeError("Event target must be an object");
 	  let listeners = event(target);
 	  return type in listeners ? listeners[type] : listeners[type] = [];
 	};
-
+	
 	/**
 	 * Registers an event `listener` that is called every time events of
 	 * specified `type` is emitted on the given event `target`.
 	 * @param {Object} target
 	 *    Event target object.
 	 * @param {String} type
 	 *    The type of event.
 	 * @param {Function} listener
 	 *    The listener function that processes the event.
 	 */
 	function on(target, type, listener) {
 	  if (typeof(listener) !== 'function')
 	    throw new Error(BAD_LISTENER);
-
+	
 	  let listeners = observers(target, type);
 	  if (!~listeners.indexOf(listener))
 	    listeners.push(listener);
 	}
 	exports.on = on;
-
-
+	
+	
 	var onceWeakMap = new WeakMap();
-
-
+	
+	
 	/**
 	 * Registers an event `listener` that is called only the next time an event
 	 * of the specified `type` is emitted on the given event `target`.
 	 * @param {Object} target
 	 *    Event target object.
 	 * @param {String} type
 	 *    The type of the event.
 	 * @param {Function} listener
@@ -13582,17 +13560,17 @@ var Debugger =
 	    off(target, type, observer);
 	    onceWeakMap.delete(listener);
 	    listener.apply(target, args);
 	  };
 	  onceWeakMap.set(listener, replacement);
 	  on(target, type, replacement);
 	}
 	exports.once = once;
-
+	
 	/**
 	 * Execute each of the listeners in order with the supplied arguments.
 	 * All the exceptions that are thrown by listeners during the emit
 	 * are caught and can be handled by listeners of 'error' event. Thrown
 	 * exceptions are passed as an argument to an 'error' event listener.
 	 * If no 'error' listener is registered exception will be logged into an
 	 * error console.
 	 * @param {Object} target
@@ -13601,27 +13579,27 @@ var Debugger =
 	 *    The type of event.
 	 * @params {Object|Number|String|Boolean} args
 	 *    Arguments that will be passed to listeners.
 	 */
 	function emit (target, type, ...args) {
 	  emitOnObject(target, type, target, ...args);
 	}
 	exports.emit = emit;
-
+	
 	/**
 	 * A variant of emit that allows setting the this property for event listeners
 	 */
 	function emitOnObject(target, type, thisArg, ...args) {
 	  let all = observers(target, '*').length;
 	  let state = observers(target, type);
 	  let listeners = state.slice();
 	  let count = listeners.length;
 	  let index = 0;
-
+	
 	  // If error event and there are no handlers (explicit or catch-all)
 	  // then print error message to the console.
 	  if (count === 0 && type === 'error' && all === 0)
 	    console.exception(args[0]);
 	  while (index < count) {