Bug 1415300 - Update Debugger frontend (11-7). r=jdescottes, a=gchang
authorJason Laster <jason.laster.11@gmail.com>
Fri, 10 Nov 2017 12:04:10 +0100
changeset 444782 fb1d0acce911246a649a595072a7b12ee7ac2833
parent 444781 70b42ae89f23a5a9a17aaebc4a7c9f33150b6547
child 444783 d42d5cea8c10efee8d1f5bc1173d5e4be3bb039c
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes, gchang
bugs1415300
milestone58.0
Bug 1415300 - Update Debugger frontend (11-7). r=jdescottes, a=gchang Taken from upstream commit: be179268c9b89390c13bdc9c4cca6000f6f583e5 Added skip-if true to some new debugger mochitests that still look intermittent. MozReview-Commit-ID: EIcx5z9s7XF
devtools/client/debugger/new/README.mozilla
devtools/client/debugger/new/debugger.css
devtools/client/debugger/new/debugger.js
devtools/client/debugger/new/parser-worker.js
devtools/client/debugger/new/pretty-print-worker.js
devtools/client/debugger/new/search-worker.js
devtools/client/debugger/new/test/mochitest/browser.ini
devtools/client/debugger/new/test/mochitest/browser_dbg-breaking.js
devtools/client/debugger/new/test/mochitest/browser_dbg-debugger-buttons.js
devtools/client/debugger/new/test/mochitest/browser_dbg-editor-select.js
devtools/client/debugger/new/test/mochitest/browser_dbg-expressions-error.js
devtools/client/debugger/new/test/mochitest/browser_dbg-navigation.js
devtools/client/debugger/new/test/mochitest/browser_dbg-pause-exceptions.js
devtools/client/debugger/new/test/mochitest/browser_dbg-preview.js
devtools/client/debugger/new/test/mochitest/browser_dbg-quick-open.js
devtools/client/debugger/new/test/mochitest/browser_dbg-returnvalues.js
devtools/client/debugger/new/test/mochitest/browser_dbg-scopes-mutations.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps2.js
devtools/client/debugger/new/test/mochitest/browser_dbg-wasm-sourcemaps.js
devtools/client/debugger/new/test/mochitest/examples/doc-scripts.html
devtools/client/debugger/new/test/mochitest/examples/simple1.js
devtools/client/debugger/new/test/mochitest/examples/simple3.js
devtools/client/debugger/new/test/mochitest/head.js
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,11 +1,11 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Taken from upstream commit: d9f18b2cd0792de70289d4dcde5ed3e38be87cf1
+Taken from upstream commit: be179268c9b89390c13bdc9c4cca6000f6f583e5
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.0
 - babel-preset-react @6.24.1
 - react @15.6.2
 - react-dom @15.6.2
 - webpack @3.8.1
--- a/devtools/client/debugger/new/debugger.css
+++ b/devtools/client/debugger/new/debugger.css
@@ -405,16 +405,20 @@ body {
   .sidebar
   .title-wrapper
   .launchpad-container
   .launchpad-container-title {
   display: inline;
   padding-left: 3px;
   font-weight: normal;
 }
+/* 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/>. */
+
 .modal-wrapper {
   position: fixed;
   display: flex;
   flex-direction: column;
   align-items: center;
   width: 100%;
   height: 100%;
   top: 0;
@@ -468,43 +472,33 @@ body {
     height: auto;
     max-height: 80vh;
   }
   .modal.entered,
   .modal.exiting {
     transform: translateY(30px);
   }
 }
+/* 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/>. */
+
 .shortcuts-content {
   padding: 15px;
   -moz-column-width: 250px;
   -webkit-column-width: 250px;
   column-width: 250px;
 }
 
 .shortcuts-content h2 {
   margin-top: 2px;
   margin-bottom: 2px;
   color: var(--theme-content-color1);
 }
 
-.mac .keystroke {
-  border-style: solid;
-  border-width: 1px;
-  border-radius: 3px;
-  border-color: var(--theme-graphs-grey);
-  background-color: var(--theme-selection-color);
-  width: 21px;
-  height: 17px;
-  display: inline-block;
-  font-size: 10px;
-  text-align: center;
-  padding-top: 2px;
-}
-
 .shortcuts-section {
   display: inline-block;
   margin: 5px;
   margin-bottom: 15px;
   width: 250px;
 }
 
 .shortcuts-list {
@@ -524,31 +518,39 @@ body {
   border: 1px solid transparent;
 }
 
 @media (max-width: 640px) {
   .shortcuts-section {
     width: 100%;
   }
 }
+/* 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 {
   --arrow-width: 10px;
 }
 
 :root.theme-light,
 :root .theme-light {
   --search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
   --popup-shadow-color: #d0d0d0;
 }
 
 :root.theme-dark,
 :root .theme-dark {
   --search-overlays-semitransparent: rgba(42, 46, 56, 0.66);
   --popup-shadow-color: #5c667b;
 }
+/* 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/>. */
+
 * {
   box-sizing: border-box;
 }
 
 button {
   background: transparent;
   outline: none;
   border: none;
@@ -597,16 +599,20 @@ button:focus {
 
 /* Utils */
 .absolute-center {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
 }
+/* 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/>. */
+
 menupopup {
   position: fixed;
   z-index: 10000;
   background: white;
   border: 1px solid #cccccc;
   padding: 5px 0;
   background: #f2f2f2;
   border-radius: 5px;
@@ -917,16 +923,20 @@ menuseparator {
  * Make sure splitter panels are not processing any mouse
  * events. This is good for performance during splitter
  * bar dragging.
  */
 .split-box.dragging > .controlled,
 .split-box.dragging > .uncontrolled {
   pointer-events: 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/>. */
+
 .arrow,
 .worker,
 .refresh,
 .shortcut,
 .add-button {
   fill: var(--theme-splitter-color);
 }
 
@@ -1030,16 +1040,20 @@ html .arrow.expanded svg {
   height: 15px;
   margin-right: 5px;
   vertical-align: sub;
 }
 
 .theme-dark .webpack {
   opacity: 0.5;
 }
+/* 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/>. */
+
 .managed-tree .tree {
   -webkit-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
   -o-user-select: none;
   user-select: none;
 
   white-space: nowrap;
@@ -1071,16 +1085,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .managed-tree .tree .node.focused svg {
   fill: white;
 }
 
 .managed-tree .tree-node button {
   position: fixed;
 }
+/* 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/>. */
+
 .close-btn path {
   fill: var(--theme-comment-alt);
 }
 
 .close-btn .close {
   width: 14px;
   height: 14px;
   transition: all 0.15s ease-in-out;
@@ -1118,16 +1136,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 .close-btn.big .close {
   width: 16px;
   height: 16px;
 }
 
 .close-btn.big .close svg {
   width: 9px;
 }
+/* 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/>. */
+
 .search-field {
   width: calc(100% - 1px);
   height: 27px;
   background-color: var(--theme-toolbar-background);
   border-bottom: 1px solid var(--theme-splitter-color);
   padding-right: 10px;
   display: flex;
   flex-shrink: 0;
@@ -1224,16 +1246,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .search-field .search-nav-buttons .nav-btn:active path {
   fill: var(--theme-comment-alt);
 }
 
 .search-field .search-nav-buttons .nav-btn path {
   fill: var(--theme-comment);
 }
+/* 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/>. */
+
 .project-text-search {
   flex-grow: 1;
   display: flex;
   flex-direction: column;
   overflow-y: hidden;
   height: 100%;
 }
 
@@ -1312,28 +1338,36 @@ html[dir="rtl"] .managed-tree .tree .nod
 .project-text-search .managed-tree {
   overflow-y: auto;
   height: calc(100% - 81px);
 }
 
 .project-text-search .managed-tree .tree {
   height: 100%;
 }
+/* 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/>. */
+
 .search-container {
   position: absolute;
   top: 30px;
   left: 0;
   width: calc(100% - 1px);
   height: calc(100% - 31px);
   display: flex;
   flex-direction: column;
   z-index: 20;
   background-color: var(--theme-body-background);
   overflow-y: hidden;
 }
+/* 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/>. */
+
 .sources-panel {
   background-color: var(--theme-sidebar-background);
   display: flex;
   flex: 1;
   flex-direction: column;
   overflow: hidden;
   position: relative;
 }
@@ -1415,16 +1449,17 @@ html[dir="rtl"] .managed-tree .tree .nod
 .source-outline-tabs {
   width: 100%;
   background: var(--theme-body-background);
   border-top: 1px solid var(--theme-splitter-color);
   display: flex;
   -moz-user-select: none;
   user-select: none;
   box-sizing: border-box;
+  height: 29px;
 }
 
 .source-outline-tabs .tab {
   flex: 1;
   justify-content: center;
   border-bottom: 1px solid transparent;
   border-left: 1px solid transparent;
   display: inline-flex;
@@ -1483,16 +1518,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .theme-dark .sources-list .managed-tree .tree .node img.blackBox {
   background-color: var(--theme-body-color);
 }
 
 .theme-dark .sources-list .managed-tree .tree .node.focused img.blackBox {
   background-color: white;
 }
+/* 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/>. */
+
 .outline {
   overflow-y: auto;
 }
 
 .outline .outline-pane-info {
   width: 100%;
   font-style: italic;
   text-align: center;
@@ -1528,16 +1567,20 @@ html[dir="rtl"] .managed-tree .tree .nod
   padding-right: 0.5rem;
   padding-top: 0.2rem;
   cursor: default;
 }
 
 .outline-list__element:hover {
   background: var(--theme-toolbar-background-hover);
 }
+/* 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/>. */
+
 .function-signature {
   align-self: center;
 }
 
 .function-signature .function-name {
   color: var(--theme-highlight-blue);
 }
 
@@ -1547,16 +1590,20 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .function-signature .paren {
   color: var(--object-color);
 }
 
 .function-signature .comma {
   color: var(--object-color);
 }
+/* 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/>. */
+
 .toggle-button-start,
 .toggle-button-end {
   transform: translate(0, 0px);
   transition: transform 0.25s ease-in-out;
   padding: 5px;
 }
 
 .toggle-button-start.vertical,
@@ -1592,16 +1639,20 @@ html[dir="rtl"] .toggle-button-start svg
 html .toggle-button-end.vertical svg {
   transform: rotate(-90deg);
 }
 
 .toggle-button-start.collapsed,
 .toggle-button-end.collapsed {
   transform: rotate(180deg);
 }
+/* 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/>. */
+
 .source-footer {
   background: var(--theme-body-background);
   border-top: 1px solid var(--theme-splitter-color);
   position: absolute;
   display: flex;
   bottom: 0;
   left: 0;
   right: 0;
@@ -1678,16 +1729,20 @@ html .toggle-button-end.vertical svg {
 
 .source-footer > .commands > .blackboxed > img.blackBox {
   background: var(--theme-highlight-blue);
 }
 
 .source-footer .blackbox-summary {
   color: var(--theme-body-color);
 }
+/* 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/>. */
+
 .search-bar {
   display: flex;
   flex-direction: column;
 }
 
 .search-bar .search-field {
   padding-left: 7px;
   height: var(--editor-searchbar-height);
@@ -2058,16 +2113,20 @@ html[dir="rtl"] .arrow svg,
 .tree .node .unavailable {
   color: var(--theme-content-color3);
 }
 
 .lessen {
   opacity: 0.6;
 }
 
+/* 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/>. */
+
 .bracket-arrow {
   position: absolute;
 }
 
 .bracket-arrow::before,
 .bracket-arrow::after {
   content: "";
   height: 0;
@@ -2100,25 +2159,33 @@ html[dir="rtl"] .arrow svg,
   border-top-color: var(--theme-body-color);
 }
 
 .bracket-arrow.down::after {
   border-bottom-color: transparent;
   border-top-color: var(--theme-body-background);
   top: -1px;
 }
+/* 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/>. */
+
 .popover {
   position: fixed;
   z-index: 100;
 }
 
 .popover .gap {
   height: 5px;
   padding-top: 5px;
 }
+/* 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/>. */
+
 .popover .preview-popup {
   background: var(--theme-body-background);
   width: 350px;
   min-height: 80px;
   border: 1px solid var(--theme-splitter-color);
   padding: 10px;
   height: auto;
   min-height: inherit;
@@ -2233,16 +2300,20 @@ html[dir="rtl"] .arrow svg,
 .add-to-expression-bar .expression-to-save-label {
   width: calc(100% - 4em);
 }
 
 .add-to-expression-bar .expression-to-save-button {
   font-size: 14px;
   color: var(--theme-content-color3);
 }
+/* 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/>. */
+
 .call-site {
   background: #f0f9ff;
   position: relative;
 }
 
 .call-site::before {
   content: "";
   position: absolute;
@@ -2278,19 +2349,27 @@ html[dir="rtl"] .arrow svg,
 
 .theme-dark .call-site-bp {
   background-color: #4b3f3f;
 }
 
 .theme-dark .call-site-bp::before {
   border-bottom-color: #dd4d4d;
 }
+/* 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/>. */
+
 .empty-line .CodeMirror-linenumber {
   opacity: 0.5;
 }
+/* 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/>. */
+
 .conditional-breakpoint-panel {
   cursor: initial;
   margin: 1em 0;
   position: relative;
   display: flex;
   align-items: center;
   background: var(--theme-toolbar-background);
   border-top: 1px solid var(--theme-splitter-color);
@@ -2315,23 +2394,28 @@ html[dir="rtl"] .arrow svg,
   font-size: 14px;
   color: var(--theme-conditional-breakpoint-color);
   line-height: 30px;
 }
 
 .conditional-breakpoint-panel input:focus {
   outline-width: 0;
 }
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 .editor-wrapper {
   --debug-line-border: rgb(145, 188, 219);
   --debug-expression-background: rgba(202, 227, 255, 0.5);
   --editor-searchbar-height: 27px;
   --editor-second-searchbar-height: 27px;
   --debug-line-error-border: rgb(255, 0, 0);
   --debug-expression-error-background: rgba(231, 116, 113, 0.3);
+  --editor-header-height: 30px;
 }
 
 .theme-dark .editor-wrapper {
   --debug-expression-background: #54617e;
   --debug-line-border: #7786a2;
 }
 
 .editor-wrapper .CodeMirror-linewidget {
@@ -2347,19 +2431,19 @@ html[dir="rtl"] .arrow svg,
 }
 
 /**
  * There's a known codemirror flex issue with chrome that this addresses.
  * BUG https://github.com/devtools-html/debugger.html/issues/63
  */
 .editor-wrapper {
   position: absolute;
-  height: calc(100% - 29px);
+  height: calc(100% - var(--editor-header-height));
   width: calc(100% - 1px);
-  top: 29px;
+  top: var(--editor-header-height);
   left: 0px;
   --editor-footer-height: 24px;
 }
 
 html[dir="rtl"] .editor-mount {
   direction: ltr;
 }
 
@@ -2529,16 +2613,20 @@ debug-expression-error {
 
 .CodeMirror-guttermarker-subtle {
   visibility: hidden;
 }
 
 .visible {
   visibility: visible;
 }
+/* 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/>. */
+
 .cm-highlight {
   position: relative;
 }
 
 .cm-highlight::before {
   position: absolute;
   border-top-style: solid;
   border-bottom-style: solid;
@@ -2554,16 +2642,20 @@ debug-expression-error {
   margin-bottom: -1px;
 }
 
 .cm-highlight-full::before {
   border: 1px solid var(--theme-comment-alt);
   border-radius: 2px;
   margin: 0 -1px -1px -1px;
 }
+/* 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/>. */
+
 .breakpoints-toggle {
   margin: 2px 3px;
 }
 
 .breakpoints-list * {
   user-select: none;
 }
 
@@ -2666,16 +2758,20 @@ html .breakpoints-list .breakpoint.pause
 
 .breakpoint .close {
   visibility: hidden;
 }
 
 .breakpoint:hover .close {
   visibility: visible;
 }
+/* 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/>. */
+
 .input-expression {
   width: 100%;
   margin: 0px;
   border: 1px;
   background-color: var(--theme-sidebar-background);
   font-size: 12px;
   padding: 0px 20px;
   color: var(--theme-body-color);
@@ -2747,16 +2843,20 @@ html .breakpoints-list .breakpoint.pause
 
 .expression-container:hover .close-btn {
   display: block;
 }
 
 .expression-input {
   max-width: 50%;
 }
+/* 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/>. */
+
 .frames ul .frames-group .group,
 .frames ul .frames-group .group .location {
   font-weight: 500;
   cursor: default;
 }
 
 .frames ul .frames-group.expanded .group,
 .frames ul .frames-group.expanded .group .location {
@@ -2770,16 +2870,20 @@ html .breakpoints-list .breakpoint.pause
 .frames ul .frames-group .frames-list li {
   padding-left: 30px;
 }
 
 .frames ul .frames-group .frames-list {
   border-top: 1px solid var(--theme-splitter-color);
   border-bottom: 1px solid var(--theme-splitter-color);
 }
+/* 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/>. */
+
 .why-paused {
   background-color: var(--theme-body-background);
   color: var(--theme-body-color);
   padding: 10px 10px 10px 20px;
   white-space: normal;
   opacity: 0.6;
   font-size: 12px;
   flex: 0 1 auto;
@@ -2798,16 +2902,20 @@ html .breakpoints-list .breakpoint.pause
 }
 
 .why-paused .message.warning {
   font-size: 10px;
   color: var(--theme-graphs-red);
   font-weight: bold;
   font-style: normal;
 }
+/* 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/>. */
+
 .frames ul {
   list-style: none;
   margin: 0;
   padding: 0;
 }
 
 .frames ul li {
   padding: 7px 10px 7px 21px;
@@ -2890,16 +2998,20 @@ html .breakpoints-list .breakpoint.pause
   width: 12px;
   margin-left: 3px;
   line-height: 8px;
 }
 
 :root.theme-dark .annotation-logo svg path {
   fill: var(--theme-highlight-blue);
 }
+/* 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/>. */
+
 .event-listeners {
   list-style: none;
   margin: 0;
   padding: 0;
 }
 
 .event-listeners .listener {
   padding: 7px 10px 7px 21px;
@@ -2935,28 +3047,36 @@ html .breakpoints-list .breakpoint.pause
 
 .event-listeners .listener .close {
   display: none;
 }
 
 .event-listeners .listener:hover .close {
   display: block;
 }
+/* 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/>. */
+
 .workers-list * {
   user-select: none;
 }
 
 .workers-list .worker {
   font-size: 12px;
   color: var(--theme-content-color1);
   padding: 0.5em 1em 0.5em 0.5em;
   line-height: 1em;
   position: relative;
   transition: all 0.25s ease;
 }
+/* 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 {
   --accordion-header-background: var(--theme-toolbar-background);
 }
 
 :root.theme-dark {
   --accordion-header-background: #141416;
 }
 
@@ -3023,16 +3143,20 @@ html .breakpoints-list .breakpoint.pause
   padding: 0;
   width: 16px;
   height: 16px;
 }
 
 .accordion .header-buttons button::-moz-focus-inner {
   border: 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/>. */
+
 .command-bar {
   flex: 0 0 29px;
   border-bottom: 1px solid var(--theme-splitter-color);
   display: flex;
   overflow: hidden;
   z-index: 1;
   background-color: var(--theme-toolbar-background);
 }
@@ -3151,16 +3275,20 @@ img.resume {
 
 .command-bar.bottom > button {
   color: var(--theme-comment);
   width: 26px;
 }
 .command-bar.bottom > button:hover {
   color: var(--theme-body-color);
 }
+/* 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/>. */
+
 .object-node.default-property {
   opacity: 0.6;
 }
 
 .object-label {
   color: var(--theme-highlight-blue);
 }
 
@@ -3181,16 +3309,20 @@ img.resume {
 
 .scopes-pane {
   overflow: auto;
 }
 
 .scopes-list .function-signature {
   display: inline-block;
 }
+/* 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/>. */
+
 .secondary-panes {
   overflow: auto;
   display: flex;
   flex-direction: column;
   flex: 1;
   white-space: nowrap;
   --breakpoint-expression-right-clear-space: 36px;
 }
@@ -3225,16 +3357,20 @@ img.resume {
   -moz-user-select: none;
   user-select: none;
   cursor: default;
 }
 
 .theme-dark .secondary-panes .accordion .arrow svg {
   fill: var(--theme-content-color3);
 }
+/* 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/>. */
+
 .welcomebox {
   width: calc(100% - 1px);
 
   /* Offsetting it by 30px for the sources-header area */
   height: calc(100% - 30px);
   position: absolute;
   top: 30px;
   left: 0;
@@ -3306,16 +3442,20 @@ html .welcomebox .toggle-button-end.coll
   .shortcutFunction {
     margin-left: 0;
   }
 
   .shortcutKey {
     display: block;
   }
 }
+/* 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/>. */
+
 .source-header {
   border-bottom: 1px solid var(--theme-splitter-color);
   width: 100%;
   height: 29px;
   display: flex;
   align-items: flex-end;
 }
 
@@ -3434,16 +3574,20 @@ html .welcomebox .toggle-button-end.coll
 
 .source-tab.active .close-btn {
   visibility: visible;
 }
 
 .source-tab:hover .close-btn {
   visibility: visible;
 }
+/* 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/>. */
+
 .dropdown {
   --width: 150px;
   background: var(--theme-body-background);
   border: 1px solid var(--theme-splitter-color);
   box-shadow: 0 4px 4px 0 var(--search-overlays-semitransparent);
   max-height: 300px;
   position: absolute;
   right: 0;
@@ -3497,16 +3641,20 @@ html[dir="rtl"] .dropdown {
   position: fixed;
   width: 100%;
   height: 100%;
   background: transparent;
   z-index: 999;
   left: 0;
   top: 0;
 }
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 .result-list {
   list-style: none;
   margin: 0px;
   padding: 0px;
   overflow: auto;
   width: calc(100% - 1px); /* 1px fixes the hidden right border */
 }
 
@@ -3586,8 +3734,10 @@ html[dir="rtl"] .dropdown {
 
 .search-bar .result-list {
   border-bottom: 1px solid var(--theme-splitter-color);
 }
 
 .theme-dark .result-list {
   background-color: var(--theme-body-background);
 }
+
+/*# sourceMappingURL=debugger.css.map*/
\ No newline at end of file
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -10199,16 +10199,20 @@ module.exports = isLength;
 /* 223 */,
 /* 224 */,
 /* 225 */,
 /* 226 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
+/* 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/>. */
+
 // @flow
 
 const { isDevelopment } = __webpack_require__(1355);
 const { Services, PrefsHelper } = __webpack_require__(1376);
 
 const prefsSchemaVersion = "1.0.3";
 
 const pref = Services.pref;
@@ -10612,17 +10616,17 @@ module.exports = charenc;
 
 /***/ }),
 /* 251 */
 /***/ (function(module, exports) {
 
 /*!
  * Determine if an object is a Buffer
  *
- * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @author   Feross Aboukhadijeh <https://feross.org>
  * @license  MIT
  */
 
 // The _isBuffer check is for Safari 5-7 support, because it's missing
 // Object.prototype.constructor. Remove this eventually
 module.exports = function (obj) {
   return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
 }
@@ -16492,17 +16496,19 @@ module.exports = "<!-- This Source Code 
 /* 1350 */,
 /* 1351 */,
 /* 1352 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
-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; };
+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; }; /* 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/>. */
 
 var _expressions = __webpack_require__(1417);
 
 var expressions = _interopRequireWildcard(_expressions);
 
 var _sources = __webpack_require__(1369);
 
 var sources = _interopRequireWildcard(_sources);
@@ -17005,16 +17011,20 @@ module.exports = {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; }; /* 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/>. */
+
 var _breakpoints = __webpack_require__(1396);
 
 var breakpoints = _interopRequireWildcard(_breakpoints);
 
 var _expressions = __webpack_require__(1398);
 
 var expressions = _interopRequireWildcard(_expressions);
 
@@ -17071,17 +17081,17 @@ var _debuggee = __webpack_require__(1533
 var debuggee = _interopRequireWildcard(_debuggee);
 
 var _toolbox = __webpack_require__(1534);
 
 var toolbox = _interopRequireWildcard(_toolbox);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-exports.default = Object.assign({}, navigation, breakpoints, expressions, eventListeners, sources, pause, ui, fileSearch, ast, coverage, projectTextSearch, quickOpen, sourceTree, loadSourceText, debuggee, toolbox);
+exports.default = _extends({}, navigation, breakpoints, expressions, eventListeners, sources, pause, ui, fileSearch, ast, coverage, projectTextSearch, quickOpen, sourceTree, loadSourceText, debuggee, toolbox);
 
 /***/ }),
 /* 1355 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -17110,17 +17120,19 @@ var _path = __webpack_require__(1393);
 var _url = __webpack_require__(334);
 
 /**
  * Trims the query part or reference identifier of a url string, if necessary.
  *
  * @memberof utils/source
  * @static
  */
-
+/* 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/>. */
 
 /**
  * Utils for working with Source URLs
  * @module utils/source
  */
 
 function trimUrlQuery(url) {
   const length = url.length;
@@ -17221,17 +17233,22 @@ function getFormattedSourceId(id) {
  * @static
  */
 function getFilename(source) {
   const { url, id } = source;
   if (!url) {
     return getFormattedSourceId(id);
   }
 
-  return getFilenameFromURL(url);
+  let filename = getFilenameFromURL(url);
+  const qMarkIdx = filename.indexOf("?");
+  if (qMarkIdx > 0) {
+    filename = filename.slice(0, qMarkIdx);
+  }
+  return filename;
 }
 
 /**
  * Show a source url.
  * If the source does not have a url, use the source id.
  *
  * @memberof utils/source
  * @static
@@ -17286,23 +17303,27 @@ function getSourceLineCount(source) {
  *
  * Returns Code Mirror mode for source content type
  * @param contentType
  * @return String
  * @memberof utils/source
  * @static
  */
 
-function getMode(source) {
+function getMode(source, sourceMetaData) {
   const { contentType, text, isWasm, url } = source;
 
   if (!text || isWasm) {
     return { name: "text" };
   }
 
+  if (url && url.match(/\.jsx$/i) || sourceMetaData && sourceMetaData.isReactComponent) {
+    return "jsx";
+  }
+
   // if the url ends with .marko we set the name to Javascript so
   // syntax highlighting works for marko too
   if (url && url.match(/\.marko$/i)) {
     return { name: "javascript" };
   }
 
   // Use HTML mode for files in which the first non whitespace
   // character is `<` regardless of extension.
@@ -17373,16 +17394,20 @@ module.exports = {
 
 /***/ }),
 /* 1358 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
+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; }; /* 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/>. */
+
 var _devtoolsConfig = __webpack_require__(1355);
 
 var _sourceDocuments = __webpack_require__(1436);
 
 var sourceDocumentUtils = _interopRequireWildcard(_sourceDocuments);
 
 var _source = __webpack_require__(1356);
 
@@ -17391,16 +17416,18 @@ var _expression = __webpack_require__(15
 var expressionUtils = _interopRequireWildcard(_expression);
 
 var _sourceSearch = __webpack_require__(1526);
 
 var sourceSearchUtils = _interopRequireWildcard(_sourceSearch);
 
 var _wasm = __webpack_require__(1401);
 
+var _ui = __webpack_require__(1439);
+
 var _devtoolsSourceEditor = __webpack_require__(1386);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 const { findNext, findPrev } = sourceSearchUtils;
 
 function shouldShowPrettyPrint(selectedSource) {
   if (!selectedSource) {
@@ -17480,18 +17507,19 @@ function toEditorRange(sourceId, locatio
 
 function toSourceLine(sourceId, line) {
   return (0, _wasm.isWasm)(sourceId) ? (0, _wasm.lineToWasmOffset)(sourceId, line) : line + 1;
 }
 
 function scrollToColumn(codeMirror, line, column) {
   const { top, left } = codeMirror.charCoords({ line: line, ch: column }, "local");
 
-  const centeredX = left - codeMirror.getScrollerElement().offsetWidth / 2;
-  const centeredY = top - codeMirror.getScrollerElement().offsetHeight / 2;
+  const scroller = codeMirror.getScrollerElement();
+  const centeredX = Math.max(left - scroller.offsetWidth / 2, 0);
+  const centeredY = Math.max(top - scroller.offsetHeight / 2, 0);
 
   codeMirror.scrollTo(centeredX, centeredY);
 }
 
 function toSourceLocation(sourceId, location) {
   return {
     line: toSourceLine(sourceId, location.line),
     column: (0, _wasm.isWasm)(sourceId) ? undefined : location.column
@@ -17517,31 +17545,32 @@ function getSourceLocationFromMouseEvent
 
   return {
     sourceId: selectedLocation.sourceId,
     line: line + 1,
     column: ch + 1
   };
 }
 
-module.exports = Object.assign({}, expressionUtils, sourceDocumentUtils, sourceSearchUtils, _devtoolsSourceEditor.SourceEditorUtils, {
+module.exports = _extends({}, expressionUtils, sourceDocumentUtils, sourceSearchUtils, _devtoolsSourceEditor.SourceEditorUtils, {
   createEditor,
   isWasm: _wasm.isWasm,
   toEditorLine,
   toEditorPosition,
   toEditorRange,
   toSourceLine,
   scrollToColumn,
   toSourceLocation,
   shouldShowPrettyPrint,
   shouldShowFooter,
   traverseResults,
   markText,
   lineAtHeight,
-  getSourceLocationFromMouseEvent
+  getSourceLocationFromMouseEvent,
+  resizeBreakpointGutter: _ui.resizeBreakpointGutter
 });
 
 /***/ }),
 /* 1359 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -17553,16 +17582,20 @@ Object.defineProperty(exports, "__esModu
 var _Svg = __webpack_require__(1540);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
 __webpack_require__(1310);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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 file maps the SVG React Components in the assets/images directory.
  */
 
 exports.default = _Svg2.default;
 
 /***/ }),
 /* 1360 */
@@ -17574,17 +17607,17 @@ exports.default = _Svg2.default;
 
 const {
   originalToGeneratedId,
   generatedToOriginalId,
   isGeneratedId,
   isOriginalId
 } = __webpack_require__(1389);
 
-const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
+const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363);
 
 const dispatcher = new WorkerDispatcher();
 
 const getOriginalURLs = dispatcher.task("getOriginalURLs");
 const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
 const getOriginalLocation = dispatcher.task("getOriginalLocation");
 const getLocationScopes = dispatcher.task("getLocationScopes");
 const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
@@ -17637,17 +17670,19 @@ function _interopRequireWildcard(obj) { 
 
 
 /**
  * @memberof utils/makeRecord
  * @static
  */
 function makeRecord(spec) {
   return I.Record(spec);
-}
+} /* 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/>. */
 
 /**
  * When Flow 0.29 is released (very soon), we can use this Record type
  * instead of the builtin immutable.js Record type. This is better
  * because all the fields are actually typed, unlike the builtin one.
  * This depends on a performance fix that will go out in 0.29 though;
  * @module utils/makeRecord
  */
@@ -18009,24 +18044,29 @@ function breakpointExists(state, locatio
 }
 
 function createBreakpoint(location, overrides = {}) {
   const {
     condition,
     disabled,
     hidden,
     generatedLocation,
-    astLocation
+    astLocation,
+    id
   } = overrides;
 
+  const defaultASTLocation = { name: undefined, offset: location };
   const properties = {
+    id,
     condition: condition || null,
     disabled: disabled || false,
     hidden: hidden || false,
-    astLocation: astLocation || { offset: location },
+    loading: false,
+    text: "",
+    astLocation: astLocation || defaultASTLocation,
     generatedLocation: generatedLocation || location,
     location
   };
 
   return properties;
 }
 
 function createPendingLocation(location) {
@@ -18054,21 +18094,23 @@ function createPendingBreakpoint(bp) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
+exports.replaceOriginalVariableName = exports.isReactComponent = exports.hasSyntaxError = exports.clearSources = exports.setSource = exports.hasSource = exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearScopes = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getScopes = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined;
 
 var _devtoolsUtils = __webpack_require__(1363);
 
-const { WorkerDispatcher } = _devtoolsUtils.workerUtils;
+const { WorkerDispatcher } = _devtoolsUtils.workerUtils; /* 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 dispatcher = new WorkerDispatcher();
 const startParserWorker = exports.startParserWorker = dispatcher.start.bind(dispatcher);
 const stopParserWorker = exports.stopParserWorker = dispatcher.stop.bind(dispatcher);
 
 const getClosestExpression = exports.getClosestExpression = dispatcher.task("getClosestExpression");
 const getSymbols = exports.getSymbols = dispatcher.task("getSymbols");
 const getScopes = exports.getScopes = dispatcher.task("getScopes");
@@ -18078,28 +18120,32 @@ const clearSymbols = exports.clearSymbol
 const clearScopes = exports.clearScopes = dispatcher.task("clearScopes");
 const clearASTs = exports.clearASTs = dispatcher.task("clearASTs");
 const getNextStep = exports.getNextStep = dispatcher.task("getNextStep");
 const getEmptyLines = exports.getEmptyLines = dispatcher.task("getEmptyLines");
 const hasSource = exports.hasSource = dispatcher.task("hasSource");
 const setSource = exports.setSource = dispatcher.task("setSource");
 const clearSources = exports.clearSources = dispatcher.task("clearSources");
 const hasSyntaxError = exports.hasSyntaxError = dispatcher.task("hasSyntaxError");
+const isReactComponent = exports.isReactComponent = dispatcher.task("isReactComponent");
+const replaceOriginalVariableName = exports.replaceOriginalVariableName = dispatcher.task("replaceOriginalVariableName");
 
 /***/ }),
 /* 1366 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-
+/* 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/>. */
 
 /**
  * Utils for utils, by utils
  * @module utils/utils
  */
 
 /**
  * @memberof utils/utils
@@ -18334,20 +18380,19 @@ module.exports = {
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.getSelectedSourceText = exports.getSelectedSource = exports.getSelectedLocation = exports.getSourcesForTabs = exports.getSearchTabs = exports.getSourceTabs = exports.getSources = undefined;
 
-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; };
-/* 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/. */
+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; }; /* 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/>. */
 
 /**
  * Sources reducer
  * @module reducers/sources
  */
 
 exports.initialState = initialState;
 exports.removeSourceFromTabList = removeSourceFromTabList;
@@ -18672,88 +18717,17 @@ const getSelectedSource = exports.getSel
 const getSelectedSourceText = exports.getSelectedSourceText = (0, _reselect.createSelector)(getSelectedSource, getSourcesState, (selectedSource, sources) => {
   const id = selectedSource.get("id");
   return id ? sources.sourcesText.get(id) : null;
 });
 
 exports.default = update;
 
 /***/ }),
-/* 1370 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.promise = exports.PROMISE = undefined;
-
-var _lodash = __webpack_require__(2);
-
-var _DevToolsUtils = __webpack_require__(1432);
-
-/* 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/. */
-
-let seqIdVal = 1;
-
-function seqIdGen() {
-  return seqIdVal++;
-}
-
-function filterAction(action) {
-  return (0, _lodash.fromPairs)((0, _lodash.toPairs)(action).filter(pair => pair[0] !== PROMISE));
-}
-
-function promiseMiddleware({ dispatch, getState }) {
-  return next => action => {
-    if (!(PROMISE in action)) {
-      return next(action);
-    }
-
-    const promiseInst = action[PROMISE];
-    const seqId = seqIdGen().toString();
-
-    // Create a new action that doesn't have the promise field and has
-    // the `seqId` field that represents the sequence id
-    action = Object.assign(filterAction(action), { seqId });
-
-    dispatch(Object.assign({}, action, { status: "start" }));
-
-    // Return the promise so action creators can still compose if they
-    // want to.
-    return new Promise((resolve, reject) => {
-      promiseInst.then(value => {
-        (0, _DevToolsUtils.executeSoon)(() => {
-          dispatch(Object.assign({}, action, {
-            status: "done",
-            value: value
-          }));
-          resolve(value);
-        });
-      }, error => {
-        (0, _DevToolsUtils.executeSoon)(() => {
-          dispatch(Object.assign({}, action, {
-            status: "error",
-            error: error.message || error
-          }));
-          reject(error);
-        });
-      });
-    });
-  };
-}
-
-const PROMISE = exports.PROMISE = "@@dispatch/promise";
-exports.promise = promiseMiddleware;
-
-/***/ }),
+/* 1370 */,
 /* 1371 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -18767,16 +18741,20 @@ exports.partIsFile = partIsFile;
 exports.createNode = createNode;
 exports.createParentMap = createParentMap;
 exports.getRelativePath = getRelativePath;
 
 var _url = __webpack_require__(334);
 
 var _source = __webpack_require__(1356);
 
+/* 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 IGNORED_URLS = ["debugger eval code", "XStringBundle"];
 
 function nodeHasChildren(item) {
   return Array.isArray(item.contents);
 }
 
 function isExactUrlMatch(pathPart, debuggeeUrl) {
   // compare to hostname with an optional 'www.' prefix
@@ -19007,17 +18985,17 @@ exports.jumpToMappedLocation = jumpToMap
 exports.addTab = addTab;
 exports.moveTab = moveTab;
 exports.closeTab = closeTab;
 exports.closeTabs = closeTabs;
 exports.togglePrettyPrint = togglePrettyPrint;
 exports.toggleBlackBox = toggleBlackBox;
 exports.loadAllSources = loadAllSources;
 
-var _promise = __webpack_require__(1370);
+var _promise = __webpack_require__(1653);
 
 var _assert = __webpack_require__(1384);
 
 var _assert2 = _interopRequireDefault(_assert);
 
 var _breakpoints = __webpack_require__(1396);
 
 var _ast = __webpack_require__(1399);
@@ -19045,21 +19023,19 @@ function _interopRequireDefault(obj) { r
 // If a request has been made to show this source, go ahead and
 // select it.
 async function checkSelectedSource(state, dispatch, source) {
   const pendingLocation = (0, _selectors.getPendingSelectedLocation)(state);
 
   if (pendingLocation && !!source.url && pendingLocation.url === source.url) {
     await dispatch(selectSource(source.id, { location: pendingLocation }));
   }
-}
-
-/* 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 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/>. */
 
 /**
  * Redux actions for the sources state
  * @module actions/sources
  */
 
 async function checkPendingBreakpoints(state, dispatch, sourceId) {
   // source may have been modified by selectSource
@@ -19296,32 +19272,33 @@ function togglePrettyPrint(sourceId) {
 
     if (!source || !(0, _source2.isLoaded)(source)) {
       return {};
     }
 
     (0, _assert2.default)(sourceMaps.isGeneratedId(sourceId), "Pretty-printing only allowed on generated sources");
 
     const selectedLocation = (0, _selectors.getSelectedLocation)(getState());
-    const selectedOriginalLocation = selectedLocation ? await sourceMaps.getOriginalLocation(selectedLocation) : {};
-
     const url = (0, _source2.getPrettySourceURL)(source.url);
     const prettySource = (0, _selectors.getSourceByURL)(getState(), url);
 
+    const options = {};
+    if (selectedLocation) {
+      options.location = await sourceMaps.getOriginalLocation(selectedLocation);
+    }
+
     if (prettySource) {
-      return dispatch(selectSource(prettySource.get("id"), {
-        location: selectedOriginalLocation
-      }));
+      return dispatch(selectSource(prettySource.get("id"), options));
     }
 
     const newPrettySource = await dispatch((0, _createPrettySource.createPrettySource)(sourceId));
     await dispatch((0, _breakpoints.remapBreakpoints)(sourceId));
     await dispatch((0, _ast.setEmptyLines)(newPrettySource.id));
 
-    return dispatch(selectSource(newPrettySource.id, { location: selectedOriginalLocation }));
+    return dispatch(selectSource(newPrettySource.id, options));
   };
 }
 
 function toggleBlackBox(source) {
   return async ({ dispatch, getState, client, sourceMaps }) => {
     const { isBlackBoxed, id } = source;
 
     return dispatch({
@@ -19385,17 +19362,20 @@ function CloseButton({ handleClick, butt
     "div",
     {
       className: buttonClass ? `close-btn ${buttonClass}` : "close-btn",
       onClick: handleClick,
       title: tooltip
     },
     _react2.default.createElement(_Svg2.default, { name: "close" })
   );
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = CloseButton;
 
 /***/ }),
 /* 1375 */,
 /* 1376 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -19480,20 +19460,19 @@ module.exports = {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
-/* 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/. */
+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; }; /* 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/>. */
 
 /**
  * Breakpoints reducer
  * @module reducers/breakpoints
  */
 
 exports.initialState = initialState;
 exports.getBreakpoints = getBreakpoints;
@@ -19709,16 +19688,20 @@ var _classnames2 = _interopRequireDefaul
 var _Close = __webpack_require__(1374);
 
 var _Close2 = _interopRequireDefault(_Close);
 
 __webpack_require__(1313);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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 arrowBtn = (onClick, type, className, tooltip) => {
   const props = {
     onClick,
     type,
     className,
     title: tooltip,
     key: type
   };
@@ -19838,16 +19821,21 @@ exports.default = SearchInput;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.getLibraryFromUrl = getLibraryFromUrl;
 exports.annotateFrame = annotateFrame;
 exports.simplifyDisplayName = simplifyDisplayName;
 exports.formatDisplayName = formatDisplayName;
 exports.formatCopyName = formatCopyName;
 exports.collapseFrames = collapseFrames;
 
 var _lodash = __webpack_require__(2);
@@ -19971,17 +19959,17 @@ function mapDisplayNames(frame, library)
 
 function annotateFrame(frame) {
   if (!(0, _devtoolsConfig.isEnabled)("collapseFrame")) {
     return frame;
   }
 
   const library = getLibraryFromUrl(frame);
   if (library) {
-    return Object.assign({}, frame, { library });
+    return _extends({}, frame, { library });
   }
 
   return frame;
 }
 
 // Decodes an anonymous naming scheme that
 // spider monkey implements based on "Naming Anonymous JavaScript Functions"
 // http://johnjbarton.github.io/nonymous/index.html
@@ -20307,44 +20295,46 @@ Object.defineProperty(exports, "__esModu
 });
 exports.initialState = initialState;
 exports.getSymbols = getSymbols;
 exports.hasSymbols = hasSymbols;
 exports.isEmptyLineInSource = isEmptyLineInSource;
 exports.getEmptyLines = getEmptyLines;
 exports.getOutOfScopeLocations = getOutOfScopeLocations;
 exports.getPreview = getPreview;
+exports.getSourceMetaData = getSourceMetaData;
 
 var _immutable = __webpack_require__(146);
 
 var I = _interopRequireWildcard(_immutable);
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 /* 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/. */
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /**
  * Ast reducer
  * @module reducers/ast
  */
 
 function initialState() {
   return (0, _makeRecord2.default)({
     symbols: I.Map(),
     emptyLines: I.Map(),
     outOfScopeLocations: null,
-    preview: null
+    preview: null,
+    sourceMetaData: I.Map()
   })();
 }
 
 function update(state = initialState(), action) {
   switch (action.type) {
     case "SET_SYMBOLS":
       {
         const { source, symbols } = action;
@@ -20401,16 +20391,21 @@ function update(state = initialState(), 
         return state.set("outOfScopeLocations", null);
       }
 
     case "NAVIGATE":
       {
         return initialState();
       }
 
+    case "SET_SOURCE_METADATA":
+      {
+        return state.setIn(["sourceMetaData", action.sourceId], action.sourceMetaData);
+      }
+
     default:
       {
         return state;
       }
   }
 }
 
 // NOTE: we'd like to have the app state fully typed
@@ -20449,16 +20444,20 @@ function getEmptyLines(state, source) {
 function getOutOfScopeLocations(state) {
   return state.ast.get("outOfScopeLocations");
 }
 
 function getPreview(state) {
   return state.ast.get("preview");
 }
 
+function getSourceMetaData(state, sourceId) {
+  return state.ast.getIn(["sourceMetaData", sourceId]) || {};
+}
+
 exports.default = update;
 
 /***/ }),
 /* 1384 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -20469,48 +20468,59 @@ Object.defineProperty(exports, "__esModu
 exports.default = assert;
 
 var _devtoolsConfig = __webpack_require__(1355);
 
 function assert(condition, message) {
   if ((0, _devtoolsConfig.isDevelopment)() && !condition) {
     throw new Error(`Assertion failure: ${message}`);
   }
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1385 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.setContextMenu = setContextMenu;
+exports.setPrimaryPaneTab = setPrimaryPaneTab;
 exports.closeActiveSearch = closeActiveSearch;
 exports.setActiveSearch = setActiveSearch;
 exports.toggleFrameworkGrouping = toggleFrameworkGrouping;
 exports.showSource = showSource;
 exports.togglePaneCollapse = togglePaneCollapse;
 exports.highlightLineRange = highlightLineRange;
+exports.flashLineRange = flashLineRange;
 exports.clearHighlightLineRange = clearHighlightLineRange;
 exports.openConditionalPanel = openConditionalPanel;
 exports.closeConditionalPanel = closeConditionalPanel;
 exports.setProjectDirectoryRoot = setProjectDirectoryRoot;
 exports.setOrientation = setOrientation;
 
 var _selectors = __webpack_require__(1352);
 
 function setContextMenu(type, event) {
   return ({ dispatch }) => {
     dispatch({ type: "SET_CONTEXT_MENU", contextMenu: { type, event } });
   };
-}
+} /* 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/>. */
+
+function setPrimaryPaneTab(tabName) {
+  return { type: "SET_PRIMARY_PANE_TAB", tabName };
+}
+
 function closeActiveSearch() {
   return {
     type: "TOGGLE_ACTIVE_SEARCH",
     value: null
   };
 }
 
 function setActiveSearch(activeSearch) {
@@ -20535,61 +20545,80 @@ function toggleFrameworkGrouping(toggleV
     });
   };
 }
 
 function showSource(sourceId) {
   return ({ dispatch, getState }) => {
     const source = (0, _selectors.getSource)(getState(), sourceId);
 
+    dispatch(setPrimaryPaneTab("sources"));
     dispatch({
       type: "SHOW_SOURCE",
       sourceUrl: ""
     });
 
     dispatch({
       type: "SHOW_SOURCE",
       sourceUrl: source.get("url")
     });
   };
 }
 
 function togglePaneCollapse(position, paneCollapsed) {
-  return {
-    type: "TOGGLE_PANE",
-    position,
-    paneCollapsed
+  return ({ dispatch, getState }) => {
+    const prevPaneCollapse = (0, _selectors.getPaneCollapse)(getState(), position);
+    if (prevPaneCollapse === paneCollapsed) {
+      return;
+    }
+
+    dispatch({
+      type: "TOGGLE_PANE",
+      position,
+      paneCollapsed
+    });
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
 function highlightLineRange(location) {
   return {
     type: "HIGHLIGHT_LINES",
     location
   };
 }
 
+function flashLineRange(location) {
+  return ({ dispatch }) => {
+    dispatch(highlightLineRange(location));
+    setTimeout(() => dispatch(clearHighlightLineRange()), 200);
+  };
+}
+
 /**
  * @memberof actions/sources
  * @static
  */
 function clearHighlightLineRange() {
   return {
     type: "CLEAR_HIGHLIGHT_LINES"
   };
 }
 
 function openConditionalPanel(line) {
+  if (!line) {
+    return;
+  }
+
   return {
     type: "OPEN_CONDITIONAL_PANEL",
-    line: line
+    line
   };
 }
 
 function closeConditionalPanel() {
   return {
     type: "CLOSE_CONDITIONAL_PANEL"
   };
 }
@@ -20630,17 +20659,19 @@ module.exports = { SourceEditor, SourceE
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.formatKeyShortcut = undefined;
 
 var _devtoolsModules = __webpack_require__(1376);
 
-const { appinfo } = _devtoolsModules.Services;
+const { appinfo } = _devtoolsModules.Services; /* 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/>. */
 
 /**
  * Utils for keyboard command strings
  * @module utils/text
  */
 
 
 const isMacOS = appinfo.OS === "Darwin";
@@ -20672,16 +20703,20 @@ exports.formatKeyShortcut = formatKeySho
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+/* 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/>. */
+
 /**
  * Clipboard function taken from
  * https://dxr.mozilla.org/mozilla-central/source/devtools/shared/platform/content/clipboard.js
  */
 function copyToTheClipboard(string) {
   const doCopy = function (e) {
     e.clipboardData.setData("text/plain", string);
     e.preventDefault();
@@ -20770,196 +20805,32 @@ module.exports = {
   generatedToOriginalId,
   isOriginalId,
   isGeneratedId,
   getContentType,
   contentMapForTesting: contentMap
 };
 
 /***/ }),
-/* 1390 */
-/***/ (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 networkRequest = __webpack_require__(1391);
-const workerUtils = __webpack_require__(1392);
-
-module.exports = {
-  networkRequest,
-  workerUtils
-};
-
-/***/ }),
-/* 1391 */
-/***/ (function(module, exports) {
-
-/* 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/. */
-
-function networkRequest(url, opts) {
-  return fetch(url, {
-    cache: opts.loadFromCache ? "default" : "no-cache"
-  }).then(res => {
-    if (res.status >= 200 && res.status < 300) {
-      return res.text().then(text => ({ content: text }));
-    }
-    return Promise.reject(`request failed with status ${res.status}`);
-  });
-}
-
-module.exports = networkRequest;
-
-/***/ }),
-/* 1392 */
-/***/ (function(module, exports) {
-
-function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
-
-function WorkerDispatcher() {
-  this.msgId = 1;
-  this.worker = null;
-} /* 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/. */
-
-WorkerDispatcher.prototype = {
-  start(url) {
-    this.worker = new Worker(url);
-    this.worker.onerror = () => {
-      console.error(`Error in worker ${url}`);
-    };
-  },
-
-  stop() {
-    if (!this.worker) {
-      return;
-    }
-
-    this.worker.terminate();
-    this.worker = null;
-  },
-
-  task(method) {
-    return (...args) => {
-      return new Promise((resolve, reject) => {
-        const id = this.msgId++;
-        this.worker.postMessage({ id, method, args });
-
-        const listener = ({ data: result }) => {
-          if (result.id !== id) {
-            return;
-          }
-
-          this.worker.removeEventListener("message", listener);
-          if (result.error) {
-            reject(result.error);
-          } else {
-            resolve(result.response);
-          }
-        };
-
-        this.worker.addEventListener("message", listener);
-      });
-    };
-  }
-};
-
-function workerHandler(publicInterface) {
-  return function (msg) {
-    const { id, method, args } = msg.data;
-    try {
-      const response = publicInterface[method].apply(undefined, args);
-      if (response instanceof Promise) {
-        response.then(val => self.postMessage({ id, response: val }),
-        // Error can't be sent via postMessage, so be sure to
-        // convert to string.
-        err => self.postMessage({ id, error: err.toString() }));
-      } else {
-        self.postMessage({ id, response });
-      }
-    } catch (error) {
-      // Error can't be sent via postMessage, so be sure to convert to
-      // string.
-      self.postMessage({ id, error: error.toString() });
-    }
-  };
-}
-
-function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
-  let streamingWorker = (() => {
-    var _ref = _asyncToGenerator(function* (id, tasks) {
-      let isWorking = true;
-
-      const intervalId = setTimeout(function () {
-        isWorking = false;
-      }, timeout);
-
-      const results = [];
-      while (tasks.length !== 0 && isWorking) {
-        const { callback, context, args } = tasks.shift();
-        const result = yield callback.call(context, args);
-        results.push(result);
-      }
-      worker.postMessage({ id, status: "pending", data: results });
-      clearInterval(intervalId);
-
-      if (tasks.length !== 0) {
-        yield streamingWorker(id, tasks);
-      }
-    });
-
-    return function streamingWorker(_x, _x2) {
-      return _ref.apply(this, arguments);
-    };
-  })();
-
-  return (() => {
-    var _ref2 = _asyncToGenerator(function* (msg) {
-      const { id, method, args } = msg.data;
-      const workerMethod = publicInterface[method];
-      if (!workerMethod) {
-        console.error(`Could not find ${method} defined in worker.`);
-      }
-      worker.postMessage({ id, status: "start" });
-
-      try {
-        const tasks = workerMethod(args);
-        yield streamingWorker(id, tasks);
-        worker.postMessage({ id, status: "done" });
-      } catch (error) {
-        worker.postMessage({ id, status: "error", error });
-      }
-    });
-
-    return function (_x3) {
-      return _ref2.apply(this, arguments);
-    };
-  })();
-}
-
-module.exports = {
-  WorkerDispatcher,
-  workerHandler,
-  streamingWorkerHandler
-};
-
-/***/ }),
+/* 1390 */,
+/* 1391 */,
+/* 1392 */,
 /* 1393 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+/* 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/>. */
+
 function basename(path) {
   return path.split("/").pop();
 }
 
 function dirname(path) {
   const idx = path.lastIndexOf("/");
   return path.slice(0, idx);
 }
@@ -20989,121 +20860,122 @@ exports.join = join;
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.getSelectedFrame = exports.getLoadedObjects = exports.getPause = exports.State = undefined;
 
-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; };
+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; }; /* 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/>. */
+
 /* eslint complexity: ["error", 30]*/
 
-/* 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/. */
-
 /**
  * Pause reducer
  * @module reducers/pause
  */
 
+exports.getPauseReason = getPauseReason;
 exports.isStepping = isStepping;
 exports.isPaused = isPaused;
 exports.isEvaluatingExpression = isEvaluatingExpression;
-exports.pausedInEval = pausedInEval;
 exports.getLoadedObject = getLoadedObject;
+exports.hasLoadingObjects = hasLoadingObjects;
 exports.getObjectProperties = getObjectProperties;
 exports.getIsWaitingOnBreak = getIsWaitingOnBreak;
 exports.getShouldPauseOnExceptions = getShouldPauseOnExceptions;
 exports.getShouldIgnoreCaughtExceptions = getShouldIgnoreCaughtExceptions;
 exports.getFrames = getFrames;
-exports.getFrameScopes = getFrameScopes;
+exports.getFrameScope = getFrameScope;
+exports.getSelectedScope = getSelectedScope;
 exports.getScopes = getScopes;
 exports.getSelectedFrameId = getSelectedFrameId;
 exports.getDebuggeeUrl = getDebuggeeUrl;
 exports.getChromeScopes = getChromeScopes;
 
 var _reselect = __webpack_require__(993);
 
 var _prefs = __webpack_require__(226);
 
+var _lodash = __webpack_require__(2);
+
 const State = exports.State = () => ({
   pause: undefined,
+  why: null,
   isWaitingOnBreak: false,
   frames: undefined,
   selectedFrameId: undefined,
   frameScopes: {},
   loadedObjects: {},
   shouldPauseOnExceptions: _prefs.prefs.pauseOnExceptions,
   shouldIgnoreCaughtExceptions: _prefs.prefs.ignoreCaughtExceptions,
   debuggeeUrl: "",
   command: ""
 });
 
+const emptyPauseState = {
+  pause: null,
+  frames: null,
+  frameScopes: {},
+  selectedFrameId: null,
+  loadedObjects: {}
+};
+
 function update(state = State(), action) {
   switch (action.type) {
     case "PAUSED":
       {
-        const {
-          selectedFrameId,
-          frames,
-          scopes,
-          loadedObjects,
-          pauseInfo
-        } = action;
+        const { selectedFrameId, frames, loadedObjects, pauseInfo } = action;
+
+        const { why } = pauseInfo;
         pauseInfo.isInterrupted = pauseInfo.why.type === "interrupted";
 
-        const frameScopes = { [selectedFrameId]: scopes };
-
         // turn this into an object keyed by object id
         const objectMap = {};
         loadedObjects.forEach(obj => {
           objectMap[obj.value.objectId] = obj;
         });
 
-        return Object.assign({}, state, {
+        return _extends({}, state, {
           isWaitingOnBreak: false,
           pause: pauseInfo,
           selectedFrameId,
           frames,
-          frameScopes,
-          loadedObjects: objectMap
+          frameScopes: {},
+          loadedObjects: objectMap,
+          why
         });
       }
 
+    case "ADD_SCOPES":
     case "MAP_SCOPES":
       const { frame, scopes } = action;
       const selectedFrameId = frame.id;
 
-      return _extends({}, state, {
-        frameScopes: _extends({}, state.frameScopes, { [selectedFrameId]: scopes })
-      });
-    case "RESUME":
-      return Object.assign({}, state, {
-        pause: null,
-        frames: null,
-        selectedFrameId: null,
-        loadedObjects: {}
-      });
+      const frameScopes = _extends({}, state.frameScopes, { [selectedFrameId]: scopes });
+      return _extends({}, state, { frameScopes });
 
     case "TOGGLE_PRETTY_PRINT":
       if (action.status == "done") {
         const frames = action.value.frames;
         const pause = state.pause;
         if (pause) {
           pause.frame = frames[0];
         }
 
-        return Object.assign({}, state, { pause, frames });
+        return _extends({}, state, { pause, frames });
       }
 
       break;
+
     case "BREAK_ON_NEXT":
-      return Object.assign({}, state, { isWaitingOnBreak: true });
+      return _extends({}, state, { isWaitingOnBreak: true });
 
     case "SELECT_FRAME":
       return _extends({}, state, {
         selectedFrameId: action.frame.id
       });
 
     case "LOAD_OBJECT_PROPERTIES":
       if (action.status === "start") {
@@ -21111,58 +20983,60 @@ function update(state = State(), action)
           loadedObjects: _extends({}, state.loadedObjects, {
             [action.objectId]: {}
           })
         });
       }
 
       if (action.status === "done") {
         if (!action.value) {
-          return Object.assign({}, state);
+          return _extends({}, state);
         }
 
         const ownProperties = action.value.ownProperties;
         const ownSymbols = action.value.ownSymbols || [];
         const prototype = action.value.prototype;
 
         return _extends({}, state, {
           loadedObjects: _extends({}, state.loadedObjects, {
             [action.objectId]: { ownProperties, prototype, ownSymbols }
           })
         });
       }
       break;
 
     case "CONNECT":
-      return Object.assign({}, State(), { debuggeeUrl: action.url });
+      return _extends({}, State(), { debuggeeUrl: action.url });
 
     case "PAUSE_ON_EXCEPTIONS":
       const { shouldPauseOnExceptions, shouldIgnoreCaughtExceptions } = action;
 
       _prefs.prefs.pauseOnExceptions = shouldPauseOnExceptions;
       _prefs.prefs.ignoreCaughtExceptions = shouldIgnoreCaughtExceptions;
 
-      return Object.assign({}, state, {
+      return _extends({}, state, {
         shouldPauseOnExceptions,
         shouldIgnoreCaughtExceptions
       });
 
     case "COMMAND":
-      return _extends({}, state, { command: action.value.type });
-
-    case "CLEAR_COMMAND":
-      return _extends({}, state, { command: "" });
+      return action.status === "start" ? _extends({}, state, emptyPauseState, { command: action.command }) : _extends({}, state, { command: "" });
+
+    case "RESUME":
+      // We clear why on resume because we need it to decide if
+      // we shoul re-evaluate watch expressions.
+      return _extends({}, state, { why: null });
 
     case "EVALUATE_EXPRESSION":
       return _extends({}, state, {
         command: action.status === "start" ? "expression" : ""
       });
 
     case "NAVIGATE":
-      return _extends({}, state, { debuggeeUrl: action.url });
+      return _extends({}, state, emptyPauseState, { debuggeeUrl: action.url });
   }
 
   return state;
 }
 
 // Selectors
 
 // Unfortunately, it's really hard to make these functions accept just
@@ -21175,45 +21049,41 @@ function update(state = State(), action)
 
 
 const getPauseState = state => state.pause;
 
 const getPause = exports.getPause = (0, _reselect.createSelector)(getPauseState, pauseWrapper => pauseWrapper.pause);
 
 const getLoadedObjects = exports.getLoadedObjects = (0, _reselect.createSelector)(getPauseState, pauseWrapper => pauseWrapper.loadedObjects);
 
+function getPauseReason(state) {
+  return state.pause.why;
+}
+
 function isStepping(state) {
   return ["stepIn", "stepOver", "stepOut"].includes(state.pause.command);
 }
 
 function isPaused(state) {
   return !!getPause(state);
 }
 
 function isEvaluatingExpression(state) {
   return state.pause.command === "expression";
 }
 
-function pausedInEval(state) {
-  if (!state.pause.pause) {
-    return false;
-  }
-
-  const exception = state.pause.pause.why.exception;
-  if (!exception) {
-    return false;
-  }
-
-  return exception.preview.fileName === "debugger eval code";
-}
-
 function getLoadedObject(state, objectId) {
   return getLoadedObjects(state)[objectId];
 }
 
+function hasLoadingObjects(state) {
+  const objects = getLoadedObjects(state);
+  return Object.values(objects).some(_lodash.isEmpty);
+}
+
 function getObjectProperties(state, parentId) {
   return getLoadedObjects(state).filter(obj => obj.parentId == parentId);
 }
 
 function getIsWaitingOnBreak(state) {
   return state.pause.isWaitingOnBreak;
 }
 
@@ -21224,20 +21094,29 @@ function getShouldPauseOnExceptions(stat
 function getShouldIgnoreCaughtExceptions(state) {
   return state.pause.shouldIgnoreCaughtExceptions;
 }
 
 function getFrames(state) {
   return state.pause.frames;
 }
 
-function getFrameScopes(state, frameId) {
+function getFrameScope(state, frameId) {
+  if (!frameId) {
+    return null;
+  }
+
   return state.pause.frameScopes[frameId];
 }
 
+function getSelectedScope(state) {
+  const frameId = getSelectedFrameId(state);
+  return getFrameScope(state, frameId);
+}
+
 function getScopes(state) {
   const selectedFrameId = getSelectedFrameId(state);
   return state.pause.frameScopes[selectedFrameId];
 }
 
 function getSelectedFrameId(state) {
   return state.pause.selectedFrameId;
 }
@@ -21270,17 +21149,19 @@ exports.default = update;
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.findSourceMatches = exports.searchSources = exports.getMatches = exports.stopSearchWorker = exports.startSearchWorker = undefined;
 
 var _devtoolsUtils = __webpack_require__(1363);
 
-const { WorkerDispatcher } = _devtoolsUtils.workerUtils;
+const { WorkerDispatcher } = _devtoolsUtils.workerUtils; /* 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 dispatcher = new WorkerDispatcher();
 const startSearchWorker = exports.startSearchWorker = dispatcher.start.bind(dispatcher);
 const stopSearchWorker = exports.stopSearchWorker = dispatcher.stop.bind(dispatcher);
 
 const getMatches = exports.getMatches = dispatcher.task("getMatches");
 const searchSources = exports.searchSources = dispatcher.task("searchSources");
 const findSourceMatches = exports.findSourceMatches = dispatcher.task("findSourceMatches");
@@ -21291,20 +21172,19 @@ const findSourceMatches = exports.findSo
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
-/* 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/. */
+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; }; /* 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/>. */
 
 /**
  * Redux actions for breakpoints
  * @module actions/breakpoints
  */
 
 // this will need to be changed so that addCLientBreakpoint is removed
 
@@ -21320,17 +21200,17 @@ exports.toggleBreakpoints = toggleBreakp
 exports.removeAllBreakpoints = removeAllBreakpoints;
 exports.removeBreakpoints = removeBreakpoints;
 exports.remapBreakpoints = remapBreakpoints;
 exports.setBreakpointCondition = setBreakpointCondition;
 exports.toggleBreakpoint = toggleBreakpoint;
 exports.addOrToggleDisabledBreakpoint = addOrToggleDisabledBreakpoint;
 exports.toggleDisabledBreakpoint = toggleDisabledBreakpoint;
 
-var _promise = __webpack_require__(1370);
+var _promise = __webpack_require__(1653);
 
 var _selectors = __webpack_require__(1352);
 
 var _breakpoint = __webpack_require__(1364);
 
 var _addBreakpoint = __webpack_require__(1519);
 
 var _addBreakpoint2 = _interopRequireDefault(_addBreakpoint);
@@ -21688,17 +21568,19 @@ async function getGeneratedLocation(stat
   const generatedSource = (0, _selectors.getSource)(state, sourceId);
   const sourceUrl = generatedSource.get("url");
   return {
     line,
     sourceId,
     column: column === 0 ? undefined : column,
     sourceUrl
   };
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1398 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -21708,19 +21590,17 @@ Object.defineProperty(exports, "__esModu
 exports.addExpression = addExpression;
 exports.updateExpression = updateExpression;
 exports.deleteExpression = deleteExpression;
 exports.evaluateExpressions = evaluateExpressions;
 exports.getMappedExpression = getMappedExpression;
 
 var _selectors = __webpack_require__(1352);
 
-var _promise = __webpack_require__(1370);
-
-var _utils = __webpack_require__(1522);
+var _promise = __webpack_require__(1653);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _expressions = __webpack_require__(1437);
 
 var _parser = __webpack_require__(1365);
 
 var parser = _interopRequireWildcard(_parser);
@@ -21749,17 +21629,19 @@ function addExpression(input) {
     dispatch({
       type: "ADD_EXPRESSION",
       input
     });
 
     const newExpression = (0, _selectors.getExpression)(getState(), input);
     dispatch(evaluateExpression(newExpression));
   };
-}
+} /* 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/>. */
 
 function updateExpression(input, expression) {
   return ({ dispatch, getState }) => {
     if (!input || input == expression.input) {
       return;
     }
 
     dispatch({
@@ -21828,16 +21710,17 @@ function evaluateExpression(expression) 
       const sourceId = source.get("id");
 
       if (!(0, _devtoolsSourceMap.isGeneratedId)(sourceId)) {
         input = await getMappedExpression({ sourceMaps }, generatedLocation, input);
       }
     }
 
     const frameId = (0, _selectors.getSelectedFrameId)(getState());
+
     return dispatch({
       type: "EVALUATE_EXPRESSION",
       input: expression.input,
       [_promise.PROMISE]: client.evaluate((0, _expressions.wrapExpression)(input), { frameId })
     });
   };
 }
 
@@ -21849,54 +21732,80 @@ async function getMappedExpression({ sou
   const astScopes = await parser.getScopes(generatedLocation);
 
   const generatedScopes = await sourceMaps.getLocationScopes(generatedLocation, astScopes);
 
   if (!generatedScopes) {
     return expression;
   }
 
-  return (0, _utils.replaceOriginalVariableName)(expression, generatedScopes);
+  return parser.replaceOriginalVariableName(expression, generatedScopes);
 }
 
 /***/ }),
 /* 1399 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
-
+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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+exports.setSourceMetaData = setSourceMetaData;
 exports.setSymbols = setSymbols;
 exports.setEmptyLines = setEmptyLines;
 exports.setOutOfScopeLocations = setOutOfScopeLocations;
 exports.clearPreview = clearPreview;
 exports.setPreview = setPreview;
 
 var _selectors = __webpack_require__(1352);
 
 var _expressions = __webpack_require__(1398);
 
-var _promise = __webpack_require__(1370);
+var _promise = __webpack_require__(1653);
 
 var _parser = __webpack_require__(1365);
 
 var _ast = __webpack_require__(1638);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 const extraProps = {
   react: { displayName: "this._reactInternalInstance.getName()" }
 };
 
+function setSourceMetaData(sourceId) {
+  return async ({ dispatch, getState }) => {
+    const sourceRecord = (0, _selectors.getSource)(getState(), sourceId);
+    if (!sourceRecord) {
+      return;
+    }
+
+    const source = sourceRecord.toJS();
+    if (!source.text || source.isWasm) {
+      return;
+    }
+
+    const isReactComp = await (0, _parser.isReactComponent)(source);
+    dispatch({
+      type: "SET_SOURCE_METADATA",
+      sourceId: source.id,
+      sourceMetaData: {
+        isReactComponent: isReactComp
+      }
+    });
+  };
+}
+
 function setSymbols(sourceId) {
   return async ({ dispatch, getState }) => {
     const sourceRecord = (0, _selectors.getSource)(getState(), sourceId);
     if (!sourceRecord) {
       return;
     }
 
     const source = sourceRecord.toJS();
@@ -22037,22 +21946,25 @@ function setPreview(token, tokenPos, cur
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.updateFrameLocations = updateFrameLocations;
 exports.updateScopeBindings = updateScopeBindings;
 exports.getPauseReason = getPauseReason;
 exports.getPausedPosition = getPausedPosition;
+exports.inDebuggerEval = inDebuggerEval;
 
 var _lodash = __webpack_require__(2);
 
 var _parser = __webpack_require__(1365);
 
 function updateFrameLocations(frames, sourceMaps) {
   if (!frames || frames.length == 0) {
     return Promise.resolve(frames);
@@ -22066,17 +21978,17 @@ function updateFrameLocations(frames, so
 
 function extendScope(scope, generatedScopes, index) {
   if (!scope) {
     return undefined;
   }
   if (index >= generatedScopes.length) {
     return scope;
   }
-  return Object.assign({}, scope, {
+  return _extends({}, scope, {
     parent: extendScope(scope.parent, generatedScopes, index + 1),
     sourceBindings: generatedScopes[index].bindings
   });
 }
 
 async function updateScopeBindings(scope, location, sourceMaps) {
   const astScopes = await (0, _parser.getScopes)(location);
   const generatedScopes = await sourceMaps.getLocationScopes(location, astScopes);
@@ -22123,32 +22035,44 @@ function getPauseReason(pauseInfo) {
 async function getPausedPosition(pauseInfo, sourceMaps) {
   let { frames } = pauseInfo;
   frames = await updateFrameLocations(frames, sourceMaps);
   const frame = frames[0];
   const { location } = frame;
   return location;
 }
 
+function inDebuggerEval(why) {
+  if (why && why.type === "exception" && why.exception && why.exception.preview && why.exception.preview.fileName) {
+    return why.exception.preview.fileName === "debugger eval code";
+  }
+
+  return false;
+}
+
 /***/ }),
 /* 1401 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.renderWasmText = exports.clearWasmStates = exports.wasmOffsetToLine = exports.lineToWasmOffset = exports.isWasm = exports.getWasmLineNumberFormatter = exports.getWasmText = undefined;
 
 var _WasmParser = __webpack_require__(677);
 
 var _WasmDis = __webpack_require__(678);
 
+/* 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/>. */
+
 var wasmStates = Object.create(null);
 
 /**
  * @memberof utils/wasm
  * @static
  */
 function getWasmText(sourceId, data) {
   const parser = new _WasmParser.BinaryReader();
@@ -22245,17 +22169,17 @@ function clearWasmStates() {
 
 function renderWasmText(sourceId, { binary }) {
   // binary does not survive as Uint8Array, converting from string
   const data = new Uint8Array(binary.length);
   for (let i = 0; i < data.length; i++) {
     data[i] = binary.charCodeAt(i);
   }
   const { lines } = getWasmText(sourceId, data);
-  const MAX_LINES = 100000;
+  const MAX_LINES = 1000000;
   if (lines.length > MAX_LINES) {
     lines.splice(MAX_LINES, lines.length - MAX_LINES);
     lines.push(";; .... text is truncated due to the size");
   }
   return lines;
 }
 
 exports.getWasmText = getWasmText;
@@ -22288,18 +22212,19 @@ function _interopRequireDefault(obj) { r
  * Ignore doing outline matches for less than 3 whitespaces
  *
  * @memberof utils/source-search
  * @static
  */
 function ignoreWhiteSpace(str) {
   return (/^\s{0,2}$/.test(str) ? "(?!\\s*.*)" : str
   );
-}
-
+} /* 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/>. */
 
 function wholeMatch(query, wholeWord) {
   if (query === "" || !wholeWord) {
     return query;
   }
 
   return `\\b${query}\\b`;
 }
@@ -22401,17 +22326,20 @@ class Modal extends _react2.default.Comp
           onClick: this.onClick
         },
         this.props.children
       )
     );
   }
 }
 
-exports.Modal = Modal;
+exports.Modal = Modal; /* 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/>. */
+
 Modal.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
 function Slide({
   in: inProp,
   children,
   additionalClass,
@@ -22438,17 +22366,19 @@ function Slide({
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* 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/>. */
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 __webpack_require__(1311);
 
 var _devtoolsComponents = __webpack_require__(1441);
@@ -22586,16 +22516,20 @@ Object.defineProperty(exports, "__esModu
 });
 exports.getFilenameFromPath = getFilenameFromPath;
 exports.getURL = getURL;
 
 var _url = __webpack_require__(334);
 
 var _lodash = __webpack_require__(2);
 
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 function getFilenameFromPath(pathname) {
   let filename = "";
   if (pathname) {
     filename = pathname.substring(pathname.lastIndexOf("/") + 1);
     // This file does not have a name. Default should be (index).
     if (filename == "" || !filename.includes(".")) {
       filename = "(index)";
     }
@@ -22692,17 +22626,19 @@ function scrollList(resultList, index) {
 
   const resultEl = resultList[index];
 
   if ((0, _devtoolsConfig.isFirefox)()) {
     resultEl.scrollIntoView({ block: "center", behavior: "smooth" });
   } else {
     chromeScrollList(resultEl, index);
   }
-}
+} /* 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/>. */
 
 function chromeScrollList(elem, index) {
   const resultsEl = elem.parentNode;
   if (!resultsEl || resultsEl.children.length === 0) {
     return;
   }
 
   const resultsHeight = resultsEl.clientHeight;
@@ -22739,16 +22675,20 @@ var _classnames2 = _interopRequireDefaul
 var _Svg = __webpack_require__(1359);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
 __webpack_require__(1321);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class PaneToggleButton extends _react.Component {
   shouldComponentUpdate(nextProps) {
     const { collapsed, horizontal } = this.props;
 
     return horizontal !== nextProps.horizontal || collapsed !== nextProps.collapsed;
   }
 
   render() {
@@ -23420,17 +23360,19 @@ exports.findScopeByName = findScopeByNam
 
 var _parser = __webpack_require__(1365);
 
 function containsPosition(a, b) {
   const startsBefore = a.start.line < b.line || a.start.line === b.line && a.start.column <= b.column;
   const endsAfter = a.end.line > b.line || a.end.line === b.line && a.end.column >= b.column;
 
   return startsBefore && endsAfter;
-}
+} /* 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/>. */
 
 function findClosestScope(functions, location) {
   return functions.reduce((found, currNode) => {
     if (currNode.name === "anonymous" || !containsPosition(currNode.location, location)) {
       return found;
     }
 
     if (!found) {
@@ -23454,17 +23396,17 @@ async function getASTLocation(source, lo
 
   const scope = findClosestScope(functions, location);
   if (scope) {
     // we only record the line, but at some point we may
     // also do column offsets
     const line = location.line - scope.location.start.line;
     return {
       name: scope.name,
-      offset: { line }
+      offset: { line, column: undefined }
     };
   }
   return { name: undefined, offset: location };
 }
 
 async function findScopeByName(source, name) {
   const symbols = await (0, _parser.getSymbols)(source);
   const functions = symbols.functions;
@@ -23496,20 +23438,19 @@ var _lodash = __webpack_require__(2);
 var _reselect = __webpack_require__(993);
 
 var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 const State = exports.State = (0, _makeRecord2.default)({
   expressions: (0, _immutable.List)(restoreExpressions())
-});
-/* 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 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/>. */
 
 /**
  * Expressions reducer
  * @module reducers/expressions
  */
 
 function update(state = State(), action) {
   switch (action.type) {
@@ -23608,20 +23549,19 @@ var _immutable = __webpack_require__(146
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 const State = exports.State = (0, _makeRecord2.default)({
   workers: (0, _immutable.List)()
-});
-/* 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 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/>. */
 
 /**
  * Debuggee reducer
  * @module reducers/debuggee
  */
 
 function debuggee(state = State(), action) {
   switch (action.type) {
@@ -23663,17 +23603,17 @@ var _breakpoint = __webpack_require__(13
 var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 /* 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/. */
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /**
  * Pending breakpoints reducer
  * @module reducers/pending-breakpoints
  */
 
 function initialState() {
   return (0, _makeRecord2.default)({
@@ -23846,16 +23786,17 @@ exports.default = update;
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.State = undefined;
+exports.getSelectedPrimaryPaneTab = getSelectedPrimaryPaneTab;
 exports.getActiveSearch = getActiveSearch;
 exports.getContextMenu = getContextMenu;
 exports.getFrameworkGroupingState = getFrameworkGroupingState;
 exports.getShownSource = getShownSource;
 exports.getPaneCollapse = getPaneCollapse;
 exports.getHighlightedLineRange = getHighlightedLineRange;
 exports.getConditionalPanelLine = getConditionalPanelLine;
 exports.getProjectDirectoryRoot = getProjectDirectoryRoot;
@@ -23866,24 +23807,25 @@ var _makeRecord = __webpack_require__(13
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 /* 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/. */
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /**
  * UI reducer
  * @module reducers/ui
  */
 
 const State = exports.State = (0, _makeRecord2.default)({
+  selectedPrimaryPaneTab: "sources",
   activeSearch: null,
   contextMenu: {},
   shownSource: "",
   projectDirectoryRoot: "",
   startPanelCollapsed: _prefs.prefs.startPanelCollapsed,
   endPanelCollapsed: _prefs.prefs.endPanelCollapsed,
   frameworkGroupingOn: _prefs.prefs.frameworkGroupingOn,
   highlightedLineRange: undefined,
@@ -23935,38 +23877,46 @@ function update(state = State(), action)
       let lineRange = {};
 
       if (start && end && sourceId) {
         lineRange = { start, end, sourceId };
       }
 
       return state.set("highlightedLineRange", lineRange);
 
+    case "CLOSE_QUICK_OPEN":
     case "CLEAR_HIGHLIGHT_LINES":
       return state.set("highlightedLineRange", {});
 
     case "OPEN_CONDITIONAL_PANEL":
       return state.set("conditionalPanelLine", action.line);
 
     case "CLOSE_CONDITIONAL_PANEL":
       return state.set("conditionalPanelLine", null);
 
     case "SET_PROJECT_DIRECTORY_ROOT":
       _prefs.prefs.projectDirectoryRoot = action.url;
       return state.set("projectDirectoryRoot", action.url);
 
+    case "SET_PRIMARY_PANE_TAB":
+      return state.set("selectedPrimaryPaneTab", action.tabName);
+
     default:
       {
         return state;
       }
   }
 }
 
 // NOTE: we'd like to have the app state fully typed
 // https://github.com/devtools-html/debugger.html/blob/master/src/reducers/sources.js#L179-L185
+function getSelectedPrimaryPaneTab(state) {
+  return state.ui.get("selectedPrimaryPaneTab");
+}
+
 function getActiveSearch(state) {
   return state.ui.get("activeSearch");
 }
 
 function getContextMenu(state) {
   return state.ui.get("contextMenu");
 }
 
@@ -24022,16 +23972,20 @@ exports.getFileSearchResults = getFileSe
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 /**
  * File Search reducer
  * @module reducers/fileSearch
  */
 
 const State = exports.State = (0, _makeRecord2.default)({
   query: "",
   searchResults: {
@@ -24129,20 +24083,19 @@ var _fromJS2 = _interopRequireDefault(_f
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 const State = exports.State = (0, _makeRecord2.default)({
   coverageOn: false,
   hitCount: I.Map()
-});
-/* 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 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/>. */
 
 /**
  * Code coverage reducer
  * @module reducers/coverage
  */
 
 function update(state = State(), action) {
   switch (action.type) {
@@ -24192,17 +24145,17 @@ var _makeRecord = __webpack_require__(13
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 /* 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/. */
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /**
  * Project text search reducer
  * @module reducers/project-text-search
  */
 
 function InitialState() {
   return (0, _makeRecord2.default)({ query: "", results: I.List() })();
@@ -24258,20 +24211,19 @@ var _makeRecord = __webpack_require__(13
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function InitialState() {
   return (0, _makeRecord2.default)({
     expanded: null
   })();
-}
-/* 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 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/>. */
 
 /**
  * Source tree reducer
  * @module reducers/source-tree
  */
 
 function update(state = InitialState(), action) {
   switch (action.type) {
@@ -24300,17 +24252,19 @@ exports.default = getVisibleBreakpoints;
 var _breakpoints = __webpack_require__(1378);
 
 var _sources = __webpack_require__(1369);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 function getLocation(breakpoint, isGeneratedSource) {
   return isGeneratedSource ? breakpoint.generatedLocation || breakpoint.location : breakpoint.location;
-}
+} /* 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/>. */
 
 function formatBreakpoint(breakpoint, selectedSource) {
   const { condition, loading, disabled, hidden } = breakpoint;
   const sourceId = selectedSource.get("id");
   const isGeneratedSource = (0, _devtoolsSourceMap.isGeneratedId)(sourceId);
 
   return {
     location: getLocation(breakpoint, isGeneratedSource),
@@ -24347,36 +24301,43 @@ function getVisibleBreakpoints(state) {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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.createFrame = createFrame;
 exports.createSource = createSource;
 exports.createPause = createPause;
 exports.createBreakpointLocation = createBreakpointLocation;
+/* 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 module converts Firefox specific types to the generic types
 
 function createFrame(frame) {
   let title;
   if (frame.type == "call") {
     const c = frame.callee;
     title = c.name || c.userDisplayName || c.displayName || L10N.getStr("anonymous");
   } else {
     title = `(${frame.type})`;
   }
   const location = {
     sourceId: frame.where.source.actor,
     line: frame.where.line,
     column: frame.where.column
   };
+
   return {
     id: frame.actor,
     displayName: title,
     location,
     generatedLocation: location,
     this: frame.this,
     scope: frame.environment
   };
@@ -24393,17 +24354,17 @@ function createSource(source, { supports
     loadedState: "unloaded"
   };
 }
 
 function createPause(packet, response) {
   // NOTE: useful when the debugger is already paused
   const frame = packet.frame || response.frames[0];
 
-  return Object.assign({}, packet, {
+  return _extends({}, packet, {
     frame: createFrame(frame),
     frames: response.frames.map(createFrame)
   });
 }
 
 // Firefox only returns `actualLocation` if it actually changed,
 // but we want it always to exist. Format `actualLocation` if it
 // exists, otherwise use `location`.
@@ -24430,16 +24391,20 @@ function createBreakpointLocation(locati
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.fromServerLocation = fromServerLocation;
 exports.toServerLocation = toServerLocation;
 exports.createFrame = createFrame;
 exports.createLoadedObject = createLoadedObject;
+/* 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/>. */
+
 function fromServerLocation(serverLocation) {
   if (serverLocation) {
     return {
       sourceId: serverLocation.scriptId,
       line: serverLocation.lineNumber + 1,
       column: serverLocation.columnNumber,
       sourceUrl: ""
     };
@@ -24479,16 +24444,21 @@ function createLoadedObject(serverObject
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.bootstrapStore = bootstrapStore;
 exports.bootstrapApp = bootstrapApp;
 exports.bootstrapWorkers = bootstrapWorkers;
 exports.teardownWorkers = teardownWorkers;
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
@@ -24506,17 +24476,17 @@ var _devtoolsLaunchpad = __webpack_requi
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _search = __webpack_require__(1395);
 
 var _prettyPrint = __webpack_require__(1431);
 
 var _parser = __webpack_require__(1365);
 
-var _createStore = __webpack_require__(1510);
+var _createStore = __webpack_require__(1658);
 
 var _createStore2 = _interopRequireDefault(_createStore);
 
 var _reducers = __webpack_require__(1516);
 
 var _reducers2 = _interopRequireDefault(_reducers);
 
 var _selectors = __webpack_require__(1352);
@@ -24531,17 +24501,17 @@ var _prefs = __webpack_require__(226);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function bootstrapStore(client, { services, toolboxActions }) {
   const createStore = (0, _createStore2.default)({
     log: (0, _devtoolsConfig.isTesting)() || (0, _devtoolsConfig.getValue)("logging.actions"),
     timing: (0, _devtoolsConfig.isDevelopment)(),
     makeThunkArgs: (args, state) => {
-      return Object.assign({}, args, { client }, services, toolboxActions);
+      return _extends({}, args, { client }, services, toolboxActions);
     }
   });
 
   const store = createStore((0, _redux.combineReducers)(_reducers2.default));
   store.subscribe(() => updatePrefs(store.getState()));
 
   const actions = (0, _redux.bindActionCreators)(__webpack_require__(1354).default, store.dispatch);
 
@@ -24607,17 +24577,19 @@ var _devtoolsUtils = __webpack_require__
 var _source = __webpack_require__(1356);
 
 var _assert = __webpack_require__(1384);
 
 var _assert2 = _interopRequireDefault(_assert);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const { WorkerDispatcher } = _devtoolsUtils.workerUtils;
+const { WorkerDispatcher } = _devtoolsUtils.workerUtils; /* 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 dispatcher = new WorkerDispatcher();
 const startPrettyPrintWorker = exports.startPrettyPrintWorker = dispatcher.start.bind(dispatcher);
 const stopPrettyPrintWorker = exports.stopPrettyPrintWorker = dispatcher.stop.bind(dispatcher);
 const _prettyPrint = dispatcher.task("prettyPrint");
 
 async function prettyPrint({ source, url }) {
   const indent = 2;
@@ -24648,17 +24620,19 @@ var _assert = __webpack_require__(1384);
 
 var _assert2 = _interopRequireDefault(_assert);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function reportException(who, exception) {
   const msg = `${who} threw an exception: `;
   console.error(msg, exception);
-}
+} /* 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/>. */
 
 function executeSoon(fn) {
   setTimeout(fn, 0);
 }
 
 exports.default = _assert2.default;
 
 /***/ }),
@@ -24682,17 +24656,17 @@ var _search = __webpack_require__(1395);
 var _selectors = __webpack_require__(1352);
 
 var _source = __webpack_require__(1356);
 
 var _sources = __webpack_require__(1373);
 
 /* 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/. */
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /**
  * Redux actions for the search state
  * @module actions/search
  */
 
 function addSearchQuery(query) {
   return ({ dispatch, getState }) => {
@@ -24754,24 +24728,28 @@ function searchSource(sourceId, query) {
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.loadSourceText = loadSourceText;
 
-var _promise = __webpack_require__(1370);
+var _promise = __webpack_require__(1653);
 
 var _ast = __webpack_require__(1399);
 
 var _selectors = __webpack_require__(1352);
 
 var _parser = __webpack_require__(1365);
 
+/* 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/>. */
+
 async function loadSource(source, { sourceMaps, client }) {
   if (sourceMaps.isOriginalId(source.id)) {
     return await sourceMaps.getOriginalSourceText(source);
   }
 
   const response = await client.sourceContents(source.id);
 
   return {
@@ -24801,16 +24779,17 @@ function loadSourceText(source) {
     const newSource = (0, _selectors.getSource)(getState(), source.id).toJS();
     if (newSource.isWasm) {
       return;
     }
 
     await (0, _parser.setSource)(newSource);
     await dispatch((0, _ast.setSymbols)(source.id));
     await dispatch((0, _ast.setEmptyLines)(source.id));
+    await dispatch((0, _ast.setSourceMetaData)(source.id));
   };
 }
 
 /***/ }),
 /* 1436 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -24822,17 +24801,19 @@ Object.defineProperty(exports, "__esModu
 exports.showLoading = exports.showSourceText = exports.updateDocument = exports.updateLineNumberFormat = exports.resetLineNumberFormat = exports.clearDocuments = exports.removeDocument = exports.setDocument = exports.getDocument = undefined;
 
 var _source = __webpack_require__(1356);
 
 var _wasm = __webpack_require__(1401);
 
 var _ui = __webpack_require__(1439);
 
-let sourceDocs = {};
+let sourceDocs = {}; /* 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/>. */
 
 function getDocument(key) {
   return sourceDocs[key];
 }
 
 function setDocument(key, doc) {
   sourceDocs[key] = doc;
 }
@@ -24897,38 +24878,40 @@ function setEditorText(editor, source) {
     editor.setText(text);
   }
 }
 
 /**
  * Handle getting the source document or creating a new
  * document with the correct mode and text.
  */
-function showSourceText(editor, source) {
+function showSourceText(editor, source, sourceMetaData) {
   if (!source) {
     return;
   }
 
   let doc = getDocument(source.id);
   if (editor.codeMirror.doc === doc) {
+    editor.setMode((0, _source.getMode)(source, sourceMetaData));
     return;
   }
 
   if (doc) {
     editor.replaceDocument(doc);
     updateLineNumberFormat(editor, source.id);
+    editor.setMode((0, _source.getMode)(source, sourceMetaData));
     return doc;
   }
 
   doc = editor.createDocument();
   setDocument(source.id, doc);
   editor.replaceDocument(doc);
 
   setEditorText(editor, source);
-  editor.setMode((0, _source.getMode)(source));
+  editor.setMode((0, _source.getMode)(source, sourceMetaData));
   updateLineNumberFormat(editor, source.id);
 }
 
 exports.getDocument = getDocument;
 exports.setDocument = setDocument;
 exports.removeDocument = removeDocument;
 exports.clearDocuments = clearDocuments;
 exports.resetLineNumberFormat = resetLineNumberFormat;
@@ -24959,17 +24942,19 @@ function sanitizeInput(input) {
 }
 
 /*
  * wrap the expression input in a try/catch so that it can be safely
  * evaluated.
  *
  * NOTE: we add line after the expression to protect against comments.
 */
-
+/* 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/>. */
 
 function wrapExpression(input) {
   return (0, _indentation.correctIndentation)(`
     try {
       ${sanitizeInput(input)}
     } catch (e) {
       e
     }
@@ -25025,16 +25010,20 @@ function getValue(expression) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.correctIndentation = correctIndentation;
+/* 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/>. */
+
 function getIndentation(lines) {
   const firstLine = lines[0];
   const secondLine = lines[1];
   const lastLine = lines[lines.length - 1];
 
   const _getIndentation = line => line && line.match(/^\s*/)[0].length;
 
   const indentations = [_getIndentation(firstLine), _getIndentation(secondLine), _getIndentation(lastLine)];
@@ -25059,16 +25048,20 @@ function correctIndentation(text) {
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.isVisible = isVisible;
 exports.getLineNumberWidth = getLineNumberWidth;
 exports.resizeBreakpointGutter = resizeBreakpointGutter;
 exports.resizeToggleButton = resizeToggleButton;
+/* 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/>. */
+
 /* Checks to see if the root element is available and
  * if the element is visible. We check the width of the element
  * because it is more reliable than either checking a focus state or
  * the visibleState or hidden property.
  */
 function isVisible() {
   const el = document.querySelector("#mount");
   return el && el.getBoundingClientRect().width;
@@ -25293,17 +25286,19 @@ function createNodeInTree(part, path, tr
 }
 
 /*
  * Look for the child directory
  * 1. if it exists return it
  * 2. if it does not exist create it
  * 3. if it is a file, replace it with a directory
  */
-
+/* 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/>. */
 
 function findOrCreateNode(parts, subTree, path, part, index, url, debuggeeHost) {
   const addedPartIsFile = (0, _utils.partIsFile)(index, parts, url);
   const { found: childFound, index: childIndex } = (0, _treeOrder.findNodeInContents)(subTree, (0, _treeOrder.createTreeNodeMatcher)(part, !addedPartIsFile, debuggeeHost));
 
   // we create and enter the new node
   if (!childFound) {
     return createNodeInTree(part, path, subTree, childIndex);
@@ -25415,17 +25410,19 @@ function collapseTree(node, depth = 0) {
         return collapseTree((0, _utils.createNode)(`${node.name}/${next.name}`, next.path, next.contents), depth + 1);
       }
     }
     // Map the contents.
     return (0, _utils.createNode)(node.name, node.path, node.contents.map(next => collapseTree(next, depth + 1)));
   }
   // Node is a leaf, not a folder, do not modify it.
   return node;
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1445 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -25485,17 +25482,20 @@ class ResultList extends _react.Componen
 
     return _react2.default.createElement(
       "ul",
       { className: (0, _classnames2.default)("result-list", size) },
       items.map(this.renderListItem)
     );
   }
 }
-exports.default = ResultList;
+exports.default = ResultList; /* 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/>. */
+
 ResultList.defaultProps = {
   size: "small"
 };
 
 /***/ }),
 /* 1446 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -25513,16 +25513,20 @@ var _react2 = _interopRequireDefault(_re
 var _lodash = __webpack_require__(2);
 
 var _frame = __webpack_require__(1380);
 
 __webpack_require__(1320);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 function getFunctionName(func) {
   const name = func.userDisplayName || func.displayName || func.name;
   return (0, _frame.simplifyDisplayName)(name);
 }
 
 class PreviewFunction extends _react.Component {
   renderFunctionName(func) {
     const name = getFunctionName(func);
@@ -25604,28 +25608,30 @@ const { a, span } = React.DOM;
  */
 StringRep.propTypes = {
   useQuotes: React.PropTypes.bool,
   escapeWhitespace: React.PropTypes.bool,
   style: React.PropTypes.object,
   object: React.PropTypes.string.isRequired,
   member: React.PropTypes.any,
   cropLimit: React.PropTypes.number,
-  openLink: React.PropTypes.func
+  openLink: React.PropTypes.func,
+  omitLinkHref: React.PropTypes.bool
 };
 
 function StringRep(props) {
   let {
     cropLimit,
     object: text,
     member,
     style,
     useQuotes = true,
     escapeWhitespace = true,
-    openLink
+    openLink,
+    omitLinkHref = true
   } = props;
 
   let config = { className: "objectBox objectBox-string" };
   if (style) {
     config.style = style;
   }
 
   if (useQuotes) {
@@ -25653,17 +25659,17 @@ function StringRep(props) {
     tokenStart = text.indexOf(token, textIndex);
     if (isURL(token)) {
       items.push(text.slice(textIndex, tokenStart));
       textIndex = tokenStart + token.length;
 
       items.push(a({
         className: "url",
         title: token,
-        href: token,
+        href: omitLinkHref === true ? null : token,
         draggable: false,
         onClick: openLink ? e => {
           e.preventDefault();
           openLink(token);
         } : null
       }, token));
     }
   });
@@ -26692,16 +26698,20 @@ var _frame = __webpack_require__(1380);
 var _source = __webpack_require__(1356);
 
 var _FrameMenu = __webpack_require__(1454);
 
 var _FrameMenu2 = _interopRequireDefault(_FrameMenu);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 function FrameTitle({ frame, options }) {
   const displayName = (0, _frame.formatDisplayName)(frame, options);
   return _react2.default.createElement(
     "div",
     { className: "title" },
     displayName
   );
 }
@@ -26804,17 +26814,19 @@ Object.defineProperty(exports, "__esModu
 exports.default = FrameMenu;
 
 var _devtoolsLaunchpad = __webpack_require__(1362);
 
 var _clipboard = __webpack_require__(1388);
 
 var _lodash = __webpack_require__(2);
 
-const blackboxString = "sourceFooter.blackbox";
+const blackboxString = "sourceFooter.blackbox"; /* 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 unblackboxString = "sourceFooter.unblackbox";
 
 function formatMenuElement(labelString, click, disabled = false) {
   const label = L10N.getStr(labelString);
   const accesskey = L10N.getStr(`${labelString}.accesskey`);
   const id = `node-menu-${(0, _lodash.kebabCase)(label)}`;
   return {
@@ -26894,16 +26906,20 @@ var _devtoolsLaunchpad = __webpack_requi
 var _devtoolsConfig = __webpack_require__(1355);
 
 var _client = __webpack_require__(1499);
 
 var _bootstrap = __webpack_require__(1430);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 if (false) {
   window.Perf = require("react-addons-perf");
 }
 
 if ((0, _devtoolsConfig.isFirefoxPanel)()) {
   module.exports = {
     bootstrap: ({
       threadClient,
@@ -30251,22 +30267,30 @@ var _firefox = __webpack_require__(1500)
 var firefox = _interopRequireWildcard(_firefox);
 
 var _chrome = __webpack_require__(1507);
 
 var chrome = _interopRequireWildcard(_chrome);
 
 var _prefs = __webpack_require__(226);
 
+var _timings = __webpack_require__(1657);
+
+var timings = _interopRequireWildcard(_timings);
+
 var _devtoolsConfig = __webpack_require__(1355);
 
 var _bootstrap = __webpack_require__(1430);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
+/* 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/>. */
+
 function loadFromPrefs(actions) {
   const { pauseOnExceptions, ignoreCaughtExceptions } = _prefs.prefs;
   if (pauseOnExceptions || ignoreCaughtExceptions) {
     return actions.pauseOnExceptions(pauseOnExceptions, ignoreCaughtExceptions);
   }
 }
 
 function getClient(connection) {
@@ -30296,17 +30320,18 @@ async function onConnect(connection, { s
       store,
       actions,
       selectors,
       client: client.clientCommands,
       prefs: _prefs.prefs,
       features: _prefs.features,
       connection,
       bpClients,
-      services
+      services,
+      timings
     };
   };
 
   if (!(0, _devtoolsConfig.isFirefoxPanel)()) {
     console.group("Development Notes");
     const baseUrl = "https://devtools-html.github.io/debugger.html";
     const localDevelopmentUrl = `${baseUrl}/docs/local-development.html`;
     console.log("Debugging Tips", localDevelopmentUrl);
@@ -30391,17 +30416,19 @@ async function onConnect(connection, act
   // If the threadClient is already paused, make sure to show a
   // paused state.
   const pausedPacket = threadClient.getLastPausePacket();
   if (pausedPacket) {
     _events.clientEvents.paused("paused", pausedPacket);
   }
 
   return { bpClients };
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.clientCommands = _commands.clientCommands;
 exports.clientEvents = _events.clientEvents;
 
 /***/ }),
 /* 1501 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -30412,16 +30439,20 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.clientCommands = exports.setupCommands = undefined;
 
 var _breakpoint = __webpack_require__(1364);
 
 var _create = __webpack_require__(1428);
 
+/* 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/>. */
+
 let bpClients;
 let threadClient;
 let tabTarget;
 let debuggerClient;
 let supportsWasm;
 
 function setupCommands(dependencies) {
   threadClient = dependencies.threadClient;
@@ -30670,17 +30701,19 @@ var _immutable = __webpack_require__(146
 var I = _interopRequireWildcard(_immutable);
 
 var _lodash = __webpack_require__(2);
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
 // hasOwnProperty is defensive because it is possible that the
 // object that we're creating a map for has a `hasOwnProperty` field
-
+/* 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/>. */
 
 /**
  * Immutable JS conversion utils
  * @deprecated
  * @module utils/fromJS
  */
 
 function hasOwnProperty(value, key) {
@@ -30782,17 +30815,19 @@ var _sources = __webpack_require__(1369)
 
 var _breakpoints = __webpack_require__(1378);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 function isGenerated(selectedSource) {
   const sourceId = selectedSource.get("id");
   return (0, _devtoolsSourceMap.isGeneratedId)(sourceId);
-}
+} /* 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/>. */
 
 function getColumn(column, selectedSource) {
   if (column) {
     return column;
   }
 
   return isGenerated(selectedSource) ? undefined : 0;
 }
@@ -30861,17 +30896,19 @@ var _source = __webpack_require__(1356);
 var _lodash = __webpack_require__(2);
 
 function getOutOfScopeLines(outOfScopeLocations) {
   if (!outOfScopeLocations) {
     return null;
   }
 
   return (0, _lodash.uniq)((0, _lodash.flatMap)(outOfScopeLocations, location => (0, _lodash.range)(location.start.line, location.end.line)));
-}
+} /* 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/>. */
 
 function getInScopeLines(state) {
   const source = (0, _sources.getSelectedSource)(state);
   const outOfScopeLocations = (0, _ast.getOutOfScopeLocations)(state);
 
   if (!source || !source.get("text")) {
     return;
   }
@@ -30903,16 +30940,20 @@ exports.default = isSelectedFrameVisible
 var _pause = __webpack_require__(1394);
 
 var _sources = __webpack_require__(1369);
 
 /*
  * Checks to if the selected frame's source is currently
  * selected.
  */
+/* 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/>. */
+
 function isSelectedFrameVisible(state) {
   const selectedLocation = (0, _sources.getSelectedLocation)(state);
   const selectedFrame = (0, _pause.getSelectedFrame)(state);
 
   return selectedFrame && selectedLocation && selectedFrame.location.sourceId == selectedLocation.sourceId;
 }
 
 /***/ }),
@@ -30926,17 +30967,19 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.clientEvents = exports.setupEvents = undefined;
 
 var _create = __webpack_require__(1428);
 
 var _devtoolsConfig = __webpack_require__(1355);
 
-const CALL_STACK_PAGE_SIZE = 1000;
+const CALL_STACK_PAGE_SIZE = 1000; /* 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/>. */
 
 let threadClient;
 let actions;
 let supportsWasm;
 
 function setupEvents(dependencies) {
   threadClient = dependencies.threadClient;
   actions = dependencies.actions;
@@ -31000,16 +31043,20 @@ Object.defineProperty(exports, "__esModu
 });
 exports.clientEvents = exports.clientCommands = undefined;
 exports.onConnect = onConnect;
 
 var _commands = __webpack_require__(1508);
 
 var _events = __webpack_require__(1509);
 
+/* 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/>. */
+
 async function onConnect(connection, actions) {
   const { tabConnection, connTarget: { type } } = connection;
   const { Debugger, Runtime, Page } = tabConnection;
 
   Debugger.enable();
   Debugger.setPauseOnExceptions({ state: "none" });
   Debugger.setAsyncCallStackDepth({ maxDepth: 0 });
 
@@ -31041,17 +31088,19 @@ exports.clientEvents = _events.clientEve
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.clientCommands = exports.setupCommands = undefined;
 
 var _create = __webpack_require__(1429);
 
-let debuggerAgent;
+let debuggerAgent; /* 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/>. */
 
 let runtimeAgent;
 let pageAgent;
 
 function setupCommands({ Debugger, Runtime, Page }) {
   debuggerAgent = Debugger;
   runtimeAgent = Runtime;
   pageAgent = Page;
@@ -31162,20 +31211,23 @@ exports.clientCommands = clientCommands;
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.clientEvents = exports.pageEvents = exports.setupEvents = undefined;
 
+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; }; /* 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/>. */
+
 var _create = __webpack_require__(1429);
 
 let actions;
-
 let pageAgent;
 let clientType;
 let runtimeAgent;
 
 function setupEvents(dependencies) {
   actions = dependencies.actions;
   pageAgent = dependencies.Page;
   clientType = dependencies.clientType;
@@ -31221,19 +31273,17 @@ async function paused({
   callFrames,
   reason,
   data,
   hitBreakpoints,
   asyncStackTrace
 }) {
   const frames = callFrames.map(_create.createFrame);
   const frame = frames[0];
-  const why = Object.assign({}, {
-    type: reason
-  }, data);
+  const why = _extends({ type: reason }, data);
 
   const objectId = frame.scopeChain[0].object.objectId;
   const { result } = await runtimeAgent.getProperties({
     objectId
   });
 
   const loadedObjects = result.map(_create.createLoadedObject);
 
@@ -31285,359 +31335,22 @@ const pageEvents = {
   frameStoppedLoading
 };
 
 exports.setupEvents = setupEvents;
 exports.pageEvents = pageEvents;
 exports.clientEvents = clientEvents;
 
 /***/ }),
-/* 1510 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-
-var _redux = __webpack_require__(3);
-
-var _waitService = __webpack_require__(1511);
-
-var _log = __webpack_require__(1512);
-
-var _history = __webpack_require__(1513);
-
-var _promise = __webpack_require__(1370);
-
-var _thunk = __webpack_require__(1514);
-
-var _timing = __webpack_require__(1515);
-
-/**
- * This creates a dispatcher with all the standard middleware in place
- * that all code requires. It can also be optionally configured in
- * various ways, such as logging and recording.
- *
- * @param {object} opts:
- *        - log: log all dispatched actions to console
- *        - history: an array to store every action in. Should only be
- *                   used in tests.
- *        - middleware: array of middleware to be included in the redux store
- * @memberof utils/create-store
- * @static
- */
-
-
-/**
- * @memberof utils/create-store
- * @static
- */
-const configureStore = (opts = {}) => {
-  const middleware = [(0, _thunk.thunk)(opts.makeThunkArgs), _promise.promise,
-
-  // Order is important: services must go last as they always
-  // operate on "already transformed" actions. Actions going through
-  // them shouldn't have any special fields like promises, they
-  // should just be normal JSON objects.
-  _waitService.waitUntilService];
-
-  if (opts.history) {
-    middleware.push((0, _history.history)(opts.history));
-  }
-
-  if (opts.middleware) {
-    opts.middleware.forEach(fn => middleware.push(fn));
-  }
-
-  if (opts.log) {
-    middleware.push(_log.log);
-  }
-
-  if (opts.timing) {
-    middleware.push(_timing.timing);
-  }
-
-  // Hook in the redux devtools browser extension if it exists
-  const devtoolsExt = typeof window === "object" && window.devToolsExtension ? window.devToolsExtension() : f => f;
-
-  return (0, _redux.applyMiddleware)(...middleware)(devtoolsExt(_redux.createStore));
-};
-
-/* 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/. */
-/* global window */
-
-/**
- * Redux store utils
- * @module utils/create-store
- */
-
-exports.default = configureStore;
-
-/***/ }),
-/* 1511 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.waitUntilService = waitUntilService;
-
-
-/**
- * A middleware which acts like a service, because it is stateful
- * and "long-running" in the background. It provides the ability
- * for actions to install a function to be run once when a specific
- * condition is met by an action coming through the system. Think of
- * it as a thunk that blocks until the condition is met. Example:
- *
- * ```js
- * const services = { WAIT_UNTIL: require('wait-service').NAME };
- *
- * { type: services.WAIT_UNTIL,
- *   predicate: action => action.type === "ADD_ITEM",
- *   run: (dispatch, getState, action) => {
- *     // Do anything here. You only need to accept the arguments
- *     // if you need them. `action` is the action that satisfied
- *     // the predicate.
- *   }
- * }
- * ```
- */
-const NAME = exports.NAME = "@@service/waitUntil";
-
-function waitUntilService({ dispatch, getState }) {
-  let pending = [];
-
-  function checkPending(action) {
-    const readyRequests = [];
-    const stillPending = [];
-
-    // Find the pending requests whose predicates are satisfied with
-    // this action. Wait to run the requests until after we update the
-    // pending queue because the request handler may synchronously
-    // dispatch again and run this service (that use case is
-    // completely valid).
-    for (const request of pending) {
-      if (request.predicate(action)) {
-        readyRequests.push(request);
-      } else {
-        stillPending.push(request);
-      }
-    }
-
-    pending = stillPending;
-    for (const request of readyRequests) {
-      request.run(dispatch, getState, action);
-    }
-  }
-
-  return next => action => {
-    if (action.type === NAME) {
-      pending.push(action);
-      return null;
-    }
-    const result = next(action);
-    checkPending(action);
-    return result;
-  };
-}
-
-/***/ }),
-/* 1512 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: 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.log = log;
-
-var _devtoolsConfig = __webpack_require__(1355);
-
-const blacklist = ["LOAD_OBJECT_PROPERTIES", "SET_SYMBOLS", "OUT_OF_SCOPE_LOCATIONS"];
-
-function cloneAction(action) {
-  action = action || {};
-  action = _extends({}, action);
-
-  // ADD_TAB, ...
-  if (action.source && action.source.text) {
-    const source = _extends({}, action.source, { text: "" });
-    action.source = source;
-  }
-
-  // LOAD_SOURCE_TEXT
-  if (action.text) {
-    action.text = "";
-  }
-
-  if (action.value && action.value.text) {
-    const value = _extends({}, action.value, { text: "" });
-    action.value = value;
-  }
-
-  return action;
-}
-
-function formatFrame(frame) {
-  const { id, location, displayName } = frame;
-  return { id, location, displayName };
-}
-
-function formatPause(pause) {
-  return _extends({}, pause, {
-    pauseInfo: { why: pause.pauseInfo.why },
-    scopes: [],
-    frames: pause.frames.map(formatFrame),
-    loadedObjects: []
-  });
-}
-
-function serializeAction(action) {
-  try {
-    action = cloneAction(action);
-    if (blacklist.includes(action.type)) {
-      action = {};
-    }
-
-    if (action.type === "PAUSED") {
-      action = formatPause(action);
-    }
-
-    // dump(`> ${action.type}...\n ${JSON.stringify(action)}\n`);
-    return JSON.stringify(action);
-  } catch (e) {
-    console.error(e);
-  }
-}
-
-/**
- * A middleware that logs all actions coming through the system
- * to the console.
- */
-function log({ dispatch, getState }) {
-  return next => action => {
-    const asyncMsg = !action.status ? "" : `[${action.status}]`;
-
-    if ((0, _devtoolsConfig.isTesting)()) {
-      dump(`[ACTION] ${action.type} ${asyncMsg} - ${serializeAction(action)}\n`);
-    } else {
-      console.log(action, asyncMsg);
-    }
-
-    next(action);
-  };
-}
-
-/***/ }),
-/* 1513 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.history = undefined;
-
-var _devtoolsConfig = __webpack_require__(1355);
-
-/**
- * A middleware that stores every action coming through the store in the passed
- * in logging object. Should only be used for tests, as it collects all
- * action information, which will cause memory bloat.
- */
-const history = exports.history = (log = []) => ({
-  dispatch,
-  getState
-}) => {
-  return next => action => {
-    if ((0, _devtoolsConfig.isDevelopment)()) {
-      log.push(action);
-    }
-
-    return next(action);
-  };
-};
-
-/***/ }),
-/* 1514 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.thunk = thunk;
-
-
-/**
- * A middleware that allows thunks (functions) to be dispatched. If
- * it's a thunk, it is called with an argument that contains
- * `dispatch`, `getState`, and any additional args passed in via the
- * middleware constructure. This allows the action to create multiple
- * actions (most likely asynchronously).
- */
-function thunk(makeArgs) {
-  return ({ dispatch, getState }) => {
-    const args = { dispatch, getState };
-
-    return next => action => {
-      return typeof action === "function" ? action(makeArgs ? makeArgs(args, getState()) : args) : next(action);
-    };
-  };
-}
-
-/***/ }),
-/* 1515 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.timing = timing;
-/**
- * Redux middleware that sets performance markers for all actions such that they
- * will appear in performance tooling under the User Timing API
- */
-
-const mark = window.performance && window.performance.mark ? window.performance.mark.bind(window.performance) : () => {};
-
-const measure = window.performance && window.performance.measure ? window.performance.measure.bind(window.performance) : () => {};
-
-function timing(store) {
-  return next => action => {
-    mark(`${action.type}_start`);
-    const result = next(action);
-    mark(`${action.type}_end`);
-    measure(`${action.type}`, `${action.type}_start`, `${action.type}_end`);
-    return result;
-  };
-}
-
-/***/ }),
+/* 1510 */,
+/* 1511 */,
+/* 1512 */,
+/* 1513 */,
+/* 1514 */,
+/* 1515 */,
 /* 1516 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -31846,16 +31559,20 @@ var _Tabs = __webpack_require__(1614);
 var _Tabs2 = _interopRequireDefault(_Tabs);
 
 var _QuickOpenModal = __webpack_require__(1652);
 
 var _QuickOpenModal2 = _interopRequireDefault(_QuickOpenModal);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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 shortcuts = new _devtoolsModules.KeyShortcuts({ window });
 
 const { appinfo } = _devtoolsModules.Services;
 
 const isMacOS = appinfo.OS === "Darwin";
 
 const verticalLayoutBreakpoint = window.matchMedia("(min-width: 800px)");
 
@@ -32105,17 +31822,19 @@ exports.default = (0, _reactRedux.connec
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* 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/>. */
 
 var _breakpoint = __webpack_require__(1364);
 
 var _selectors = __webpack_require__(1352);
 
 var _sourceMaps = __webpack_require__(1397);
 
 exports.default = async function addBreakpoint(getState, client, sourceMaps, { breakpoint }) {
@@ -32173,16 +31892,20 @@ exports.default = async function addBrea
 
 Object.defineProperty(exports, "__esModule", {
   value: 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 = remapLocations;
+/* 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/>. */
+
 function remapLocations(breakpoints, sourceId, sourceMaps) {
   const sourceBreakpoints = breakpoints.map(async breakpoint => {
     if (breakpoint.location.sourceId !== sourceId) {
       return breakpoint;
     }
     const location = await sourceMaps.getOriginalLocation(breakpoint.location);
     return _extends({}, breakpoint, { location });
   });
@@ -32196,17 +31919,19 @@ function remapLocations(breakpoints, sou
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.syncClientBreakpoint = syncClientBreakpoint;
 
 var _breakpoint = __webpack_require__(1364);
 
 var _sourceMaps = __webpack_require__(1397);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
@@ -32222,18 +31947,18 @@ async function makeScopedLocation({ name
   return {
     line,
     column: location.column,
     sourceUrl: source.url,
     sourceId: source.id
   };
 }
 
-function createSyncData(pendingBreakpoint, location, generatedLocation, previousLocation = null) {
-  const overrides = _extends({}, pendingBreakpoint, { generatedLocation });
+function createSyncData(id, pendingBreakpoint, location, generatedLocation, previousLocation = null) {
+  const overrides = _extends({}, pendingBreakpoint, { generatedLocation, id });
   const breakpoint = (0, _breakpoint.createBreakpoint)(location, overrides);
 
   (0, _breakpoint.assertBreakpoint)(breakpoint);
   return { breakpoint, previousLocation };
 }
 
 // we have three forms of syncing: disabled syncing, existing server syncing
 // and adding a new breakpoint
@@ -32259,71 +31984,40 @@ async function syncClientBreakpoint(getS
   const isSameLocation = !(0, _breakpoint.locationMoved)(generatedLocation, scopedGeneratedLocation);
 
   const existingClient = client.getBreakpointByLocation(generatedLocation);
 
   /** ******* CASE 1: No server change ***********/
   // early return if breakpoint is disabled or we are in the sameLocation
   // send update only to redux
   if (pendingBreakpoint.disabled || existingClient && isSameLocation) {
-    return createSyncData(pendingBreakpoint, scopedLocation, scopedGeneratedLocation);
+    const id = pendingBreakpoint.disabled ? "" : existingClient.id;
+    return createSyncData(id, pendingBreakpoint, scopedLocation, scopedGeneratedLocation);
   }
 
   // clear server breakpoints if they exist and we have moved
   if (existingClient) {
     await client.removeBreakpoint(generatedLocation);
   }
 
   /** ******* Case 2: Add New Breakpoint ***********/
   // If we are not disabled, set the breakpoint on the server and get
   // that info so we can set it on our breakpoints.
-  const clientBreakpoint = await client.setBreakpoint(scopedGeneratedLocation, pendingBreakpoint.condition, sourceMaps.isOriginalId(sourceId));
+  const { id, actualLocation } = await client.setBreakpoint(scopedGeneratedLocation, pendingBreakpoint.condition, sourceMaps.isOriginalId(sourceId));
 
   // the breakpoint might have slid server side, so we want to get the location
   // based on the server's return value
-  const newGeneratedLocation = clientBreakpoint.actualLocation;
+  const newGeneratedLocation = actualLocation;
   const newLocation = await sourceMaps.getOriginalLocation(newGeneratedLocation);
 
-  return createSyncData(pendingBreakpoint, newLocation, newGeneratedLocation, previousLocation);
-}
-
-/***/ }),
-/* 1522 */
-/***/ (function(module, exports) {
-
-
-
-function replaceOriginalVariableName(expression, generatedScopes) {
-  // JavaScript indetifier is a complex thing: it can contain '$', '\', ZWJ, any
-  // unicode letter or number. Simplifing that to latin character set for now.
-  // For simplicity, search only first characters of the expression to find an
-  // identifier/variable name.
-  const possibleVarNameRegex = /^([$\w]+)/;
-  const matchedVarName = possibleVarNameRegex.exec(expression);
-  if (!matchedVarName) {
-    return expression;
-  }
-
-  const originalName = matchedVarName[1];
-  // The generatedScopes sorted in inner-to-outer scope order, finding first.
-  const foundScope = generatedScopes.find(({ bindings }) => originalName in bindings);
-  if (!foundScope) {
-    return expression;
-  }
-
-  // Replace original name (which will be at the beginning of the expression)
-  // with found generated name.
-  const generatedName = foundScope.bindings[originalName];
-  const expressionWoOriginalName = expression.substring(originalName.length);
-  return `${generatedName}${expressionWoOriginalName}`;
-}
-
-module.exports = { replaceOriginalVariableName };
-
-/***/ }),
+  return createSyncData(id, pendingBreakpoint, newLocation, newGeneratedLocation, previousLocation);
+}
+
+/***/ }),
+/* 1522 */,
 /* 1523 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -32333,16 +32027,20 @@ exports.createPrettySource = createPrett
 var _selectors = __webpack_require__(1352);
 
 var _prettyPrint = __webpack_require__(1431);
 
 var _pause = __webpack_require__(1400);
 
 var _source = __webpack_require__(1356);
 
+/* 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/>. */
+
 function createPrettySource(sourceId) {
   return async ({ dispatch, getState, sourceMaps }) => {
     const source = (0, _selectors.getSource)(getState(), sourceId).toJS();
     const url = (0, _source.getPrettySourceURL)(source.url);
     const id = await sourceMaps.generatedToOriginalId(sourceId, url);
 
     const { code, mappings } = await (0, _prettyPrint.prettyPrint)({
       source,
@@ -32416,36 +32114,22 @@ function getTokenLocation(codeMirror, to
   const { line, ch } = codeMirror.coordsChar({ left, top });
 
   return {
     line: line + lineOffset,
     column: ch
   };
 }
 
-/**
- * Forces the breakpoint gutter to be the same size as the line
- * numbers gutter. Editor CSS will absolutely position the gutter
- * beneath the line numbers. This makes it easy to be flexible with
- * how we overlay breakpoints.
- */
-function resizeBreakpointGutter(editor) {
-  const gutters = editor.display.gutters;
-  const lineNumbers = gutters.querySelector(".CodeMirror-linenumbers");
-  const breakpoints = gutters.querySelector(".breakpoints");
-  breakpoints.style.width = `${lineNumbers.clientWidth}px`;
-}
-
 module.exports = {
   removeLineClass,
   clearLineClass,
   getTextForLine,
   getCursorLine,
-  getTokenLocation,
-  resizeBreakpointGutter
+  getTokenLocation
 };
 
 /***/ }),
 /* 1525 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -32464,17 +32148,19 @@ function getTokenLocation(codeMirror, to
     left: left + width / 2,
     top: top + height / 2
   });
 
   return {
     line: line + 1,
     column: ch
   };
-}
+} /* 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/>. */
 
 function updatePreview(target, editor, { linesInScope, preview, setPreview, clearPreview }) {
   const location = getTokenLocation(editor.codeMirror, target);
   const tokenText = target.innerText ? target.innerText.trim() : "";
   const cursorPos = target.getBoundingClientRect();
 
   if (preview) {
     // We are mousing over the same token as before
@@ -32531,17 +32217,19 @@ function getSearchCursor(cm, query, pos,
   const regexQuery = (0, _buildQuery2.default)(query, modifiers, { isGlobal: true });
   return cm.getSearchCursor(regexQuery, pos);
 }
 
 /**
  * @memberof utils/source-search
  * @static
  */
-
+/* 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/>. */
 
 function SearchState() {
   this.posFrom = this.posTo = this.query = null;
   this.overlay = null;
   this.results = [];
 }
 
 /**
@@ -32804,16 +32492,17 @@ exports.updateEventBreakpoints = updateE
 var _DevToolsUtils = __webpack_require__(1432);
 
 var _selectors = __webpack_require__(1352);
 
 // delay is in ms
 /* 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/. */
+
 /* global window gThreadClient setNamedTimeout services EVENTS */
 /* eslint no-shadow: 0  */
 
 /**
  * Redux actions for the event listeners state
  * @module actions/event-listeners
  */
 
@@ -32997,16 +32686,20 @@ var _wasm = __webpack_require__(1401);
  * Redux actions for the navigation state
  * @module actions/navigation
  */
 
 /**
  * @memberof actions/navigation
  * @static
  */
+/* 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/>. */
+
 function willNavigate(_, event) {
   return async function ({ dispatch, getState, client, sourceMaps }) {
     await sourceMaps.clearSourceMaps();
     (0, _wasm.clearWasmStates)();
     (0, _editor.clearDocuments)();
     (0, _parser.clearSymbols)();
     (0, _parser.clearASTs)();
     (0, _parser.clearScopes)();
@@ -33065,16 +32758,20 @@ exports.closeFileSearch = closeFileSearc
 var _editor = __webpack_require__(1358);
 
 var _search = __webpack_require__(1395);
 
 var _selectors = __webpack_require__(1352);
 
 var _ui = __webpack_require__(1385);
 
+/* 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/>. */
+
 function doSearch(query, editor) {
   return ({ getState, dispatch }) => {
     const selectedSource = (0, _selectors.getSelectedSource)(getState());
     if (!selectedSource || !selectedSource.get("text")) {
       return;
     }
 
     dispatch(setFileSearchQuery(query));
@@ -33182,17 +32879,19 @@ function recordCoverage() {
   return async function ({ dispatch, getState, client }) {
     const { coverage } = await client.recordCoverage();
 
     return dispatch({
       type: "RECORD_COVERAGE",
       value: { coverage }
     });
   };
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1532 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -33202,29 +32901,35 @@ Object.defineProperty(exports, "__esModu
 exports.setExpandedState = setExpandedState;
 function setExpandedState(expanded) {
   return ({ dispatch, getState }) => {
     dispatch({
       type: "SET_EXPANDED_STATE",
       expanded
     });
   };
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1533 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.setWorkers = setWorkers;
+/* 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/>. */
+
 function setWorkers(workers) {
   return {
     type: "SET_WORKERS",
     workers
   };
 }
 
 /***/ }),
@@ -33233,21 +32938,20 @@ function setWorkers(workers) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.openLink = openLink;
-
-
-/* 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 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 { isDevelopment } = __webpack_require__(1355);
 
 /**
  * @memberof actions/toolbox
  * @static
  */
 function openLink(url) {
   return async function ({ openLink: openLinkCommand }) {
@@ -33399,17 +33103,19 @@ class ShortcutsModal extends _react.Comp
         "in": enabled,
         additionalClass: "shortcuts-modal",
         handleClose: this.props.handleClose
       },
       this.renderShortcutsContent()
     );
   }
 }
-exports.ShortcutsModal = ShortcutsModal;
+exports.ShortcutsModal = ShortcutsModal; /* 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/>. */
 
 /***/ }),
 /* 1536 */
 /***/ (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/. */
@@ -33740,16 +33446,20 @@ var _TextSearch = __webpack_require__(15
 var _TextSearch2 = _interopRequireDefault(_TextSearch);
 
 var _selectors = __webpack_require__(1352);
 
 __webpack_require__(1317);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class ProjectSearch extends _react.Component {
 
   constructor(props) {
     super(props);
     this.toggleProjectTextSearch = this.toggleProjectTextSearch.bind(this);
   }
 
   componentDidMount() {
@@ -33998,16 +33708,17 @@ class TextSearch extends _react.Componen
   }
 
   renderMatchValue(lineMatch) {
     return (0, _highlight.highlightMatches)(lineMatch);
   }
 
   renderResults() {
     const results = this.getResults().filter(result => result.matches.length > 0);
+
     function getFilePath(item, index) {
       return item.filepath ? `${item.sourceId}-${index}` : `${item.sourceId}-${item.line}-${item.column}-${index}`;
     }
 
     const renderItem = (item, depth, focused, _, expanded, { setExpanded }) => {
       return item.filepath ? this.renderFile(item, focused, expanded, setExpanded) : this.renderMatch(item, focused);
     };
 
@@ -34028,24 +33739,23 @@ class TextSearch extends _react.Componen
         { className: "no-result-msg absolute-center" },
         L10N.getStr("projectTextSearch.noResults")
       );
     }
   }
 
   renderInput() {
     const resultCount = this.getResultCount();
-    const summaryMsg = L10N.getFormatStr("sourceSearch.resultsSummary1", resultCount);
 
     return _react2.default.createElement(_SearchInput2.default, {
       query: this.state.inputValue,
       count: resultCount,
       placeholder: L10N.getStr("projectTextSearch.placeholder"),
       size: "big",
-      summaryMsg: summaryMsg,
+      summaryMsg: this.props.query !== "" ? L10N.getFormatStr("sourceSearch.resultsSummary1", resultCount) : "",
       onChange: e => this.inputOnChange(e),
       onFocus: () => this.inputFocused = true,
       onBlur: () => this.inputFocused = false,
       onKeyDown: e => this.onKeyDown(e),
       handleClose: this.props.closeActiveSearch,
       ref: "searchInput"
     });
   }
@@ -34061,17 +33771,20 @@ class TextSearch extends _react.Componen
         this.renderInput(),
         searchBottomBar
       ),
       this.renderResults()
     );
   }
 }
 
-exports.default = TextSearch;
+exports.default = TextSearch; /* 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/>. */
+
 TextSearch.propTypes = {
   sources: _propTypes2.default.object,
   results: _propTypes2.default.array,
   query: _propTypes2.default.string,
   closeActiveSearch: _propTypes2.default.func,
   searchSources: _propTypes2.default.func,
   selectSource: _propTypes2.default.func,
   searchBottomBar: _propTypes2.default.object
@@ -34751,17 +34464,19 @@ function formatTree(tree, depth = 0, str
       str = formatTree(t, depth + 1, str);
     });
   } else {
     const id = tree.contents.get("id");
     str += `${whitespace} - ${tree.name} path=${tree.path} source_id=${id} \n`;
   }
 
   return str;
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1543 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -34774,16 +34489,20 @@ exports.createTreeNodeMatcher = createTr
 
 var _url = __webpack_require__(334);
 
 var _utils = __webpack_require__(1371);
 
 /*
  * Gets domain from url (without www prefix)
  */
+/* 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/>. */
+
 function getDomain(url) {
   // TODO: define how files should be ordered on the browser debugger
   if (!url) {
     return null;
   }
   const { host } = (0, _url.parse)(url);
   if (!host) {
     return null;
@@ -34895,17 +34614,19 @@ function createTreeNodeMatcher(part, isD
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.sortEntireTree = sortEntireTree;
 exports.sortTree = sortTree;
 
 var _utils = __webpack_require__(1371);
 
 /**
  * Look at the nodes in the source tree, and determine the index of where to
@@ -34960,16 +34681,20 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.getDirectories = getDirectories;
 
 var _utils = __webpack_require__(1371);
 
 var _getURL = __webpack_require__(1405);
 
+/* 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/>. */
+
 function findSource(sourceTree, sourceUrl) {
   let returnTarget = null;
   function _traverse(subtree) {
     if ((0, _utils.nodeHasChildren)(subtree)) {
       for (const child of subtree.contents) {
         _traverse(child);
       }
     } else if (!returnTarget) {
@@ -35037,17 +34762,19 @@ function createTree(sources, debuggeeUrl
   const sourceTree = (0, _collapseTree.collapseTree)(uncollapsedTree);
 
   return {
     uncollapsedTree,
     sourceTree,
     parentMap: (0, _utils.createParentMap)(sourceTree),
     focusedItem: null
   };
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1547 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -35080,17 +34807,21 @@ function highlightMatches(lineMatch) {
       value.substr(column, len)
     ),
     _react2.default.createElement(
       "span",
       { className: "line-match", key: 2 },
       value.slice(column + len, value.length)
     )
   );
-} // Maybe reuse file search's functions?
+} /* 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/>. */
+
+// Maybe reuse file search's functions?
 
 /***/ }),
 /* 1548 */,
 /* 1549 */,
 /* 1550 */,
 /* 1551 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -35134,51 +34865,50 @@ var _SourcesTree = __webpack_require__(1
 var _SourcesTree2 = _interopRequireDefault(_SourcesTree);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class PrimaryPanes extends _react.Component {
 
   constructor(props) {
     super(props);
-    this.state = { selectedPane: "sources" };
 
     this.renderShortcut = this.renderShortcut.bind(this);
     this.showPane = this.showPane.bind(this);
     this.renderTabs = this.renderTabs.bind(this);
   }
 
   showPane(selectedPane) {
-    this.setState({ selectedPane });
+    this.props.setPrimaryPaneTab(selectedPane);
   }
 
   renderOutlineTabs() {
     if (!(0, _devtoolsConfig.isEnabled)("outline")) {
       return;
     }
 
     const sources = (0, _text.formatKeyShortcut)(L10N.getStr("sources.header"));
 
     const outline = (0, _text.formatKeyShortcut)(L10N.getStr("outline.header"));
 
     return [_react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("tab", {
-          active: this.state.selectedPane === "sources"
+          active: this.props.selectedTab === "sources"
         }),
         onClick: () => this.showPane("sources"),
         key: "sources-tab"
       },
       sources
     ), _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("tab", {
-          active: this.state.selectedPane === "outline"
+          active: this.props.selectedTab === "outline"
         }),
         onClick: () => this.showPane("outline"),
         key: "outline-tab"
       },
       outline
     )];
   }
 
@@ -35215,28 +34945,31 @@ class PrimaryPanes extends _react.Compon
   }
 
   renderSources() {
     const { sources, selectSource } = this.props;
     return _react2.default.createElement(_SourcesTree2.default, { sources: sources, selectSource: selectSource });
   }
 
   render() {
-    const { selectedPane } = this.state;
+    const { selectedTab } = this.props;
 
     return _react2.default.createElement(
       "div",
       { className: "sources-panel" },
       this.renderTabs(),
-      selectedPane === "sources" ? this.renderSources() : this.renderOutline()
-    );
-  }
-}
+      selectedTab === "sources" ? this.renderSources() : this.renderOutline()
+    );
+  }
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.default = (0, _reactRedux.connect)(state => ({
+  selectedTab: (0, _selectors.getSelectedPrimaryPaneTab)(state),
   sources: (0, _selectors.getSources)(state),
   sourceSearchOn: (0, _selectors.getActiveSearch)(state) === "source"
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(PrimaryPanes);
 
 /***/ }),
 /* 1552 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -35267,16 +35000,20 @@ var _selectors = __webpack_require__(135
 var _PreviewFunction = __webpack_require__(1446);
 
 var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
 
 var _lodash = __webpack_require__(2);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class Outline extends _react.Component {
   selectItem(location) {
     const { selectedSource, selectSource } = this.props;
     if (!selectedSource) {
       return;
     }
     const selectedSourceId = selectedSource.get("id");
     const startLine = location.start.line;
@@ -35454,28 +35191,27 @@ class SourcesTree extends _react.Compone
   }
 
   componentWillReceiveProps(nextProps) {
     if (this.props.projectRoot !== nextProps.projectRoot || this.props.debuggeeUrl !== nextProps.debuggeeUrl) {
       // Recreate tree because the sort order changed
       this.setState((0, _sourcesTree.createTree)(nextProps.sources, nextProps.debuggeeUrl, nextProps.projectRoot));
       return;
     }
-    const { selectedSource } = this.props;
     if (nextProps.shownSource && nextProps.shownSource != this.props.shownSource) {
       const listItems = (0, _sourcesTree.getDirectories)(nextProps.shownSource, this.state.sourceTree);
 
       if (listItems && listItems[0]) {
         this.selectItem(listItems[0]);
       }
 
       return this.setState({ listItems });
     }
 
-    if (nextProps.selectedSource && nextProps.selectedSource != selectedSource) {
+    if (nextProps.selectedSource && nextProps.selectedSource != this.props.selectedSource) {
       const highlightItems = (0, _sourcesTree.getDirectories)(nextProps.selectedSource.get("url"), this.state.sourceTree);
 
       return this.setState({ highlightItems });
     }
 
     if (nextProps.sources === this.props.sources) {
       return;
     }
@@ -35525,22 +35261,28 @@ class SourcesTree extends _react.Compone
 
   getPath(item) {
     const { sources } = this.props;
     const blackBoxedPart = item.contents.get && sources.get(item.contents.get("id")).get("isBlackBoxed") ? "update" : "";
     return `${item.path}/${item.name}/${blackBoxedPart}`;
   }
 
   getIcon(sources, item, depth) {
+    const { debuggeeUrl } = this.props;
+
     if (item.path === "/Webpack") {
       return _react2.default.createElement(_Svg2.default, { name: "webpack" });
     }
 
     if (depth === 0) {
-      return _react2.default.createElement("img", { className: "domain" });
+      return _react2.default.createElement("img", {
+        className: (0, _classnames2.default)("domain", {
+          debuggee: debuggeeUrl && debuggeeUrl.includes(item.name)
+        })
+      });
     }
 
     if (!(0, _sourcesTree.nodeHasChildren)(item)) {
       const source = sources.get(item.contents.get("id"));
       if (source.get("isBlackBoxed")) {
         return _react2.default.createElement("img", { className: "blackBox" });
       }
       return _react2.default.createElement("img", { className: "file" });
@@ -35682,17 +35424,19 @@ class SourcesTree extends _react.Compone
 
 // Components
 
 
 // Types
 
 
 // Redux
-
+/* 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/>. */
 
 // React
 exports.default = (0, _reactRedux.connect)(state => {
   return {
     shownSource: (0, _selectors.getShownSource)(state),
     selectedSource: (0, _selectors.getSelectedSource)(state),
     debuggeeUrl: (0, _selectors.getDebuggeeUrl)(state),
     expanded: (0, _selectors.getExpandedState)(state),
@@ -35719,38 +35463,34 @@ var _propTypes2 = _interopRequireDefault
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _reactDom = __webpack_require__(4);
 
 var _reactDom2 = _interopRequireDefault(_reactDom);
 
-var _reactImmutableProptypes = __webpack_require__(150);
-
-var _reactImmutableProptypes2 = _interopRequireDefault(_reactImmutableProptypes);
-
-var _redux = __webpack_require__(3);
-
 var _reactRedux = __webpack_require__(1189);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
 var _devtoolsLaunchpad = __webpack_require__(1362);
 
 var _source = __webpack_require__(1356);
 
 var _devtoolsConfig = __webpack_require__(1355);
 
 var _devtoolsSourceEditor = __webpack_require__(1386);
 
 var _selectors = __webpack_require__(1352);
 
+var _redux = __webpack_require__(3);
+
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _Footer = __webpack_require__(1555);
 
 var _Footer2 = _interopRequireDefault(_Footer);
 
@@ -35803,75 +35543,72 @@ var _editor = __webpack_require__(1358);
 var _ui = __webpack_require__(1439);
 
 __webpack_require__(1332);
 
 __webpack_require__(1333);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+// Redux actions
+/* 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 cssVars = {
   searchbarHeight: "var(--editor-searchbar-height)",
   secondSearchbarHeight: "var(--editor-second-searchbar-height)",
   footerHeight: "var(--editor-footer-height)"
 };
 
-
 class Editor extends _react.PureComponent {
 
   constructor() {
     super();
 
     this.onToggleBreakpoint = (key, e) => {
       e.preventDefault();
-      const { codeMirror } = this.state.editor;
       const { selectedSource } = this.props;
-      const line = (0, _editor.getCursorLine)(codeMirror);
 
       if (!selectedSource) {
         return;
       }
 
-      const sourceLine = (0, _editor.toSourceLine)(selectedSource.get("id"), line);
+      const line = this.getCurrentLine();
 
       if (e.shiftKey) {
-        this.toggleConditionalPanel(sourceLine);
+        this.toggleConditionalPanel(line);
       } else {
-        this.props.toggleBreakpoint(sourceLine);
+        this.props.toggleBreakpoint(line);
       }
     };
 
     this.onEscape = (key, e) => {
       if (!this.state.editor) {
         return;
       }
 
       const { codeMirror } = this.state.editor;
       if (codeMirror.listSelections().length > 1) {
         codeMirror.execCommand("singleSelection");
         e.preventDefault();
       }
     };
 
     this.onSearchAgain = (_, e) => {
-      const { query, searchModifiers } = this.props;
-      const { editor: { codeMirror } } = this.state.editor;
-      const ctx = { ed: this.state.editor, cm: codeMirror };
-
-      const direction = e.shiftKey ? "prev" : "next";
-      (0, _editor.traverseResults)(e, ctx, query, direction, searchModifiers.toJS());
+      this.props.traverseResults(e.shiftKey, this.state.editor);
     };
 
     this.onGutterClick = (cm, line, gutter, ev) => {
       const {
         selectedSource,
-        toggleBreakpoint,
         conditionalPanelLine,
         closeConditionalPanel,
         addOrToggleDisabledBreakpoint,
+        toggleBreakpoint,
         continueToHere
       } = this.props;
 
       // ignore right clicks in the gutter
       if (ev.ctrlKey && ev.button === 0 || ev.which === 3 || selectedSource && selectedSource.get("isBlackBoxed") || !selectedSource) {
         return;
       }
 
@@ -35902,16 +35639,21 @@ class Editor extends _react.PureComponen
     };
 
     this.toggleConditionalPanel = line => {
       const {
         conditionalPanelLine,
         closeConditionalPanel,
         openConditionalPanel
       } = this.props;
+
+      if (!line || isNaN(line)) {
+        line = this.getCurrentLine();
+      }
+
       if (conditionalPanelLine) {
         return closeConditionalPanel();
       }
 
       return openConditionalPanel(line);
     };
 
     this.closeConditionalPanel = () => {
@@ -35927,17 +35669,17 @@ class Editor extends _react.PureComponen
     };
   }
 
   componentWillReceiveProps(nextProps) {
     if (!this.state.editor) {
       return;
     }
 
-    (0, _ui.resizeBreakpointGutter)(this.state.editor.codeMirror);
+    (0, _editor.resizeBreakpointGutter)(this.state.editor.codeMirror);
     (0, _ui.resizeToggleButton)(this.state.editor.codeMirror);
   }
 
   setupEditor() {
     const editor = (0, _editor.createEditor)();
 
     // disables the default search shortcuts
 
@@ -35946,17 +35688,17 @@ class Editor extends _react.PureComponen
     const node = _reactDom2.default.findDOMNode(this);
     if (node instanceof HTMLElement) {
       editor.appendToLocalElement(node.querySelector(".editor-mount"));
     }
 
     const { codeMirror } = editor;
     const codeMirrorWrapper = codeMirror.getWrapperElement();
 
-    (0, _ui.resizeBreakpointGutter)(codeMirror);
+    (0, _editor.resizeBreakpointGutter)(codeMirror);
     (0, _ui.resizeToggleButton)(codeMirror);
 
     (0, _devtoolsLaunchpad.debugGlobal)("cm", codeMirror);
 
     codeMirror.on("gutterClick", this.onGutterClick);
 
     // Set code editor wrapper to be focusable
     codeMirrorWrapper.tabIndex = 0;
@@ -36049,16 +35791,24 @@ class Editor extends _react.PureComponen
     // Only update and jump around in real source texts. This will
     // keep the jump state around until the real source text is
     // loaded.
     if (selectedSource && (0, _source.isLoaded)(selectedSource.toJS())) {
       this.highlightLine();
     }
   }
 
+  getCurrentLine() {
+    const { codeMirror } = this.state.editor;
+    const { selectedSource } = this.props;
+    const line = (0, _editor.getCursorLine)(codeMirror);
+
+    return (0, _editor.toSourceLine)(selectedSource.get("id"), line);
+  }
+
   onKeyDown(e) {
     const { codeMirror } = this.state.editor;
     const { key, target } = e;
     const codeWrapper = codeMirror.getWrapperElement();
     const textArea = codeWrapper.querySelector("textArea");
 
     if (key === "Escape" && target == textArea) {
       e.stopPropagation();
@@ -36079,17 +35829,16 @@ class Editor extends _react.PureComponen
    */
 
 
   openMenu(event) {
     event.stopPropagation();
     event.preventDefault();
 
     const { setContextMenu } = this.props;
-
     if (event.target.classList.contains("CodeMirror-linenumber")) {
       return setContextMenu("Gutter", event);
     }
 
     return setContextMenu("Editor", event);
   }
 
   onClick(e) {
@@ -36147,17 +35896,17 @@ class Editor extends _react.PureComponen
     }
 
     if (nextProps.startPanelSize !== this.props.startPanelSize || nextProps.endPanelSize !== this.props.endPanelSize) {
       this.state.editor.codeMirror.setSize();
     }
   }
 
   setText(props) {
-    const { selectedSource } = props;
+    const { selectedSource, sourceMetaData } = props;
     if (!this.state.editor) {
       return;
     }
 
     if (!selectedSource) {
       return this.showMessage("");
     }
 
@@ -36165,17 +35914,17 @@ class Editor extends _react.PureComponen
       return (0, _editor.showLoading)(this.state.editor);
     }
 
     if (selectedSource.get("error")) {
       return this.showMessage(selectedSource.get("error"));
     }
 
     if (selectedSource) {
-      return (0, _editor.showSourceText)(this.state.editor, selectedSource.toJS());
+      return (0, _editor.showSourceText)(this.state.editor, selectedSource.toJS(), sourceMetaData);
     }
   }
 
   showMessage(msg) {
     const { editor } = this.state;
     if (!editor) {
       return;
     }
@@ -36266,58 +36015,36 @@ class Editor extends _react.PureComponen
         className: "editor-mount devtools-monospace",
         style: this.getInlineEditorStyles()
       }),
       this.renderItems()
     );
   }
 }
 
-Editor.propTypes = {
-  hitCount: _propTypes2.default.object,
-  selectedLocation: _propTypes2.default.object,
-  selectedSource: _reactImmutableProptypes2.default.map,
-  searchOn: _propTypes2.default.bool,
-  addOrToggleDisabledBreakpoint: _propTypes2.default.func,
-  toggleBreakpoint: _propTypes2.default.func,
-  selectSource: _propTypes2.default.func,
-  jumpToMappedLocation: _propTypes2.default.func,
-  coverageOn: _propTypes2.default.bool,
-  selectedFrame: _propTypes2.default.object,
-  searchModifiers: _propTypes2.default.object,
-  query: _propTypes2.default.string,
-  horizontal: _propTypes2.default.bool,
-  startPanelSize: _propTypes2.default.number,
-  endPanelSize: _propTypes2.default.number,
-  conditionalPanelLine: _propTypes2.default.number,
-  openConditionalPanel: _propTypes2.default.func,
-  closeConditionalPanel: _propTypes2.default.func,
-  continueToHere: _propTypes2.default.func,
-  setContextMenu: _propTypes2.default.func
-};
-
 Editor.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
-exports.default = (0, _reactRedux.connect)(state => {
+const mapStateToProps = state => {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   const sourceId = selectedSource ? selectedSource.get("id") : "";
   return {
     selectedLocation: (0, _selectors.getSelectedLocation)(state),
     selectedSource,
     searchOn: (0, _selectors.getActiveSearch)(state) === "file",
     hitCount: (0, _selectors.getHitCountForSource)(state, sourceId),
     selectedFrame: (0, _selectors.getSelectedFrame)(state),
-    query: (0, _selectors.getFileSearchQuery)(state),
-    modifiers: (0, _selectors.getFileSearchModifiers)(state),
     coverageOn: (0, _selectors.getCoverageEnabled)(state),
-    conditionalPanelLine: (0, _selectors.getConditionalPanelLine)(state)
-  };
-}, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Editor);
+    conditionalPanelLine: (0, _selectors.getConditionalPanelLine)(state),
+    sourceMetaData: (0, _selectors.getSourceMetaData)(state, sourceId)
+  };
+};
+
+exports.default = (0, _reactRedux.connect)(mapStateToProps, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Editor);
 
 /***/ }),
 /* 1555 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -36480,17 +36207,20 @@ class SourceFooter extends _react.PureCo
 
     return _react2.default.createElement(
       "div",
       { className: "source-footer" },
       this.renderCommands(),
       this.renderToggleButton()
     );
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   const selectedId = selectedSource && selectedSource.get("id");
   return {
     selectedSource,
     prettySource: (0, _selectors.getPrettySource)(state, selectedId),
     endPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "end")
   };
@@ -36544,16 +36274,20 @@ var _SearchInput = __webpack_require__(1
 var _SearchInput2 = _interopRequireDefault(_SearchInput);
 
 var _lodash = __webpack_require__(2);
 
 __webpack_require__(1323);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 function getShortcuts() {
   const searchAgainKey = L10N.getStr("sourceSearch.search.again.key2");
   const searchAgainPrevKey = L10N.getStr("sourceSearch.search.againPrev.key2");
   const searchKey = L10N.getStr("sourceSearch.search.key2");
 
   return {
     shiftSearchAgainShortcut: searchAgainPrevKey,
     searchAgainShortcut: searchAgainKey,
@@ -36637,17 +36371,17 @@ class SearchBar extends _react.Component
     };
 
     this.onChange = e => {
       this.setState({ query: e.target.value });
 
       return this.doSearch(e.target.value);
     };
 
-    this.onKeyUp = e => {
+    this.onKeyDown = e => {
       if (e.key !== "Enter" && e.key !== "F3") {
         return;
       }
 
       this.traverseResults(e, e.shiftKey);
       e.preventDefault();
     };
 
@@ -36777,17 +36511,17 @@ class SearchBar extends _react.Component
       "div",
       { className: "search-bar" },
       _react2.default.createElement(_SearchInput2.default, {
         query: this.state.query,
         count: count,
         placeholder: L10N.getStr("sourceSearch.search.placeholder"),
         summaryMsg: this.buildSummaryMsg(),
         onChange: this.onChange,
-        onKeyUp: this.onKeyUp,
+        onKeyDown: this.onKeyDown,
         handleNext: e => this.traverseResults(e, false),
         handlePrev: e => this.traverseResults(e, true),
         handleClose: this.closeSearch
       }),
       _react2.default.createElement(
         "div",
         { className: "search-bottom-bar" },
         this.renderSearchModifiers()
@@ -36889,17 +36623,20 @@ class HighlightLines extends _react.Comp
         codeMirror.addLineClass(line, "line", "highlight-lines");
       });
     });
   }
 
   render() {
     return null;
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = (0, _reactRedux.connect)(state => ({
   highlightedLineRange: (0, _selectors.getHighlightedLineRange)(state)
 }))(HighlightLines);
 
 /***/ }),
 /* 1558 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -36929,34 +36666,51 @@ var _selectors = __webpack_require__(135
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _editor = __webpack_require__(1358);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class Preview extends _react.PureComponent {
 
   constructor() {
     super();
 
     const self = this;
     self.onScroll = this.onScroll.bind(this);
     self.onMouseOver = (0, _lodash.debounce)(this.onMouseOver, 40);
+    self.onMouseOver = this.onMouseOver.bind(this);
+    self.onMouseUp = this.onMouseUp.bind(this);
+    self.onMouseDown = this.onMouseDown.bind(this);
   }
 
   componentDidMount() {
     const { codeMirror } = this.props.editor;
     const codeMirrorWrapper = codeMirror.getWrapperElement();
 
     codeMirror.on("scroll", this.onScroll);
-    codeMirrorWrapper.addEventListener("mouseover", e => this.onMouseOver(e));
-    codeMirrorWrapper.addEventListener("mouseup", e => this.onMouseUp(e));
-    codeMirrorWrapper.addEventListener("mousedown", e => this.onMouseDown(e));
+    codeMirrorWrapper.addEventListener("mouseover", this.onMouseOver);
+    codeMirrorWrapper.addEventListener("mouseup", this.onMouseUp);
+    codeMirrorWrapper.addEventListener("mousedown", this.onMouseDown);
+  }
+
+  componentWillUnmount() {
+    const codeMirror = this.props.editor.codeMirror;
+    const codeMirrorWrapper = codeMirror.getWrapperElement();
+    codeMirrorWrapper.removeEventListener("mouseover", this.onMouseOver);
+    codeMirrorWrapper.removeEventListener("mouseup", this.onMouseUp);
+    codeMirrorWrapper.removeEventListener("mousedown", this.onMouseDown);
+
+    codeMirror.off("scroll", this.onScroll);
   }
 
   onMouseOver(e) {
     const { target } = e;
     if (this.props.selectedFrameVisible) {
       (0, _editor.updatePreview)(target, this.props.editor, this.props);
     }
   }
@@ -37056,17 +36810,19 @@ var _PreviewFunction = __webpack_require
 var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
 
 var _editor = __webpack_require__(1358);
 
 __webpack_require__(1328);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const { REPS: { Rep }, MODE, ObjectInspectorUtils } = _devtoolsReps2.default;
+const { REPS: { Rep }, MODE, ObjectInspectorUtils } = _devtoolsReps2.default; /* 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 { ObjectInspector } = _devtoolsReps2.default;
 const { getChildren } = ObjectInspectorUtils;
 
 function isReactComponent(roots) {
   return roots.some(root => root.name === "_reactInternalInstance");
 }
 
@@ -39814,17 +39570,19 @@ class Popover extends _react.Component {
     const { type } = this.props;
 
     if (type === "tooltip") {
       return this.renderTooltip();
     }
 
     return this.renderPopover();
   }
-}
+} /* 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/>. */
 
 Popover.defaultProps = {
   onMouseLeave: () => {},
   type: "popover"
 };
 exports.default = Popover;
 
 /***/ }),
@@ -39855,17 +39613,19 @@ const BracketArrow = ({
   left,
   top,
   bottom
 }) => {
   return _react2.default.createElement("div", {
     className: (0, _classnames2.default)("bracket-arrow", orientation || "up"),
     style: { left, top, bottom }
   });
-};
+}; /* This Source Code Form is subject to the terms of the Mozilla Public
+    * License, v. 2.0. If a copy of the MPL was not distributed with this
+    * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.default = BracketArrow;
 
 /***/ }),
 /* 1588 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -39908,39 +39668,44 @@ class Breakpoints extends _react.Compone
     if (nextProps.selectedSource && !(0, _source.isLoaded)(nextProps.selectedSource.toJS())) {
       return false;
     }
 
     return true;
   }
 
   render() {
-    const { breakpoints, selectedSource, editor } = this.props;
+    const { breakpoints, selectedSource, editor, sourceMetaData } = this.props;
 
     if (!selectedSource || !breakpoints || selectedSource.get("isBlackBoxed")) {
       return null;
     }
 
     return _react2.default.createElement(
       "div",
       null,
       breakpoints.valueSeq().map(bp => {
         return _react2.default.createElement(_Breakpoint2.default, {
           key: (0, _breakpoint.makeLocationId)(bp.location),
           breakpoint: bp,
           selectedSource: selectedSource,
+          sourceMetaData: sourceMetaData,
           editor: editor
         });
       })
     );
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = (0, _reactRedux.connect)(state => ({
   breakpoints: (0, _visibleBreakpoints2.default)(state),
-  selectedSource: (0, _selectors.getSelectedSource)(state)
+  selectedSource: (0, _selectors.getSelectedSource)(state),
+  sourceMetaData: (0, _selectors.getSourceMetaData)(state, (0, _selectors.getSelectedSource)(state).id)
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Breakpoints);
 
 /***/ }),
 /* 1589 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -39966,16 +39731,20 @@ var _classnames2 = _interopRequireDefaul
 var _Svg = __webpack_require__(1359);
 
 var _Svg2 = _interopRequireDefault(_Svg);
 
 var _editor = __webpack_require__(1358);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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 breakpointSvg = document.createElement("div");
 _reactDom2.default.render(_react2.default.createElement(_Svg2.default, { name: "breakpoint" }), breakpointSvg);
 
 function makeMarker(isDisabled) {
   const bp = breakpointSvg.cloneNode(true);
   bp.className = (0, _classnames2.default)("editor new-breakpoint", {
     "breakpoint-disabled": isDisabled,
     "folding-enabled": (0, _devtoolsConfig.isEnabled)("codeFolding")
@@ -39987,33 +39756,33 @@ function makeMarker(isDisabled) {
 class Breakpoint extends _react.Component {
 
   constructor() {
     super();
     this.addBreakpoint = this.addBreakpoint.bind(this);
   }
 
   addBreakpoint() {
-    const { breakpoint, editor, selectedSource } = this.props;
+    const { breakpoint, editor, selectedSource, sourceMetaData } = this.props;
 
     // Hidden Breakpoints are never rendered on the client
     if (breakpoint.hidden) {
       return;
     }
 
     // NOTE: we need to wait for the breakpoint to be loaded
     // to get the generated location
     if (!selectedSource || breakpoint.loading) {
       return;
     }
 
     const sourceId = selectedSource.get("id");
     const line = (0, _editor.toEditorLine)(sourceId, breakpoint.location.line);
 
-    (0, _editor.showSourceText)(editor, selectedSource.toJS());
+    (0, _editor.showSourceText)(editor, selectedSource.toJS(), sourceMetaData);
 
     editor.codeMirror.setGutterMarker(line, "breakpoints", makeMarker(breakpoint.disabled));
 
     editor.codeMirror.addLineClass(line, "line", "new-breakpoint");
     if (breakpoint.condition) {
       editor.codeMirror.addLineClass(line, "line", "has-condition");
     } else {
       editor.codeMirror.removeLineClass(line, "line", "has-condition");
@@ -40078,18 +39847,19 @@ exports.default = Breakpoint;
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _react = __webpack_require__(0);
 
-const markerEl = document.createElement("div");
-
+const markerEl = document.createElement("div"); /* 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/>. */
 
 function makeMarker() {
   const marker = markerEl.cloneNode(true);
   marker.className = "editor hit-marker";
   return marker;
 }
 
 class HitMarker extends _react.Component {
@@ -40135,17 +39905,19 @@ exports.default = HitMarker;
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* 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/>. */
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _redux = __webpack_require__(3);
@@ -40364,16 +40136,20 @@ exports.default = (0, _reactRedux.connec
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _react = __webpack_require__(0);
 
 var _editor = __webpack_require__(1358);
 
+/* 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/>. */
+
 __webpack_require__(1329);
 
 class CallSite extends _react.Component {
 
   constructor() {
     super();
 
     this.addCallSite = nextProps => {
@@ -40543,17 +40319,20 @@ class DebugLine extends _react.Component
     return { markTextClass: "debug-expression", lineClass: "new-debug-line" };
   }
 
   render() {
     return null;
   }
 }
 
-exports.DebugLine = DebugLine;
+exports.DebugLine = DebugLine; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = (0, _reactRedux.connect)(state => ({
   selectedLocation: (0, _selectors.getSelectedLocation)(state),
   selectedFrame: (0, _selectors.getSelectedFrame)(state),
   pauseInfo: (0, _selectors.getPause)(state)
 }))(DebugLine);
 
 /***/ }),
 /* 1594 */
@@ -40620,17 +40399,19 @@ class EmptyLines extends _react.Componen
         editor.codeMirror.addLineClass(line, "line", "empty-line");
       });
     });
   }
 
   render() {
     return null;
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   return {
     selectedSource,
     emptyLines: selectedSource ? (0, _selectors.getEmptyLines)(state, selectedSource.toJS()) : []
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(EmptyLines);
@@ -40641,17 +40422,19 @@ exports.default = (0, _reactRedux.connec
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.gutterMenu = gutterMenu;
 
 var _react = __webpack_require__(0);
 
 var _devtoolsLaunchpad = __webpack_require__(1362);
 
 var _redux = __webpack_require__(3);
@@ -40711,28 +40494,28 @@ function gutterMenu({
       label: L10N.getStr("editor.disableBreakpoint")
     },
     continueToHere: {
       id: "node-menu-continue-to-here",
       label: L10N.getStr("editor.continueToHere.label")
     }
   };
 
-  const toggleBreakpointItem = Object.assign({
+  const toggleBreakpointItem = _extends({
     accesskey: L10N.getStr("shortcuts.toggleBreakpoint.accesskey"),
     disabled: false,
     click: () => {
       toggleBreakpoint(line);
       if (isCbPanelOpen) {
         closeConditionalPanel();
       }
     }
   }, breakpoint ? gutterItems.removeBreakpoint : gutterItems.addBreakpoint);
 
-  const conditionalBreakpoint = Object.assign({
+  const conditionalBreakpoint = _extends({
     accesskey: L10N.getStr("editor.addConditionalBreakpoint.accesskey"),
     disabled: false,
     click: () => openConditionalPanel(line)
   }, breakpoint && breakpoint.condition ? gutterItems.editConditional : gutterItems.addConditional);
 
   const items = [toggleBreakpointItem, conditionalBreakpoint];
 
   if (pauseData) {
@@ -40740,17 +40523,17 @@ function gutterMenu({
       accesskey: L10N.getStr("editor.continueToHere.accesskey"),
       disabled: false,
       click: () => continueToHere(line)
     }, gutterItems.continueToHere);
     items.push(continueToHereItem);
   }
 
   if (breakpoint) {
-    const disableBreakpoint = Object.assign({
+    const disableBreakpoint = _extends({
       accesskey: L10N.getStr("editor.disableBreakpoint.accesskey"),
       disabled: false,
       click: () => toggleDisabledBreakpoint(line)
     }, breakpoint.disabled ? gutterItems.enableBreakpoint : gutterItems.disableBreakpoint);
     items.push(disableBreakpoint);
   }
 
   (0, _devtoolsLaunchpad.showMenu)(event, items);
@@ -40818,44 +40601,52 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _devtoolsLaunchpad = __webpack_require__(1362);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _clipboard = __webpack_require__(1388);
 
+var _source = __webpack_require__(1356);
+
 var _editor = __webpack_require__(1358);
 
 var _redux = __webpack_require__(3);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _function = __webpack_require__(1597);
 
+var _astBreakpointLocation = __webpack_require__(1416);
+
 var _selectors = __webpack_require__(1352);
 
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } /* 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/>. */
 
 function getMenuItems(event, {
   editor,
   selectedLocation,
   selectedSource,
   showSource,
   onGutterContextMenu,
   jumpToMappedLocation,
   toggleBlackBox,
   addExpression,
-  getFunctionText
+  getFunctionText,
+  getFunctionLocation,
+  flashLineRange
 }) {
   const copySourceLabel = L10N.getStr("copySource");
   const copySourceKey = L10N.getStr("copySource.accesskey");
   const copyFunctionLabel = L10N.getStr("copyFunction.label");
   const copyFunctionKey = L10N.getStr("copyFunction.accesskey");
   const copySourceUri2Label = L10N.getStr("copySourceUri2");
   const copySourceUri2Key = L10N.getStr("copySourceUri2.accesskey");
   const revealInTreeLabel = L10N.getStr("sourceTabs.revealInTree");
@@ -40884,57 +40675,67 @@ function getMenuItems(event, {
 
   const { line } = editor.codeMirror.coordsChar({
     left: event.clientX,
     top: event.clientY
   });
 
   const sourceLocation = (0, _editor.getSourceLocationFromMouseEvent)(editor, selectedLocation, event);
 
-  const pairedType = (0, _devtoolsSourceMap.isOriginalId)(selectedLocation.sourceId) ? L10N.getStr("generated") : L10N.getStr("original");
+  const isOriginal = (0, _devtoolsSourceMap.isOriginalId)(selectedLocation.sourceId);
+  const hasSourceMap = selectedSource.get("sourceMapURL");
+  const isPrettyPrinted = (0, _source.isPretty)(selectedSource.toJS());
 
   const jumpLabel = {
     accesskey: L10N.getStr("editor.jumpToMappedLocation1.accesskey"),
-    disabled: false,
-    label: L10N.getFormatStr("editor.jumpToMappedLocation1", pairedType),
+    disabled: _devtoolsSourceMap.isGeneratedId && !hasSourceMap,
+    label: L10N.getFormatStr("editor.jumpToMappedLocation1", isOriginal ? L10N.getStr("generated") : L10N.getStr("original")),
     click: () => jumpToMappedLocation(sourceLocation)
   };
 
   const watchExpressionLabel = {
     accesskey: L10N.getStr("expressions.accesskey"),
     label: L10N.getStr("expressions.label"),
     click: () => addExpression(editor.codeMirror.getSelection())
   };
 
   const blackBoxMenuItem = {
     id: "node-menu-blackbox",
     label: toggleBlackBoxLabel,
     accesskey: blackboxKey,
-    disabled: false,
+    disabled: isOriginal || isPrettyPrinted || hasSourceMap,
     click: () => toggleBlackBox(selectedSource.toJS())
   };
 
   // TODO: Find a new way to only add this for mapped sources?
   const textSelected = editor.codeMirror.somethingSelected();
 
   const showSourceMenuItem = {
     id: "node-menu-show-source",
     label: revealInTreeLabel,
     accesskey: revealInTreeKey,
-    disabled: false,
+    disabled: isPrettyPrinted,
     click: () => showSource(selectedSource.get("id"))
   };
 
   const functionText = getFunctionText(line + 1);
   const copyFunction = {
     id: "node-menu-copy-function",
     label: copyFunctionLabel,
     accesskey: copyFunctionKey,
     disabled: !functionText,
-    click: () => (0, _clipboard.copyToTheClipboard)(functionText)
+    click: () => {
+      const { location: { start, end } } = getFunctionLocation(line);
+      flashLineRange({
+        start: start.line,
+        end: end.line,
+        sourceId: selectedLocation.sourceId
+      });
+      return (0, _clipboard.copyToTheClipboard)(functionText);
+    }
   };
 
   const menuItems = [copySource, copySourceUri2, copyFunction, { type: "separator" }, jumpLabel, showSourceMenuItem, blackBoxMenuItem];
 
   if (textSelected) {
     menuItems.push(watchExpressionLabel);
   }
 
@@ -40970,17 +40771,21 @@ class EditorMenu extends _react.PureComp
 }
 
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   return {
     selectedLocation: (0, _selectors.getSelectedLocation)(state),
     selectedSource,
     contextMenu: (0, _selectors.getContextMenu)(state),
-    getFunctionText: line => (0, _function.findFunctionText)(line, selectedSource.toJS(), (0, _selectors.getSymbols)(state, selectedSource.toJS()))
+    getFunctionText: line => (0, _function.findFunctionText)(line, selectedSource.toJS(), (0, _selectors.getSymbols)(state, selectedSource.toJS())),
+    getFunctionLocation: line => (0, _astBreakpointLocation.findClosestScope)((0, _selectors.getSymbols)(state, selectedSource.toJS()).functions, {
+      line,
+      column: Infinity
+    })
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(EditorMenu);
 
 /***/ }),
 /* 1597 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -40990,16 +40795,20 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.findFunctionText = findFunctionText;
 
 var _astBreakpointLocation = __webpack_require__(1416);
 
 var _indentation = __webpack_require__(1438);
 
+/* 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/>. */
+
 function findFunctionText(line, source, symbols) {
   const func = (0, _astBreakpointLocation.findClosestScope)(symbols.functions, { line, column: Infinity });
   if (!func) {
     return null;
   }
 
   const { location: { start, end } } = func;
   const lines = source.text.split("\n");
@@ -41148,17 +40957,20 @@ class ConditionalPanel extends _react.Pu
     return panel;
   }
 
   render() {
     return null;
   }
 }
 
-exports.ConditionalPanel = ConditionalPanel;
+exports.ConditionalPanel = ConditionalPanel; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                              * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                              * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = (0, _reactRedux.connect)(state => {
   const line = (0, _selectors.getConditionalPanelLine)(state);
   const selectedLocation = (0, _selectors.getSelectedLocation)(state);
   return {
     selectedLocation,
     breakpoint: (0, _selectors.getBreakpointForLine)(state, selectedLocation.sourceId, line),
     line
   };
@@ -41248,16 +41060,20 @@ var _ChromeScopes2 = _interopRequireDefa
 var _Scopes2 = __webpack_require__(1611);
 
 var _Scopes3 = _interopRequireDefault(_Scopes2);
 
 __webpack_require__(1342);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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 Scopes = (0, _devtoolsConfig.isEnabled)("chromeScopes") ? _ChromeScopes2.default : _Scopes3.default;
 
 function debugBtn(onClick, type, className, tooltip) {
   return _react2.default.createElement(
     "button",
     {
       onClick: onClick,
       className: `${type} ${className}`,
@@ -41312,63 +41128,69 @@ class SecondaryPanes extends _react.Comp
     }, "refresh", "refresh", L10N.getStr("watchExpressions.refreshButton"))];
   }
 
   getScopeItem() {
     const isPaused = () => !!this.props.pauseData;
 
     return {
       header: L10N.getStr("scopes.header"),
+      className: "scopes-pane",
       component: Scopes,
       opened: _prefs.prefs.scopesVisible,
       onToggle: opened => {
         _prefs.prefs.scopesVisible = opened;
       },
       shouldOpen: isPaused
     };
   }
 
   getWatchItem() {
     return {
       header: L10N.getStr("watchExpressions.header"),
+      className: "watch-expressions-pane",
       buttons: this.watchExpressionHeaderButtons(),
       component: _Expressions2.default,
       opened: true
     };
   }
 
   getStartItems() {
     const scopesContent = this.props.horizontal ? this.getScopeItem() : null;
     const isPaused = () => !!this.props.pauseData;
 
     const items = [{
       header: L10N.getStr("breakpoints.header"),
+      className: "breakpoints-pane",
       buttons: this.renderBreakpointsToggle(),
       component: _Breakpoints2.default,
       opened: true
     }, {
       header: L10N.getStr("callStack.header"),
+      className: "call-stack-pane",
       component: _Frames2.default,
       opened: _prefs.prefs.callStackVisible,
       onToggle: opened => {
         _prefs.prefs.callStackVisible = opened;
       },
       shouldOpen: isPaused
     }, scopesContent];
 
     if ((0, _devtoolsConfig.isEnabled)("eventListeners")) {
       items.push({
         header: L10N.getStr("eventListenersHeader"),
+        className: "event-listeners-pane",
         component: _EventListeners2.default
       });
     }
 
     if ((0, _devtoolsConfig.isEnabled)("workers")) {
       items.push({
         header: L10N.getStr("workersHeader"),
+        className: "workers-pane",
         component: _Workers2.default
       });
     }
 
     if (this.props.horizontal) {
       items.unshift(this.getWatchItem());
     }
 
@@ -41462,16 +41284,20 @@ exports.default = (0, _reactRedux.connec
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; }; /* 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/>. */
+
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _immutable = __webpack_require__(146);
 
 var I = _interopRequireWildcard(_immutable);
 
@@ -41566,17 +41392,17 @@ class Breakpoints extends _react.PureCom
     const {
       removeBreakpoint,
       removeBreakpoints,
       removeAllBreakpoints,
       toggleBreakpoints,
       toggleAllBreakpoints,
       toggleDisabledBreakpoint,
       setBreakpointCondition,
-      toggleConditionalBreakpointPanel,
+      openConditionalPanel,
       breakpoints
     } = this.props;
 
     e.preventDefault();
 
     const deleteSelfLabel = L10N.getStr("breakpointMenuItem.deleteSelf2.label");
     const deleteAllLabel = L10N.getStr("breakpointMenuItem.deleteAll2.label");
     const deleteOthersLabel = L10N.getStr("breakpointMenuItem.deleteOthers2.label");
@@ -41689,27 +41515,27 @@ class Breakpoints extends _react.PureCom
     };
 
     const addCondition = {
       id: "node-menu-add-condition",
       label: addConditionLabel,
       accesskey: addConditionKey,
       click: () => {
         this.selectBreakpoint(breakpoint);
-        toggleConditionalBreakpointPanel(breakpoint.location.line);
+        openConditionalPanel(breakpoint.location.line);
       }
     };
 
     const editCondition = {
       id: "node-menu-edit-condition",
       label: editConditionLabel,
       accesskey: editConditionKey,
       click: () => {
         this.selectBreakpoint(breakpoint);
-        toggleConditionalBreakpointPanel(breakpoint.location.line);
+        openConditionalPanel(breakpoint.location.line);
       }
     };
 
     const hideEnableSelf = !breakpoint.disabled;
     const hideEnableAll = disabledBreakpoints.size === 0;
     const hideEnableOthers = otherDisabledBreakpoints.size === 0;
     const hideDisableAll = enabledBreakpoints.size === 0;
     const hideDisableOthers = otherEnabledBreakpoints.size === 0;
@@ -41734,29 +41560,25 @@ class Breakpoints extends _react.PureCom
       hidden: () => !breakpoint.condition
     }];
 
     (0, _devtoolsLaunchpad.showMenu)(e, (0, _devtoolsLaunchpad.buildMenu)(items));
   }
 
   selectBreakpoint(breakpoint) {
     const sourceId = breakpoint.location.sourceId;
-    const line = breakpoint.location.line;
-    this.props.selectSource(sourceId, { line });
+    const { location } = breakpoint;
+    this.props.selectSource(sourceId, { location });
   }
 
   removeBreakpoint(event, breakpoint) {
     event.stopPropagation();
     this.props.removeBreakpoint(breakpoint.location);
   }
 
-  toggleConditionalBreakpointPanel(line) {
-    this.props.toggleConditionalBreakpointPanel(line);
-  }
-
   renderBreakpoint(breakpoint) {
     const snippet = breakpoint.text || "";
     const locationId = breakpoint.locationId;
     const line = breakpoint.location.line;
     const column = breakpoint.location.column;
     const isCurrentlyPaused = breakpoint.isCurrentlyPaused;
     const isDisabled = breakpoint.disabled;
     const isConditional = !!breakpoint.condition;
@@ -41819,22 +41641,18 @@ class Breakpoints extends _react.PureCom
   }
 }
 
 function updateLocation(sources, pause, bp) {
   const source = (0, _selectors.getSourceInSources)(sources, bp.location.sourceId);
   const isCurrentlyPaused = isCurrentlyPausedAtBreakpoint(pause, bp);
   const locationId = (0, _breakpoint.makeLocationId)(bp.location);
 
-  const location = Object.assign({}, bp.location, { source });
-  const localBP = Object.assign({}, bp, {
-    location,
-    locationId,
-    isCurrentlyPaused
-  });
+  const location = _extends({}, bp.location, { source });
+  const localBP = _extends({}, bp, { location, locationId, isCurrentlyPaused });
 
   return localBP;
 }
 
 const _getBreakpoints = (0, _reselect.createSelector)(_selectors.getBreakpoints, _selectors.getSources, _selectors.getPause, (breakpoints, sources, pause) => breakpoints.map(bp => updateLocation(sources, pause, bp)).filter(bp => bp.location.source && !bp.location.source.get("isBlackBoxed")));
 
 exports.default = (0, _reactRedux.connect)((state, props) => ({ breakpoints: _getBreakpoints(state) }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Breakpoints);
 
@@ -42034,33 +41852,41 @@ class Expressions extends _react.PureCom
     const { expressions } = this.props;
     return _react2.default.createElement(
       "ul",
       { className: "pane expressions-list" },
       expressions.map(this.renderExpression),
       this.renderNewExpressionInput()
     );
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = (0, _reactRedux.connect)(state => ({
   pauseInfo: (0, _selectors.getPause)(state),
   expressions: (0, _selectors.getExpressions)(state),
   loadedObjects: (0, _selectors.getLoadedObjects)(state)
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Expressions);
 
 /***/ }),
 /* 1602 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.getAndProcessFrames = getAndProcessFrames;
 
 var _propTypes = __webpack_require__(20);
 
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
@@ -42240,19 +42066,17 @@ Frames.propTypes = {
   pause: _propTypes2.default.object
 };
 
 function getSourceForFrame(sources, frame) {
   return (0, _selectors.getSourceInSources)(sources, frame.location.sourceId);
 }
 
 function appendSource(sources, frame) {
-  return Object.assign({}, frame, {
-    source: getSourceForFrame(sources, frame).toJS()
-  });
+  return _extends({}, frame, { source: getSourceForFrame(sources, frame).toJS() });
 }
 
 function getAndProcessFrames(frames, sources) {
   if (!frames) {
     return null;
   }
 
   const processedFrames = frames.filter(frame => getSourceForFrame(sources, frame)).map(frame => appendSource(sources, frame)).filter(frame => !(0, _lodash.get)(frame, "source.isBlackBoxed")).map(_frame.annotateFrame);
@@ -42313,18 +42137,19 @@ function FrameLocation({ frame }) {
   }
 
   return _react2.default.createElement(
     "div",
     { className: "location" },
     library,
     _react2.default.createElement(_Svg2.default, { name: library.toLowerCase(), className: "annotation-logo" })
   );
-}
-
+} /* 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/>. */
 
 FrameLocation.displayName = "FrameLocation";
 
 class Group extends _react.Component {
 
   constructor(...args) {
     super(...args);
 
@@ -42446,18 +42271,19 @@ function renderExceptionSummary(exceptio
   if ((0, _lodash.isString)(exception)) {
     return exception;
   }
 
   const message = (0, _lodash.get)(exception, "preview.message");
   const name = (0, _lodash.get)(exception, "preview.name");
 
   return `${name}: ${message}`;
-}
-
+} /* 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/>. */
 
 function renderMessage(pauseInfo) {
   if (!pauseInfo) {
     return null;
   }
 
   const message = (0, _lodash.get)(pauseInfo, "why.message");
   if (message) {
@@ -42506,16 +42332,20 @@ renderWhyPaused.displayName = "whyPaused
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; }; /* 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/>. */
+
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _redux = __webpack_require__(3);
 
 var _reactRedux = __webpack_require__(1189);
 
@@ -42599,23 +42429,26 @@ class EventListeners extends _react.Comp
     const { listeners } = this.props;
     return _react2.default.createElement(
       "div",
       { className: "pane event-listeners" },
       listeners.map(this.renderListener)
     );
   }
 }
+
 exports.default = (0, _reactRedux.connect)(state => {
-  const listeners = (0, _selectors.getEventListeners)(state).map(l => Object.assign({}, l, {
-    breakpoint: (0, _selectors.getBreakpoint)(state, {
-      sourceId: l.sourceId,
-      line: l.line
-    })
-  }));
+  const listeners = (0, _selectors.getEventListeners)(state).map(l => {
+    return _extends({}, l, {
+      breakpoint: (0, _selectors.getBreakpoint)(state, {
+        sourceId: l.sourceId,
+        line: l.line
+      })
+    });
+  });
 
   return { listeners };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(EventListeners);
 
 /***/ }),
 /* 1606 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -42634,16 +42467,20 @@ var _react2 = _interopRequireDefault(_re
 __webpack_require__(1340);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _selectors = __webpack_require__(1352);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class Workers extends _react.PureComponent {
 
   renderWorkers(workers) {
     return workers.map(w => _react2.default.createElement(
       "div",
       { className: "worker", key: w.url },
       w.url
     ));
@@ -42697,21 +42534,20 @@ var _Svg2 = _interopRequireDefault(_Svg)
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class Accordion extends _react.Component {
   constructor(props) {
     super();
 
     this.renderContainer = (item, i) => {
       const { opened, created } = this.state;
-      const containerClassName = `${item.header.toLowerCase().replace(/\s/g, "-")}-pane`;
 
       return _react2.default.createElement(
         "div",
-        { className: containerClassName, key: i },
+        { className: item.className, key: i },
         _react2.default.createElement(
           "div",
           { className: "_header", onClick: () => this.handleHeaderClick(i) },
           _react2.default.createElement(_Svg2.default, { name: "arrow", className: opened[i] ? "expanded" : "" }),
           item.header,
           item.buttons ? _react2.default.createElement(
             "div",
             { className: "header-buttons" },
@@ -42766,31 +42602,36 @@ class Accordion extends _react.Component
 
   render() {
     return _react2.default.createElement(
       "div",
       { className: "accordion" },
       this.props.items.map(this.renderContainer)
     );
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
 exports.default = Accordion;
 
 /***/ }),
 /* 1608 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* 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/>. */
 
 var _propTypes = __webpack_require__(20);
 
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
@@ -42991,17 +42832,19 @@ exports.default = (0, _reactRedux.connec
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* 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/>. */
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
@@ -43085,18 +42928,19 @@ var _ManagedTree2 = _interopRequireDefau
 
 __webpack_require__(1296);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 // check to see if its an object with propertie
 function nodeHasProperties(item) {
   return !nodeHasChildren(item) && item.contents.value.type === "object";
-}
-
+} /* 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/>. */
 
 function nodeIsPrimitive(item) {}
 
 function nodeHasChildren(item) {
   return Array.isArray(item.contents);
 }
 
 function createNode(name, path, contents) {
@@ -43311,16 +43155,20 @@ var _selectors = __webpack_require__(135
 var _scopes = __webpack_require__(1612);
 
 var _devtoolsReps = __webpack_require__(1408);
 
 __webpack_require__(1296);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class Scopes extends _react.PureComponent {
   constructor(props, ...args) {
     const { pauseInfo, selectedFrame, frameScopes } = props;
 
     super(props, ...args);
 
     this.state = {
       scopes: (0, _scopes.getScopes)(pauseInfo, selectedFrame, frameScopes)
@@ -43345,16 +43193,17 @@ class Scopes extends _react.PureComponen
     const { scopes } = this.state;
 
     if (scopes) {
       return _react2.default.createElement(
         "div",
         { className: "pane scopes-list" },
         _react2.default.createElement(_devtoolsReps.ObjectInspector, {
           roots: scopes,
+          autoExpandAll: false,
           autoExpandDepth: 1,
           getObjectProperties: id => loadedObjects[id],
           loadObjectProperties: loadObjectProperties,
           disableWrap: true,
           disabledFocus: true,
           dimTopLevelWindow: true
           // TODO: See https://github.com/devtools-html/debugger.html/issues/3555.
           , getObjectEntries: actor => {},
@@ -43371,17 +43220,17 @@ class Scopes extends _react.PureComponen
         pauseInfo ? L10N.getStr("scopes.notAvailable") : L10N.getStr("scopes.notPaused")
       )
     );
   }
 }
 
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedFrame = (0, _selectors.getSelectedFrame)(state);
-  const frameScopes = selectedFrame ? (0, _selectors.getFrameScopes)(state, selectedFrame.id) : null;
+  const frameScopes = selectedFrame ? (0, _selectors.getFrameScope)(state, selectedFrame.id) : null;
   return {
     selectedFrame,
     pauseInfo: (0, _selectors.getPause)(state),
     frameScopes: frameScopes,
     loadedObjects: (0, _selectors.getLoadedObjects)(state)
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Scopes);
 
@@ -43390,17 +43239,22 @@ exports.default = (0, _reactRedux.connec
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getSpecialVariables = getSpecialVariables;
+
+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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+exports.getFramePopVariables = getFramePopVariables;
 exports.getScopes = getScopes;
 
 var _lodash = __webpack_require__(2);
 
 var _frame = __webpack_require__(1380);
 
 // Create the tree nodes representing all the variables and arguments
 // for the bindings from a scope.
@@ -43446,39 +43300,43 @@ function getSourceBindingVariables(bindi
       contents
     };
   });
   // Use rest of them (not found in the sourceBindings) as is.
   const unused = result.filter(entry => !index[entry.name].used);
   return bound.concat(unused);
 }
 
-function getSpecialVariables(pauseInfo, path) {
-  const thrown = (0, _lodash.get)(pauseInfo, "why.frameFinished.throw", undefined);
-
-  const returned = (0, _lodash.get)(pauseInfo, "why.frameFinished.return", undefined);
-
+function getFramePopVariables(pauseInfo, path) {
   const vars = [];
 
-  if (thrown !== undefined) {
-    vars.push({
-      name: "<exception>",
-      path: `${path}/<exception>`,
-      contents: { value: thrown }
-    });
-  }
-
-  if (returned !== undefined) {
-    // Do not display a return value of "undefined",
-    if (!returned || !returned.type || returned.type !== "undefined") {
+  if (pauseInfo.why && pauseInfo.why.frameFinished) {
+    const frameFinished = pauseInfo.why.frameFinished;
+
+    // Always display a `throw` property if present, even if it is falsy.
+    if (Object.prototype.hasOwnProperty.call(frameFinished, "throw")) {
       vars.push({
-        name: "<return>",
-        path: `${path}/<return>`,
-        contents: { value: returned }
-      });
+        name: "<exception>",
+        path: `${path}/<exception>`,
+        contents: { value: frameFinished.throw }
+      });
+    }
+
+    if (Object.prototype.hasOwnProperty.call(frameFinished, "return")) {
+      const returned = frameFinished.return;
+
+      // Do not display undefined. Do display falsy values like 0 and false. The
+      // protocol grip for undefined is a JSON object: { type: "undefined" }.
+      if (typeof returned !== "object" || returned.type !== "undefined") {
+        vars.push({
+          name: "<return>",
+          path: `${path}/<return>`,
+          contents: { value: returned }
+        });
+      }
     }
   }
 
   return vars;
 }
 
 function getThisVariable(frame, path) {
   const this_ = frame.this;
@@ -43505,17 +43363,16 @@ function getScopes(pauseInfo, selectedFr
 
   if (!selectedScope) {
     return null;
   }
 
   const scopes = [];
 
   let scope = selectedScope;
-  const pausedScopeActor = (0, _lodash.get)(pauseInfo, "frame.scope.actor");
   let scopeIndex = 1;
 
   do {
     const { type, actor } = scope;
     const key = `${actor}-${scopeIndex}`;
     if (type === "function" || type === "block") {
       const bindings = scope.bindings;
       const sourceBindings = scope.sourceBindings;
@@ -43523,19 +43380,20 @@ function getScopes(pauseInfo, selectedFr
       if (type === "function") {
         title = scope.function.displayName ? (0, _frame.simplifyDisplayName)(scope.function.displayName) : L10N.getStr("anonymous");
       } else {
         title = L10N.getStr("scopes.block");
       }
 
       let vars = sourceBindings ? getSourceBindingVariables(bindings, sourceBindings, key) : getBindingVariables(bindings, key);
 
-      // show exception, return, and this variables in innermost scope
-      if (scope.actor === pausedScopeActor) {
-        vars = vars.concat(getSpecialVariables(pauseInfo, key));
+      // On the innermost scope of a frame that is just about to be popped, show
+      // the return value or the exception being thrown as special variables.
+      if (scope.actor === selectedScope.actor && selectedFrame.id === pauseInfo.frame.id) {
+        vars = vars.concat(getFramePopVariables(pauseInfo, key));
       }
 
       if (scope.actor === selectedScope.actor) {
         const this_ = getThisVariable(selectedFrame, key);
 
         if (this_) {
           vars.push(this_);
         }
@@ -43549,17 +43407,17 @@ function getScopes(pauseInfo, selectedFr
           contents: vars
         });
       }
     } else if (type === "object") {
       let value = scope.object;
       // If this is the global window scope, mark it as such so that it will
       // preview Window: Global instead of Window: Window
       if (value.class === "Window") {
-        value = Object.assign({}, scope.object, { displayClass: "Global" });
+        value = _extends({}, scope.object, { displayClass: "Global" });
       }
       scopes.push({
         name: scope.object.class,
         path: key,
         contents: { value }
       });
     }
     scopeIndex++;
@@ -43598,16 +43456,20 @@ var _text = __webpack_require__(1387);
 var _PaneToggle = __webpack_require__(1407);
 
 var _PaneToggle2 = _interopRequireDefault(_PaneToggle);
 
 __webpack_require__(1343);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class WelcomeBox extends _react.Component {
   renderToggleButton() {
     const { horizontal, endPanelCollapsed, togglePaneCollapse } = this.props;
     if (horizontal) {
       return;
     }
 
     return _react2.default.createElement(_PaneToggle2.default, {
@@ -43786,17 +43648,19 @@ function getHiddenTabs(sourceTabs, sourc
     return element && hasTopOffset(element);
   });
 }
 
 /**
  * Clipboard function taken from
  * https://dxr.mozilla.org/mozilla-central/source/devtools/shared/platform/content/clipboard.js
  */
-
+/* 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/>. */
 
 function copyToTheClipboard(string) {
   const doCopy = function (e) {
     e.clipboardData.setData("text/plain", string);
     e.preventDefault();
   };
 
   document.addEventListener("copy", doCopy);
@@ -44177,16 +44041,20 @@ Object.defineProperty(exports, "__esModu
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 __webpack_require__(1345);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+/* 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/>. */
+
 class Dropdown extends _react.Component {
 
   constructor(props) {
     super(props);
     this.state = {
       dropdownShown: false
     };
 
@@ -44257,62 +44125,17 @@ exports.default = Dropdown;
 /* 1626 */,
 /* 1627 */,
 /* 1628 */,
 /* 1629 */,
 /* 1630 */,
 /* 1631 */,
 /* 1632 */,
 /* 1633 */,
-/* 1634 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.mapScopes = mapScopes;
-
-var _selectors = __webpack_require__(1352);
-
-var _pause = __webpack_require__(1400);
-
-var _devtoolsSourceMap = __webpack_require__(1360);
-
-function mapScopes() {
-  return async function ({ dispatch, getState, client, sourceMaps }) {
-    const frame = (0, _selectors.getSelectedFrame)(getState());
-    if (!frame) {
-      return;
-    }
-
-    if ((0, _devtoolsSourceMap.isGeneratedId)(frame.location.sourceId)) {
-      return;
-    }
-
-    const sourceRecord = (0, _selectors.getSource)(getState(), frame.generatedLocation.sourceId);
-
-    if (sourceRecord.get("isWasm")) {
-      return;
-    }
-
-    const frameScopes = await client.getFrameScopes(frame);
-    const scopes = await (0, _pause.updateScopeBindings)(frameScopes, frame.generatedLocation, sourceMaps);
-
-    dispatch({
-      type: "MAP_SCOPES",
-      frame,
-      scopes
-    });
-  };
-}
-
-/***/ }),
+/* 1634 */,
 /* 1635 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -44387,17 +44210,19 @@ function getQuickOpenType(state) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: 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; };
+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; }; /* This Source Code Form is subject to the terms of the Mozilla Public
+                                                                                                                                                                                                                                                                   * License, v. 2.0. If a copy of the MPL was not distributed with this
+                                                                                                                                                                                                                                                                   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 exports.parseQuickOpenQuery = parseQuickOpenQuery;
 exports.parseLineColumn = parseLineColumn;
 exports.formatSymbol = formatSymbol;
 exports.formatSymbols = formatSymbols;
 exports.formatSources = formatSources;
 
 var _utils = __webpack_require__(1366);
@@ -44437,17 +44262,17 @@ function parseLineColumn(query) {
     }, !isNaN(columnNumber) ? { column: columnNumber } : null);
   }
 }
 
 function formatSymbol(symbol) {
   return {
     id: `${symbol.name}:${symbol.location.start.line}`,
     title: symbol.name,
-    subtitle: `:${symbol.location.start.line}`,
+    subtitle: `${symbol.location.start.line}`,
     value: symbol.name,
     location: symbol.location
   };
 }
 
 function formatSymbols(symbols) {
   if (!symbols) {
     return { variables: [], functions: [] };
@@ -44486,48 +44311,51 @@ exports.stepOver = stepOver;
 exports.stepOut = stepOut;
 exports.resume = resume;
 exports.astCommand = astCommand;
 
 var _selectors = __webpack_require__(1352);
 
 var _pause = __webpack_require__(1400);
 
+var _promise = __webpack_require__(1653);
+
 var _parser = __webpack_require__(1365);
 
 var _breakpoints = __webpack_require__(1396);
 
 var _prefs = __webpack_require__(226);
 
 /**
  * Debugger commands like stepOver, stepIn, stepUp
  *
  * @param string $0.type
  * @memberof actions/pause
  * @static
  */
+/* 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/>. */
+
 function command(type) {
   return async ({ dispatch, client }) => {
-    // execute debugger thread command e.g. stepIn, stepOver
-    dispatch({ type: "COMMAND", value: { type } });
-
-    await client[type]();
-
-    dispatch({ type: "CLEAR_COMMAND" });
+    return dispatch({
+      type: "COMMAND",
+      command: type,
+      [_promise.PROMISE]: client[type]()
+    });
   };
 }
 
 /**
  * StepIn
  * @memberof actions/pause
  * @static
  * @returns {Function} {@link command}
  */
-
-
 function stepIn() {
   return ({ dispatch, getState }) => {
     if ((0, _selectors.getPause)(getState())) {
       return dispatch(command("stepIn"));
     }
   };
 }
 
@@ -44608,16 +44436,20 @@ function astCommand(stepType) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.findBestMatchExpression = findBestMatchExpression;
+/* 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/>. */
+
 function findBestMatchExpression(symbols, tokenPos, token) {
   const { memberExpressions, identifiers } = symbols;
   const { line, column } = tokenPos;
   return identifiers.concat(memberExpressions).reduce((found, expression) => {
     const overlaps = expression.location.start.line == line && expression.location.start.column <= column && expression.location.end.column >= column && !expression.computed;
 
     if (overlaps) {
       return expression;
@@ -44660,22 +44492,22 @@ Object.defineProperty(exports, "stepOut"
 });
 Object.defineProperty(exports, "resume", {
   enumerable: true,
   get: function () {
     return _commands.resume;
   }
 });
 
-var _mapScopes = __webpack_require__(1634);
-
-Object.defineProperty(exports, "mapScopes", {
+var _fetchScopes = __webpack_require__(1655);
+
+Object.defineProperty(exports, "fetchScopes", {
   enumerable: true,
   get: function () {
-    return _mapScopes.mapScopes;
+    return _fetchScopes.fetchScopes;
   }
 });
 
 var _paused = __webpack_require__(1640);
 
 Object.defineProperty(exports, "paused", {
   enumerable: true,
   get: function () {
@@ -44756,58 +44588,58 @@ var _pause = __webpack_require__(1400);
 var _breakpoints = __webpack_require__(1396);
 
 var _expressions = __webpack_require__(1398);
 
 var _sources = __webpack_require__(1373);
 
 var _ui = __webpack_require__(1385);
 
-var _mapScopes = __webpack_require__(1634);
+var _fetchScopes = __webpack_require__(1655);
 
 /**
  * Debugger has just paused
  *
  * @param {object} pauseInfo
  * @memberof actions/pause
  * @static
  */
 function paused(pauseInfo) {
   return async function ({ dispatch, getState, client, sourceMaps }) {
     const { frames, why, loadedObjects } = pauseInfo;
 
     const mappedFrames = await (0, _pause.updateFrameLocations)(frames, sourceMaps);
     const frame = mappedFrames[0];
-    const frameScopes = await client.getFrameScopes(frame);
 
     dispatch({
       type: "PAUSED",
       pauseInfo: { why, frame, frames },
       frames: mappedFrames,
-      scopes: frameScopes,
       selectedFrameId: frame.id,
       loadedObjects: loadedObjects || []
     });
 
     const hiddenBreakpointLocation = (0, _selectors.getHiddenBreakpointLocation)(getState());
     if (hiddenBreakpointLocation) {
       dispatch((0, _breakpoints.removeBreakpoint)(hiddenBreakpointLocation));
     }
 
     if (!(0, _selectors.isEvaluatingExpression)(getState())) {
       dispatch((0, _expressions.evaluateExpressions)());
     }
 
     const { line, column } = frame.location;
-    await dispatch((0, _sources.selectSource)(frame.location.sourceId, { line, column }));
+    await dispatch((0, _sources.selectSource)(frame.location.sourceId, { location: { line, column } }));
 
     dispatch((0, _ui.togglePaneCollapse)("end", false));
-    dispatch((0, _mapScopes.mapScopes)());
-  };
-}
+    dispatch((0, _fetchScopes.fetchScopes)());
+  };
+} /* 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/>. */
 
 /***/ }),
 /* 1641 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -44815,40 +44647,40 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.resumed = resumed;
 
 var _selectors = __webpack_require__(1352);
 
 var _expressions = __webpack_require__(1398);
 
+var _pause = __webpack_require__(1400);
+
 /**
  * Debugger has just resumed
  *
  * @memberof actions/pause
  * @static
  */
 function resumed() {
-  return ({ dispatch, client, getState }) => {
-    if (!(0, _selectors.isPaused)(getState())) {
-      return;
-    }
-
-    const wasPausedInEval = (0, _selectors.pausedInEval)(getState());
+  return async ({ dispatch, client, getState }) => {
+    const why = (0, _selectors.getPauseReason)(getState());
+    const wasPausedInEval = (0, _pause.inDebuggerEval)(why);
+
+    if (!(0, _selectors.isStepping)(getState()) && !wasPausedInEval) {
+      await dispatch((0, _expressions.evaluateExpressions)());
+    }
 
     dispatch({
-      type: "RESUME",
-      value: undefined
-    });
-
-    if (!(0, _selectors.isStepping)(getState()) && !wasPausedInEval) {
-      dispatch((0, _expressions.evaluateExpressions)());
-    }
-  };
-}
+      type: "RESUME"
+    });
+  };
+} /* 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/>. */
 
 /***/ }),
 /* 1642 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -44870,17 +44702,19 @@ function continueToHere(line) {
     await dispatch((0, _breakpoints.addHiddenBreakpoint)({
       line,
       column: undefined,
       sourceId: source.id
     }));
 
     dispatch((0, _commands.resume)());
   };
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1643 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -44902,38 +44736,44 @@ function breakOnNext() {
   return ({ dispatch, client }) => {
     client.breakOnNext();
 
     return dispatch({
       type: "BREAK_ON_NEXT",
       value: true
     });
   };
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1644 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.loadObjectProperties = loadObjectProperties;
 
-var _promise = __webpack_require__(1370);
+var _promise = __webpack_require__(1653);
 
 var _selectors = __webpack_require__(1352);
 
 /**
  * @memberof actions/pause
  * @static
  */
+/* 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/>. */
+
 function loadObjectProperties(object) {
   return ({ dispatch, client, getState }) => {
     const objectId = object.actor || object.objectId;
 
     if ((0, _selectors.getLoadedObject)(getState(), objectId)) {
       return;
     }
 
@@ -44952,33 +44792,35 @@ function loadObjectProperties(object) {
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.pauseOnExceptions = pauseOnExceptions;
 
-var _promise = __webpack_require__(1370);
+var _promise = __webpack_require__(1653);
 
 /**
  *
  * @memberof actions/pause
  * @static
  */
 function pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) {
   return ({ dispatch, client }) => {
     dispatch({
       type: "PAUSE_ON_EXCEPTIONS",
       shouldPauseOnExceptions,
       shouldIgnoreCaughtExceptions,
       [_promise.PROMISE]: client.pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions)
     });
   };
-}
+} /* 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/>. */
 
 /***/ }),
 /* 1646 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -44986,36 +44828,38 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.selectFrame = selectFrame;
 
 var _sources = __webpack_require__(1373);
 
 var _expressions = __webpack_require__(1398);
 
-var _mapScopes = __webpack_require__(1634);
+var _fetchScopes = __webpack_require__(1655);
 
 /**
  * @memberof actions/pause
  * @static
  */
 function selectFrame(frame) {
   return async ({ dispatch, client, getState, sourceMaps }) => {
     dispatch({
       type: "SELECT_FRAME",
       frame
     });
 
     const { line, column } = frame.location;
     dispatch((0, _sources.selectSource)(frame.location.sourceId, { line, column }));
 
     dispatch((0, _expressions.evaluateExpressions)());
-    dispatch((0, _mapScopes.mapScopes)());
-  };
-}
+    dispatch((0, _fetchScopes.fetchScopes)());
+  };
+} /* 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/>. */
 
 /***/ }),
 /* 1647 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -45025,17 +44869,20 @@ Object.defineProperty(exports, "__esModu
 exports.setQuickOpenQuery = setQuickOpenQuery;
 exports.openQuickOpen = openQuickOpen;
 exports.closeQuickOpen = closeQuickOpen;
 function setQuickOpenQuery(query) {
   return {
     type: "SET_QUICK_OPEN_QUERY",
     query
   };
-}
+} /* 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/>. */
+
 function openQuickOpen(query) {
   if (query != null) {
     return { type: "OPEN_QUICK_OPEN", query };
   }
   return { type: "OPEN_QUICK_OPEN" };
 }
 
 function closeQuickOpen() {
@@ -45073,17 +44920,19 @@ module.exports = "<svg xmlns=\"http://ww
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.QuickOpenModal = undefined;
 
-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; };
+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; }; /* 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/>. */
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _reactRedux = __webpack_require__(1189);
 
 var _redux = __webpack_require__(3);
@@ -45115,17 +44964,16 @@ var _ResultList2 = _interopRequireDefaul
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class QuickOpenModal extends _react.Component {
   constructor(props) {
     super(props);
 
     this.closeModal = () => {
       this.props.closeQuickOpen();
-      this.props.clearHighlightLineRange();
     };
 
     this.searchSources = query => {
       if (query == "") {
         const results = this.props.sources;
         this.setState({ results });
         return;
       }
@@ -45369,11 +45217,555 @@ function mapStateToProps(state) {
     symbols: (0, _quickOpen.formatSymbols)(symbols),
     query: (0, _selectors.getQuickOpenQuery)(state),
     searchType: (0, _selectors.getQuickOpenType)(state)
   };
 }
 
 exports.default = (0, _reactRedux.connect)(mapStateToProps, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(QuickOpenModal);
 
+/***/ }),
+/* 1653 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.promise = exports.PROMISE = undefined;
+
+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; }; /* 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/>. */
+
+var _lodash = __webpack_require__(2);
+
+var _DevToolsUtils = __webpack_require__(1432);
+
+let seqIdVal = 1;
+
+function seqIdGen() {
+  return seqIdVal++;
+}
+
+function filterAction(action) {
+  return (0, _lodash.fromPairs)((0, _lodash.toPairs)(action).filter(pair => pair[0] !== PROMISE));
+}
+
+function promiseMiddleware({
+  dispatch,
+  getState
+}) {
+  return next => action => {
+    if (!(PROMISE in action)) {
+      return next(action);
+    }
+
+    const promiseInst = action[PROMISE];
+    const seqId = seqIdGen().toString();
+
+    // Create a new action that doesn't have the promise field and has
+    // the `seqId` field that represents the sequence id
+    action = _extends({}, filterAction(action), { seqId });
+
+    dispatch(_extends({}, action, { status: "start" }));
+
+    // Return the promise so action creators can still compose if they
+    // want to.
+    return new Promise((resolve, reject) => {
+      promiseInst.then(value => {
+        (0, _DevToolsUtils.executeSoon)(() => {
+          dispatch(_extends({}, action, { status: "done", value: value }));
+          resolve(value);
+        });
+      }, error => {
+        (0, _DevToolsUtils.executeSoon)(() => {
+          dispatch(_extends({}, action, {
+            status: "error",
+            error: error.message || error
+          }));
+          reject(error);
+        });
+      });
+    });
+  };
+}
+
+const PROMISE = exports.PROMISE = "@@dispatch/promise";
+exports.promise = promiseMiddleware;
+
+/***/ }),
+/* 1654 */,
+/* 1655 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.fetchScopes = fetchScopes;
+
+var _selectors = __webpack_require__(1352);
+
+var _pause = __webpack_require__(1400);
+
+var _devtoolsSourceMap = __webpack_require__(1360);
+
+function fetchScopes() {
+  return async function ({ dispatch, getState, client, sourceMaps }) {
+    const frame = (0, _selectors.getSelectedFrame)(getState());
+
+    if (!frame || (0, _selectors.getFrameScope)(getState(), frame.id)) {
+      return;
+    }
+
+    const scopes = await client.getFrameScopes(frame);
+    dispatch({
+      type: "ADD_SCOPES",
+      frame,
+      scopes
+    });
+
+    const sourceRecord = (0, _selectors.getSource)(getState(), frame.generatedLocation.sourceId);
+
+    if (sourceRecord.get("isWasm")) {
+      return;
+    }
+
+    if ((0, _devtoolsSourceMap.isGeneratedId)(frame.location.sourceId)) {
+      return;
+    }
+
+    const mappedScopes = await (0, _pause.updateScopeBindings)(scopes, frame.generatedLocation, sourceMaps);
+
+    dispatch({
+      type: "MAP_SCOPES",
+      frame,
+      scopes: mappedScopes
+    });
+  };
+} /* 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/>. */
+
+/***/ }),
+/* 1656 */,
+/* 1657 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.getAsyncTimes = getAsyncTimes;
+exports.steppingTimings = steppingTimings;
+
+var _lodash = __webpack_require__(2);
+
+function getAsyncTimes(name) {
+  return (0, _lodash.zip)(window.performance.getEntriesByName(`${name}_start`), window.performance.getEntriesByName(`${name}_end`)).map(([start, end]) => +(end.startTime - start.startTime).toPrecision(2));
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.0. If a copy of the MPL was not distributed with this
+   * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+function getTimes(name) {
+  return window.performance.getEntriesByName(name).map(time => +time.duration.toPrecision(2));
+}
+
+function getStats(times) {
+  if (times.length == 0) {
+    return { times: [], avg: null, median: null };
+  }
+  const avg = times.reduce((sum, time) => time + sum, 0) / times.length;
+  const sortedtimings = [...times].sort((a, b) => a - b);
+  const median = sortedtimings[times.length / 2];
+  return {
+    times,
+    avg: +avg.toPrecision(2),
+    median: +median.toPrecision(2)
+  };
+}
+
+function steppingTimings() {
+  const commandTimings = getAsyncTimes("COMMAND");
+  const pausedTimings = getTimes("PAUSED");
+
+  return {
+    commands: getStats(commandTimings),
+    paused: getStats(pausedTimings)
+  };
+}
+
+// console.log("..", asyncTimes("COMMAND"));
+
+/***/ }),
+/* 1658 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _redux = __webpack_require__(3);
+
+var _waitService = __webpack_require__(1659);
+
+var _log = __webpack_require__(1660);
+
+var _history = __webpack_require__(1661);
+
+var _promise = __webpack_require__(1653);
+
+var _thunk = __webpack_require__(1662);
+
+var _timing = __webpack_require__(1663);
+
+/**
+ * This creates a dispatcher with all the standard middleware in place
+ * that all code requires. It can also be optionally configured in
+ * various ways, such as logging and recording.
+ *
+ * @param {object} opts:
+ *        - log: log all dispatched actions to console
+ *        - history: an array to store every action in. Should only be
+ *                   used in tests.
+ *        - middleware: array of middleware to be included in the redux store
+ * @memberof utils/create-store
+ * @static
+ */
+
+
+/**
+ * @memberof utils/create-store
+ * @static
+ */
+const configureStore = (opts = {}) => {
+  const middleware = [(0, _thunk.thunk)(opts.makeThunkArgs), _promise.promise,
+
+  // Order is important: services must go last as they always
+  // operate on "already transformed" actions. Actions going through
+  // them shouldn't have any special fields like promises, they
+  // should just be normal JSON objects.
+  _waitService.waitUntilService];
+
+  if (opts.history) {
+    middleware.push((0, _history.history)(opts.history));
+  }
+
+  if (opts.middleware) {
+    opts.middleware.forEach(fn => middleware.push(fn));
+  }
+
+  if (opts.log) {
+    middleware.push(_log.log);
+  }
+
+  if (opts.timing) {
+    middleware.push(_timing.timing);
+  }
+
+  // Hook in the redux devtools browser extension if it exists
+  const devtoolsExt = typeof window === "object" && window.devToolsExtension ? window.devToolsExtension() : f => f;
+
+  return (0, _redux.applyMiddleware)(...middleware)(devtoolsExt(_redux.createStore));
+}; /* 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/>. */
+
+/* global window */
+
+/**
+ * Redux store utils
+ * @module utils/create-store
+ */
+
+exports.default = configureStore;
+
+/***/ }),
+/* 1659 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.waitUntilService = waitUntilService;
+/* 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/>. */
+
+/* global window */
+
+/**
+ * A middleware which acts like a service, because it is stateful
+ * and "long-running" in the background. It provides the ability
+ * for actions to install a function to be run once when a specific
+ * condition is met by an action coming through the system. Think of
+ * it as a thunk that blocks until the condition is met. Example:
+ *
+ * ```js
+ * const services = { WAIT_UNTIL: require('wait-service').NAME };
+ *
+ * { type: services.WAIT_UNTIL,
+ *   predicate: action => action.type === "ADD_ITEM",
+ *   run: (dispatch, getState, action) => {
+ *     // Do anything here. You only need to accept the arguments
+ *     // if you need them. `action` is the action that satisfied
+ *     // the predicate.
+ *   }
+ * }
+ * ```
+ */
+const NAME = exports.NAME = "@@service/waitUntil";
+
+function waitUntilService({ dispatch, getState }) {
+  let pending = [];
+
+  function checkPending(action) {
+    const readyRequests = [];
+    const stillPending = [];
+
+    // Find the pending requests whose predicates are satisfied with
+    // this action. Wait to run the requests until after we update the
+    // pending queue because the request handler may synchronously
+    // dispatch again and run this service (that use case is
+    // completely valid).
+    for (const request of pending) {
+      if (request.predicate(action)) {
+        readyRequests.push(request);
+      } else {
+        stillPending.push(request);
+      }
+    }
+
+    pending = stillPending;
+    for (const request of readyRequests) {
+      request.run(dispatch, getState, action);
+    }
+  }
+
+  return next => action => {
+    if (action.type === NAME) {
+      pending.push(action);
+      return null;
+    }
+    const result = next(action);
+    checkPending(action);
+    return result;
+  };
+}
+
+/***/ }),
+/* 1660 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: 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; }; /* 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/. */
+/* global window */
+
+exports.log = log;
+
+var _devtoolsConfig = __webpack_require__(1355);
+
+const blacklist = ["LOAD_OBJECT_PROPERTIES", "SET_SYMBOLS", "OUT_OF_SCOPE_LOCATIONS"];
+
+function cloneAction(action) {
+  action = action || {};
+  action = _extends({}, action);
+
+  // ADD_TAB, ...
+  if (action.source && action.source.text) {
+    const source = _extends({}, action.source, { text: "" });
+    action.source = source;
+  }
+
+  // LOAD_SOURCE_TEXT
+  if (action.text) {
+    action.text = "";
+  }
+
+  if (action.value && action.value.text) {
+    const value = _extends({}, action.value, { text: "" });
+    action.value = value;
+  }
+
+  return action;
+}
+
+function formatFrame(frame) {
+  const { id, location, displayName } = frame;
+  return { id, location, displayName };
+}
+
+function formatPause(pause) {
+  return _extends({}, pause, {
+    pauseInfo: { why: pause.pauseInfo.why },
+    scopes: [],
+    frames: pause.frames.map(formatFrame),
+    loadedObjects: []
+  });
+}
+
+function serializeAction(action) {
+  try {
+    action = cloneAction(action);
+    if (blacklist.includes(action.type)) {
+      action = {};
+    }
+
+    if (action.type === "PAUSED") {
+      action = formatPause(action);
+    }
+
+    // dump(`> ${action.type}...\n ${JSON.stringify(action)}\n`);
+    return JSON.stringify(action);
+  } catch (e) {
+    console.error(e);
+  }
+}
+
+/**
+ * A middleware that logs all actions coming through the system
+ * to the console.
+ */
+function log({ dispatch, getState }) {
+  return next => action => {
+    const asyncMsg = !action.status ? "" : `[${action.status}]`;
+
+    if ((0, _devtoolsConfig.isTesting)()) {
+      dump(`[ACTION] ${action.type} ${asyncMsg} - ${serializeAction(action)}\n`);
+    } else {
+      console.log(action, asyncMsg);
+    }
+
+    next(action);
+  };
+}
+
+/***/ }),
+/* 1661 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.history = undefined;
+
+var _devtoolsConfig = __webpack_require__(1355);
+
+/**
+ * A middleware that stores every action coming through the store in the passed
+ * in logging object. Should only be used for tests, as it collects all
+ * action information, which will cause memory bloat.
+ */
+const history = exports.history = (log = []) => ({
+  dispatch,
+  getState
+}) => {
+  return next => action => {
+    if ((0, _devtoolsConfig.isDevelopment)()) {
+      log.push(action);
+    }
+
+    return next(action);
+  };
+}; /* 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/>. */
+
+/* global window */
+
+/***/ }),
+/* 1662 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.thunk = thunk;
+
+
+/**
+ * A middleware that allows thunks (functions) to be dispatched. If
+ * it's a thunk, it is called with an argument that contains
+ * `dispatch`, `getState`, and any additional args passed in via the
+ * middleware constructure. This allows the action to create multiple
+ * actions (most likely asynchronously).
+ */
+function thunk(makeArgs) {
+  return ({ dispatch, getState }) => {
+    const args = { dispatch, getState };
+
+    return next => action => {
+      return typeof action === "function" ? action(makeArgs ? makeArgs(args, getState()) : args) : next(action);
+    };
+  };
+} /* 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/>. */
+
+/* global window */
+
+/***/ }),
+/* 1663 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.timing = timing;
+/* 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/. */
+
+/* global window */
+
+/**
+ * Redux middleware that sets performance markers for all actions such that they
+ * will appear in performance tooling under the User Timing API
+ */
+
+const mark = window.performance && window.performance.mark ? window.performance.mark.bind(window.performance) : () => {};
+
+const measure = window.performance && window.performance.measure ? window.performance.measure.bind(window.performance) : () => {};
+
+function timing(store) {
+  return next => action => {
+    mark(`${action.type}_start`);
+    const result = next(action);
+    mark(`${action.type}_end`);
+    measure(`${action.type}`, `${action.type}_start`, `${action.type}_end`);
+    return result;
+  };
+}
+
 /***/ })
 /******/ ]);
-});
\ No newline at end of file
+});
+//# sourceMappingURL=debugger.js.map
\ No newline at end of file
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -3028,17 +3028,77 @@ module.exports = isArrayLike;
 /* 254 */,
 /* 255 */,
 /* 256 */,
 /* 257 */,
 /* 258 */,
 /* 259 */,
 /* 260 */,
 /* 261 */,
-/* 262 */,
+/* 262 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var baseFindIndex = __webpack_require__(263),
+    baseIteratee = __webpack_require__(814),
+    toInteger = __webpack_require__(302);
+
+/* Built-in method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * This method is like `_.find` except that it returns the index of the first
+ * element `predicate` returns truthy for instead of the element itself.
+ *
+ * @static
+ * @memberOf _
+ * @since 1.1.0
+ * @category Array
+ * @param {Array} array The array to inspect.
+ * @param {Function} [predicate=_.identity] The function invoked per iteration.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the found element, else `-1`.
+ * @example
+ *
+ * var users = [
+ *   { 'user': 'barney',  'active': false },
+ *   { 'user': 'fred',    'active': false },
+ *   { 'user': 'pebbles', 'active': true }
+ * ];
+ *
+ * _.findIndex(users, function(o) { return o.user == 'barney'; });
+ * // => 0
+ *
+ * // The `_.matches` iteratee shorthand.
+ * _.findIndex(users, { 'user': 'fred', 'active': false });
+ * // => 1
+ *
+ * // The `_.matchesProperty` iteratee shorthand.
+ * _.findIndex(users, ['active', false]);
+ * // => 0
+ *
+ * // The `_.property` iteratee shorthand.
+ * _.findIndex(users, 'active');
+ * // => 2
+ */
+function findIndex(array, predicate, fromIndex) {
+  var length = array == null ? 0 : array.length;
+  if (!length) {
+    return -1;
+  }
+  var index = fromIndex == null ? 0 : toInteger(fromIndex);
+  if (index < 0) {
+    index = nativeMax(length + index, 0);
+  }
+  return baseFindIndex(array, baseIteratee(predicate, 3), index);
+}
+
+module.exports = findIndex;
+
+
+/***/ }),
 /* 263 */
 /***/ (function(module, exports) {
 
 /**
  * The base implementation of `_.findIndex` and `_.findLastIndex` without
  * support for iteratee shorthands.
  *
  * @private
@@ -3940,18 +4000,69 @@ module.exports = function (index, length
 /* 387 */,
 /* 388 */,
 /* 389 */,
 /* 390 */,
 /* 391 */,
 /* 392 */,
 /* 393 */,
 /* 394 */,
-/* 395 */,
-/* 396 */,
+/* 395 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var createBaseFor = __webpack_require__(396);
+
+/**
+ * The base implementation of `baseForOwn` which iterates over `object`
+ * properties returned by `keysFunc` and invokes `iteratee` for each property.
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+var baseFor = createBaseFor();
+
+module.exports = baseFor;
+
+
+/***/ }),
+/* 396 */
+/***/ (function(module, exports) {
+
+/**
+ * Creates a base function for methods like `_.forIn` and `_.forOwn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseFor(fromRight) {
+  return function(object, iteratee, keysFunc) {
+    var index = -1,
+        iterable = Object(object),
+        props = keysFunc(object),
+        length = props.length;
+
+    while (length--) {
+      var key = props[fromRight ? length : ++index];
+      if (iteratee(iterable[key], key, iterable) === false) {
+        break;
+      }
+    }
+    return object;
+  };
+}
+
+module.exports = createBaseFor;
+
+
+/***/ }),
 /* 397 */,
 /* 398 */
 /***/ (function(module, exports, __webpack_require__) {
 
 /* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(8);
 
 /** Detect free variable `exports`. */
 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
@@ -27246,17 +27357,38 @@ module.exports = isFlattenable;
 /* 756 */,
 /* 757 */,
 /* 758 */,
 /* 759 */,
 /* 760 */,
 /* 761 */,
 /* 762 */,
 /* 763 */,
-/* 764 */,
+/* 764 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var baseFor = __webpack_require__(395),
+    keys = __webpack_require__(205);
+
+/**
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+function baseForOwn(object, iteratee) {
+  return object && baseFor(object, iteratee, keys);
+}
+
+module.exports = baseForOwn;
+
+
+/***/ }),
 /* 765 */,
 /* 766 */,
 /* 767 */,
 /* 768 */,
 /* 769 */,
 /* 770 */,
 /* 771 */,
 /* 772 */,
@@ -27668,27 +27800,3050 @@ function baseIteratee(value) {
   }
   return property(value);
 }
 
 module.exports = baseIteratee;
 
 
 /***/ }),
-/* 815 */,
-/* 816 */,
-/* 817 */,
-/* 818 */,
-/* 819 */,
-/* 820 */,
-/* 821 */,
-/* 822 */,
-/* 823 */,
-/* 824 */,
-/* 825 */,
+/* 815 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/*
+ * Copyright 2009-2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE.txt or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+exports.SourceMapGenerator = __webpack_require__(816).SourceMapGenerator;
+exports.SourceMapConsumer = __webpack_require__(822).SourceMapConsumer;
+exports.SourceNode = __webpack_require__(825).SourceNode;
+
+
+/***/ }),
+/* 816 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+
+var base64VLQ = __webpack_require__(817);
+var util = __webpack_require__(819);
+var ArraySet = __webpack_require__(820).ArraySet;
+var MappingList = __webpack_require__(821).MappingList;
+
+/**
+ * An instance of the SourceMapGenerator represents a source map which is
+ * being built incrementally. You may pass an object with the following
+ * properties:
+ *
+ *   - file: The filename of the generated source.
+ *   - sourceRoot: A root for all relative URLs in this source map.
+ */
+function SourceMapGenerator(aArgs) {
+  if (!aArgs) {
+    aArgs = {};
+  }
+  this._file = util.getArg(aArgs, 'file', null);
+  this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
+  this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
+  this._sources = new ArraySet();
+  this._names = new ArraySet();
+  this._mappings = new MappingList();
+  this._sourcesContents = null;
+}
+
+SourceMapGenerator.prototype._version = 3;
+
+/**
+ * Creates a new SourceMapGenerator based on a SourceMapConsumer
+ *
+ * @param aSourceMapConsumer The SourceMap.
+ */
+SourceMapGenerator.fromSourceMap =
+  function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
+    var sourceRoot = aSourceMapConsumer.sourceRoot;
+    var generator = new SourceMapGenerator({
+      file: aSourceMapConsumer.file,
+      sourceRoot: sourceRoot
+    });
+    aSourceMapConsumer.eachMapping(function (mapping) {
+      var newMapping = {
+        generated: {
+          line: mapping.generatedLine,
+          column: mapping.generatedColumn
+        }
+      };
+
+      if (mapping.source != null) {
+        newMapping.source = mapping.source;
+        if (sourceRoot != null) {
+          newMapping.source = util.relative(sourceRoot, newMapping.source);
+        }
+
+        newMapping.original = {
+          line: mapping.originalLine,
+          column: mapping.originalColumn
+        };
+
+        if (mapping.name != null) {
+          newMapping.name = mapping.name;
+        }
+      }
+
+      generator.addMapping(newMapping);
+    });
+    aSourceMapConsumer.sources.forEach(function (sourceFile) {
+      var content = aSourceMapConsumer.sourceContentFor(sourceFile);
+      if (content != null) {
+        generator.setSourceContent(sourceFile, content);
+      }
+    });
+    return generator;
+  };
+
+/**
+ * Add a single mapping from original source line and column to the generated
+ * source's line and column for this source map being created. The mapping
+ * object should have the following properties:
+ *
+ *   - generated: An object with the generated line and column positions.
+ *   - original: An object with the original line and column positions.
+ *   - source: The original source file (relative to the sourceRoot).
+ *   - name: An optional original token name for this mapping.
+ */
+SourceMapGenerator.prototype.addMapping =
+  function SourceMapGenerator_addMapping(aArgs) {
+    var generated = util.getArg(aArgs, 'generated');
+    var original = util.getArg(aArgs, 'original', null);
+    var source = util.getArg(aArgs, 'source', null);
+    var name = util.getArg(aArgs, 'name', null);
+
+    if (!this._skipValidation) {
+      this._validateMapping(generated, original, source, name);
+    }
+
+    if (source != null) {
+      source = String(source);
+      if (!this._sources.has(source)) {
+        this._sources.add(source);
+      }
+    }
+
+    if (name != null) {
+      name = String(name);
+      if (!this._names.has(name)) {
+        this._names.add(name);
+      }
+    }
+
+    this._mappings.add({
+      generatedLine: generated.line,
+      generatedColumn: generated.column,
+      originalLine: original != null && original.line,
+      originalColumn: original != null && original.column,
+      source: source,
+      name: name
+    });
+  };
+
+/**
+ * Set the source content for a source file.
+ */
+SourceMapGenerator.prototype.setSourceContent =
+  function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
+    var source = aSourceFile;
+    if (this._sourceRoot != null) {
+      source = util.relative(this._sourceRoot, source);
+    }
+
+    if (aSourceContent != null) {
+      // Add the source content to the _sourcesContents map.
+      // Create a new _sourcesContents map if the property is null.
+      if (!this._sourcesContents) {
+        this._sourcesContents = Object.create(null);
+      }
+      this._sourcesContents[util.toSetString(source)] = aSourceContent;
+    } else if (this._sourcesContents) {
+      // Remove the source file from the _sourcesContents map.
+      // If the _sourcesContents map is empty, set the property to null.
+      delete this._sourcesContents[util.toSetString(source)];
+      if (Object.keys(this._sourcesContents).length === 0) {
+        this._sourcesContents = null;
+      }
+    }
+  };
+
+/**
+ * Applies the mappings of a sub-source-map for a specific source file to the
+ * source map being generated. Each mapping to the supplied source file is
+ * rewritten using the supplied source map. Note: The resolution for the
+ * resulting mappings is the minimium of this map and the supplied map.
+ *
+ * @param aSourceMapConsumer The source map to be applied.
+ * @param aSourceFile Optional. The filename of the source file.
+ *        If omitted, SourceMapConsumer's file property will be used.
+ * @param aSourceMapPath Optional. The dirname of the path to the source map
+ *        to be applied. If relative, it is relative to the SourceMapConsumer.
+ *        This parameter is needed when the two source maps aren't in the same
+ *        directory, and the source map to be applied contains relative source
+ *        paths. If so, those relative source paths need to be rewritten
+ *        relative to the SourceMapGenerator.
+ */
+SourceMapGenerator.prototype.applySourceMap =
+  function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
+    var sourceFile = aSourceFile;
+    // If aSourceFile is omitted, we will use the file property of the SourceMap
+    if (aSourceFile == null) {
+      if (aSourceMapConsumer.file == null) {
+        throw new Error(
+          'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
+          'or the source map\'s "file" property. Both were omitted.'
+        );
+      }
+      sourceFile = aSourceMapConsumer.file;
+    }
+    var sourceRoot = this._sourceRoot;
+    // Make "sourceFile" relative if an absolute Url is passed.
+    if (sourceRoot != null) {
+      sourceFile = util.relative(sourceRoot, sourceFile);
+    }
+    // Applying the SourceMap can add and remove items from the sources and
+    // the names array.
+    var newSources = new ArraySet();
+    var newNames = new ArraySet();
+
+    // Find mappings for the "sourceFile"
+    this._mappings.unsortedForEach(function (mapping) {
+      if (mapping.source === sourceFile && mapping.originalLine != null) {
+        // Check if it can be mapped by the source map, then update the mapping.
+        var original = aSourceMapConsumer.originalPositionFor({
+          line: mapping.originalLine,
+          column: mapping.originalColumn
+        });
+        if (original.source != null) {
+          // Copy mapping
+          mapping.source = original.source;
+          if (aSourceMapPath != null) {
+            mapping.source = util.join(aSourceMapPath, mapping.source)
+          }
+          if (sourceRoot != null) {
+            mapping.source = util.relative(sourceRoot, mapping.source);
+          }
+          mapping.originalLine = original.line;
+          mapping.originalColumn = original.column;
+          if (original.name != null) {
+            mapping.name = original.name;
+          }
+        }
+      }
+
+      var source = mapping.source;
+      if (source != null && !newSources.has(source)) {
+        newSources.add(source);
+      }
+
+      var name = mapping.name;
+      if (name != null && !newNames.has(name)) {
+        newNames.add(name);
+      }
+
+    }, this);
+    this._sources = newSources;
+    this._names = newNames;
+
+    // Copy sourcesContents of applied map.
+    aSourceMapConsumer.sources.forEach(function (sourceFile) {
+      var content = aSourceMapConsumer.sourceContentFor(sourceFile);
+      if (content != null) {
+        if (aSourceMapPath != null) {
+          sourceFile = util.join(aSourceMapPath, sourceFile);
+        }
+        if (sourceRoot != null) {
+          sourceFile = util.relative(sourceRoot, sourceFile);
+        }
+        this.setSourceContent(sourceFile, content);
+      }
+    }, this);
+  };
+
+/**
+ * A mapping can have one of the three levels of data:
+ *
+ *   1. Just the generated position.
+ *   2. The Generated position, original position, and original source.
+ *   3. Generated and original position, original source, as well as a name
+ *      token.
+ *
+ * To maintain consistency, we validate that any new mapping being added falls
+ * in to one of these categories.
+ */
+SourceMapGenerator.prototype._validateMapping =
+  function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
+                                              aName) {
+    // When aOriginal is truthy but has empty values for .line and .column,
+    // it is most likely a programmer error. In this case we throw a very
+    // specific error message to try to guide them the right way.
+    // For example: https://github.com/Polymer/polymer-bundler/pull/519
+    if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+        throw new Error(
+            'original.line and original.column are not numbers -- you probably meant to omit ' +
+            'the original mapping entirely and only map the generated position. If so, pass ' +
+            'null for the original mapping instead of an object with empty or null values.'
+        );
+    }
+
+    if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
+        && aGenerated.line > 0 && aGenerated.column >= 0
+        && !aOriginal && !aSource && !aName) {
+      // Case 1.
+      return;
+    }
+    else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
+             && aOriginal && 'line' in aOriginal && 'column' in aOriginal
+             && aGenerated.line > 0 && aGenerated.column >= 0
+             && aOriginal.line > 0 && aOriginal.column >= 0
+             && aSource) {
+      // Cases 2 and 3.
+      return;
+    }
+    else {
+      throw new Error('Invalid mapping: ' + JSON.stringify({
+        generated: aGenerated,
+        source: aSource,
+        original: aOriginal,
+        name: aName
+      }));
+    }
+  };
+
+/**
+ * Serialize the accumulated mappings in to the stream of base 64 VLQs
+ * specified by the source map format.
+ */
+SourceMapGenerator.prototype._serializeMappings =
+  function SourceMapGenerator_serializeMappings() {
+    var previousGeneratedColumn = 0;
+    var previousGeneratedLine = 1;
+    var previousOriginalColumn = 0;
+    var previousOriginalLine = 0;
+    var previousName = 0;
+    var previousSource = 0;
+    var result = '';
+    var next;
+    var mapping;
+    var nameIdx;
+    var sourceIdx;
+
+    var mappings = this._mappings.toArray();
+    for (var i = 0, len = mappings.length; i < len; i++) {
+      mapping = mappings[i];
+      next = ''
+
+      if (mapping.generatedLine !== previousGeneratedLine) {
+        previousGeneratedColumn = 0;
+        while (mapping.generatedLine !== previousGeneratedLine) {
+          next += ';';
+          previousGeneratedLine++;
+        }
+      }
+      else {
+        if (i > 0) {
+          if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
+            continue;
+          }
+          next += ',';
+        }
+      }
+
+      next += base64VLQ.encode(mapping.generatedColumn
+                                 - previousGeneratedColumn);
+      previousGeneratedColumn = mapping.generatedColumn;
+
+      if (mapping.source != null) {
+        sourceIdx = this._sources.indexOf(mapping.source);
+        next += base64VLQ.encode(sourceIdx - previousSource);
+        previousSource = sourceIdx;
+
+        // lines are stored 0-based in SourceMap spec version 3
+        next += base64VLQ.encode(mapping.originalLine - 1
+                                   - previousOriginalLine);
+        previousOriginalLine = mapping.originalLine - 1;
+
+        next += base64VLQ.encode(mapping.originalColumn
+                                   - previousOriginalColumn);
+        previousOriginalColumn = mapping.originalColumn;
+
+        if (mapping.name != null) {
+          nameIdx = this._names.indexOf(mapping.name);
+          next += base64VLQ.encode(nameIdx - previousName);
+          previousName = nameIdx;
+        }
+      }
+
+      result += next;
+    }
+
+    return result;
+  };
+
+SourceMapGenerator.prototype._generateSourcesContent =
+  function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
+    return aSources.map(function (source) {
+      if (!this._sourcesContents) {
+        return null;
+      }
+      if (aSourceRoot != null) {
+        source = util.relative(aSourceRoot, source);
+      }
+      var key = util.toSetString(source);
+      return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
+        ? this._sourcesContents[key]
+        : null;
+    }, this);
+  };
+
+/**
+ * Externalize the source map.
+ */
+SourceMapGenerator.prototype.toJSON =
+  function SourceMapGenerator_toJSON() {
+    var map = {
+      version: this._version,
+      sources: this._sources.toArray(),
+      names: this._names.toArray(),
+      mappings: this._serializeMappings()
+    };
+    if (this._file != null) {
+      map.file = this._file;
+    }
+    if (this._sourceRoot != null) {
+      map.sourceRoot = this._sourceRoot;
+    }
+    if (this._sourcesContents) {
+      map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
+    }
+
+    return map;
+  };
+
+/**
+ * Render the source map being generated to a string.
+ */
+SourceMapGenerator.prototype.toString =
+  function SourceMapGenerator_toString() {
+    return JSON.stringify(this.toJSON());
+  };
+
+exports.SourceMapGenerator = SourceMapGenerator;
+
+
+/***/ }),
+/* 817 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ *
+ * Based on the Base 64 VLQ implementation in Closure Compiler:
+ * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
+ *
+ * Copyright 2011 The Closure Compiler Authors. All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of Google Inc. nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR 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.
+ */
+
+var base64 = __webpack_require__(818);
+
+// A single base 64 digit can contain 6 bits of data. For the base 64 variable
+// length quantities we use in the source map spec, the first bit is the sign,
+// the next four bits are the actual value, and the 6th bit is the
+// continuation bit. The continuation bit tells us whether there are more
+// digits in this value following this digit.
+//
+//   Continuation
+//   |    Sign
+//   |    |
+//   V    V
+//   101011
+
+var VLQ_BASE_SHIFT = 5;
+
+// binary: 100000
+var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
+
+// binary: 011111
+var VLQ_BASE_MASK = VLQ_BASE - 1;
+
+// binary: 100000
+var VLQ_CONTINUATION_BIT = VLQ_BASE;
+
+/**
+ * Converts from a two-complement value to a value where the sign bit is
+ * placed in the least significant bit.  For example, as decimals:
+ *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
+ *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
+ */
+function toVLQSigned(aValue) {
+  return aValue < 0
+    ? ((-aValue) << 1) + 1
+    : (aValue << 1) + 0;
+}
+
+/**
+ * Converts to a two-complement value from a value where the sign bit is
+ * placed in the least significant bit.  For example, as decimals:
+ *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
+ *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
+ */
+function fromVLQSigned(aValue) {
+  var isNegative = (aValue & 1) === 1;
+  var shifted = aValue >> 1;
+  return isNegative
+    ? -shifted
+    : shifted;
+}
+
+/**
+ * Returns the base 64 VLQ encoded value.
+ */
+exports.encode = function base64VLQ_encode(aValue) {
+  var encoded = "";
+  var digit;
+
+  var vlq = toVLQSigned(aValue);
+
+  do {
+    digit = vlq & VLQ_BASE_MASK;
+    vlq >>>= VLQ_BASE_SHIFT;
+    if (vlq > 0) {
+      // There are still more digits in this value, so we must make sure the
+      // continuation bit is marked.
+      digit |= VLQ_CONTINUATION_BIT;
+    }
+    encoded += base64.encode(digit);
+  } while (vlq > 0);
+
+  return encoded;
+};
+
+/**
+ * Decodes the next base 64 VLQ value from the given string and returns the
+ * value and the rest of the string via the out parameter.
+ */
+exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
+  var strLen = aStr.length;
+  var result = 0;
+  var shift = 0;
+  var continuation, digit;
+
+  do {
+    if (aIndex >= strLen) {
+      throw new Error("Expected more digits in base 64 VLQ value.");
+    }
+
+    digit = base64.decode(aStr.charCodeAt(aIndex++));
+    if (digit === -1) {
+      throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
+    }
+
+    continuation = !!(digit & VLQ_CONTINUATION_BIT);
+    digit &= VLQ_BASE_MASK;
+    result = result + (digit << shift);
+    shift += VLQ_BASE_SHIFT;
+  } while (continuation);
+
+  aOutParam.value = fromVLQSigned(result);
+  aOutParam.rest = aIndex;
+};
+
+
+/***/ }),
+/* 818 */
+/***/ (function(module, exports) {
+
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+
+var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
+
+/**
+ * Encode an integer in the range of 0 to 63 to a single base 64 digit.
+ */
+exports.encode = function (number) {
+  if (0 <= number && number < intToCharMap.length) {
+    return intToCharMap[number];
+  }
+  throw new TypeError("Must be between 0 and 63: " + number);
+};
+
+/**
+ * Decode a single base 64 character code digit to an integer. Returns -1 on
+ * failure.
+ */
+exports.decode = function (charCode) {
+  var bigA = 65;     // 'A'
+  var bigZ = 90;     // 'Z'
+
+  var littleA = 97;  // 'a'
+  var littleZ = 122; // 'z'
+
+  var zero = 48;     // '0'
+  var nine = 57;     // '9'
+
+  var plus = 43;     // '+'
+  var slash = 47;    // '/'
+
+  var littleOffset = 26;
+  var numberOffset = 52;
+
+  // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
+  if (bigA <= charCode && charCode <= bigZ) {
+    return (charCode - bigA);
+  }
+
+  // 26 - 51: abcdefghijklmnopqrstuvwxyz
+  if (littleA <= charCode && charCode <= littleZ) {
+    return (charCode - littleA + littleOffset);
+  }
+
+  // 52 - 61: 0123456789
+  if (zero <= charCode && charCode <= nine) {
+    return (charCode - zero + numberOffset);
+  }
+
+  // 62: +
+  if (charCode == plus) {
+    return 62;
+  }
+
+  // 63: /
+  if (charCode == slash) {
+    return 63;
+  }
+
+  // Invalid base64 digit.
+  return -1;
+};
+
+
+/***/ }),
+/* 819 */
+/***/ (function(module, exports) {
+
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+
+/**
+ * This is a helper function for getting values from parameter/options
+ * objects.
+ *
+ * @param args The object we are extracting values from
+ * @param name The name of the property we are getting.
+ * @param defaultValue An optional value to return if the property is missing
+ * from the object. If this is not specified and the property is missing, an
+ * error will be thrown.
+ */
+function getArg(aArgs, aName, aDefaultValue) {
+  if (aName in aArgs) {
+    return aArgs[aName];
+  } else if (arguments.length === 3) {
+    return aDefaultValue;
+  } else {
+    throw new Error('"' + aName + '" is a required argument.');
+  }
+}
+exports.getArg = getArg;
+
+var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+var dataUrlRegexp = /^data:.+\,.+$/;
+
+function urlParse(aUrl) {
+  var match = aUrl.match(urlRegexp);
+  if (!match) {
+    return null;
+  }
+  return {
+    scheme: match[1],
+    auth: match[2],
+    host: match[3],
+    port: match[4],
+    path: match[5]
+  };
+}
+exports.urlParse = urlParse;
+
+function urlGenerate(aParsedUrl) {
+  var url = '';
+  if (aParsedUrl.scheme) {
+    url += aParsedUrl.scheme + ':';
+  }
+  url += '//';
+  if (aParsedUrl.auth) {
+    url += aParsedUrl.auth + '@';
+  }
+  if (aParsedUrl.host) {
+    url += aParsedUrl.host;
+  }
+  if (aParsedUrl.port) {
+    url += ":" + aParsedUrl.port
+  }
+  if (aParsedUrl.path) {
+    url += aParsedUrl.path;
+  }
+  return url;
+}
+exports.urlGenerate = urlGenerate;
+
+/**
+ * Normalizes a path, or the path portion of a URL:
+ *
+ * - Replaces consecutive slashes with one slash.
+ * - Removes unnecessary '.' parts.
+ * - Removes unnecessary '<dir>/..' parts.
+ *
+ * Based on code in the Node.js 'path' core module.
+ *
+ * @param aPath The path or url to normalize.
+ */
+function normalize(aPath) {
+  var path = aPath;
+  var url = urlParse(aPath);
+  if (url) {
+    if (!url.path) {
+      return aPath;
+    }
+    path = url.path;
+  }
+  var isAbsolute = exports.isAbsolute(path);
+
+  var parts = path.split(/\/+/);
+  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
+    part = parts[i];
+    if (part === '.') {
+      parts.splice(i, 1);
+    } else if (part === '..') {
+      up++;
+    } else if (up > 0) {
+      if (part === '') {
+        // The first part is blank if the path is absolute. Trying to go
+        // above the root is a no-op. Therefore we can remove all '..' parts
+        // directly after the root.
+        parts.splice(i + 1, up);
+        up = 0;
+      } else {
+        parts.splice(i, 2);
+        up--;
+      }
+    }
+  }
+  path = parts.join('/');
+
+  if (path === '') {
+    path = isAbsolute ? '/' : '.';
+  }
+
+  if (url) {
+    url.path = path;
+    return urlGenerate(url);
+  }
+  return path;
+}
+exports.normalize = normalize;
+
+/**
+ * Joins two paths/URLs.
+ *
+ * @param aRoot The root path or URL.
+ * @param aPath The path or URL to be joined with the root.
+ *
+ * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
+ *   scheme-relative URL: Then the scheme of aRoot, if any, is prepended
+ *   first.
+ * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
+ *   is updated with the result and aRoot is returned. Otherwise the result
+ *   is returned.
+ *   - If aPath is absolute, the result is aPath.
+ *   - Otherwise the two paths are joined with a slash.
+ * - Joining for example 'http://' and 'www.example.com' is also supported.
+ */
+function join(aRoot, aPath) {
+  if (aRoot === "") {
+    aRoot = ".";
+  }
+  if (aPath === "") {
+    aPath = ".";
+  }
+  var aPathUrl = urlParse(aPath);
+  var aRootUrl = urlParse(aRoot);
+  if (aRootUrl) {
+    aRoot = aRootUrl.path || '/';
+  }
+
+  // `join(foo, '//www.example.org')`
+  if (aPathUrl && !aPathUrl.scheme) {
+    if (aRootUrl) {
+      aPathUrl.scheme = aRootUrl.scheme;
+    }
+    return urlGenerate(aPathUrl);
+  }
+
+  if (aPathUrl || aPath.match(dataUrlRegexp)) {
+    return aPath;
+  }
+
+  // `join('http://', 'www.example.com')`
+  if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
+    aRootUrl.host = aPath;
+    return urlGenerate(aRootUrl);
+  }
+
+  var joined = aPath.charAt(0) === '/'
+    ? aPath
+    : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
+
+  if (aRootUrl) {
+    aRootUrl.path = joined;
+    return urlGenerate(aRootUrl);
+  }
+  return joined;
+}
+exports.join = join;
+
+exports.isAbsolute = function (aPath) {
+  return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+};
+
+/**
+ * Make a path relative to a URL or another path.
+ *
+ * @param aRoot The root path or URL.
+ * @param aPath The path or URL to be made relative to aRoot.
+ */
+function relative(aRoot, aPath) {
+  if (aRoot === "") {
+    aRoot = ".";
+  }
+
+  aRoot = aRoot.replace(/\/$/, '');
+
+  // It is possible for the path to be above the root. In this case, simply
+  // checking whether the root is a prefix of the path won't work. Instead, we
+  // need to remove components from the root one by one, until either we find
+  // a prefix that fits, or we run out of components to remove.
+  var level = 0;
+  while (aPath.indexOf(aRoot + '/') !== 0) {
+    var index = aRoot.lastIndexOf("/");
+    if (index < 0) {
+      return aPath;
+    }
+
+    // If the only part of the root that is left is the scheme (i.e. http://,
+    // file:///, etc.), one or more slashes (/), or simply nothing at all, we
+    // have exhausted all components, so the path is not relative to the root.
+    aRoot = aRoot.slice(0, index);
+    if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
+      return aPath;
+    }
+
+    ++level;
+  }
+
+  // Make sure we add a "../" for each component we removed from the root.
+  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
+}
+exports.relative = relative;
+
+var supportsNullProto = (function () {
+  var obj = Object.create(null);
+  return !('__proto__' in obj);
+}());
+
+function identity (s) {
+  return s;
+}
+
+/**
+ * Because behavior goes wacky when you set `__proto__` on objects, we
+ * have to prefix all the strings in our set with an arbitrary character.
+ *
+ * See https://github.com/mozilla/source-map/pull/31 and
+ * https://github.com/mozilla/source-map/issues/30
+ *
+ * @param String aStr
+ */
+function toSetString(aStr) {
+  if (isProtoString(aStr)) {
+    return '$' + aStr;
+  }
+
+  return aStr;
+}
+exports.toSetString = supportsNullProto ? identity : toSetString;
+
+function fromSetString(aStr) {
+  if (isProtoString(aStr)) {
+    return aStr.slice(1);
+  }
+
+  return aStr;
+}
+exports.fromSetString = supportsNullProto ? identity : fromSetString;
+
+function isProtoString(s) {
+  if (!s) {
+    return false;
+  }
+
+  var length = s.length;
+
+  if (length < 9 /* "__proto__".length */) {
+    return false;
+  }
+
+  if (s.charCodeAt(length - 1) !== 95  /* '_' */ ||
+      s.charCodeAt(length - 2) !== 95  /* '_' */ ||
+      s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
+      s.charCodeAt(length - 4) !== 116 /* 't' */ ||
+      s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
+      s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
+      s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
+      s.charCodeAt(length - 8) !== 95  /* '_' */ ||
+      s.charCodeAt(length - 9) !== 95  /* '_' */) {
+    return false;
+  }
+
+  for (var i = length - 10; i >= 0; i--) {
+    if (s.charCodeAt(i) !== 36 /* '$' */) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+/**
+ * Comparator between two mappings where the original positions are compared.
+ *
+ * Optionally pass in `true` as `onlyCompareGenerated` to consider two
+ * mappings with the same original source/line/column, but different generated
+ * line and column the same. Useful when searching for a mapping with a
+ * stubbed out mapping.
+ */
+function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
+  var cmp = mappingA.source - mappingB.source;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.originalLine - mappingB.originalLine;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.originalColumn - mappingB.originalColumn;
+  if (cmp !== 0 || onlyCompareOriginal) {
+    return cmp;
+  }
+
+  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.generatedLine - mappingB.generatedLine;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  return mappingA.name - mappingB.name;
+}
+exports.compareByOriginalPositions = compareByOriginalPositions;
+
+/**
+ * Comparator between two mappings with deflated source and name indices where
+ * the generated positions are compared.
+ *
+ * Optionally pass in `true` as `onlyCompareGenerated` to consider two
+ * mappings with the same generated line and column, but different
+ * source/name/original line and column the same. Useful when searching for a
+ * mapping with a stubbed out mapping.
+ */
+function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
+  var cmp = mappingA.generatedLine - mappingB.generatedLine;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
+  if (cmp !== 0 || onlyCompareGenerated) {
+    return cmp;
+  }
+
+  cmp = mappingA.source - mappingB.source;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.originalLine - mappingB.originalLine;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.originalColumn - mappingB.originalColumn;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  return mappingA.name - mappingB.name;
+}
+exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
+
+function strcmp(aStr1, aStr2) {
+  if (aStr1 === aStr2) {
+    return 0;
+  }
+
+  if (aStr1 > aStr2) {
+    return 1;
+  }
+
+  return -1;
+}
+
+/**
+ * Comparator between two mappings with inflated source and name strings where
+ * the generated positions are compared.
+ */
+function compareByGeneratedPositionsInflated(mappingA, mappingB) {
+  var cmp = mappingA.generatedLine - mappingB.generatedLine;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = strcmp(mappingA.source, mappingB.source);
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.originalLine - mappingB.originalLine;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  cmp = mappingA.originalColumn - mappingB.originalColumn;
+  if (cmp !== 0) {
+    return cmp;
+  }
+
+  return strcmp(mappingA.name, mappingB.name);
+}
+exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+
+/***/ }),
+/* 820 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+
+var util = __webpack_require__(819);
+var has = Object.prototype.hasOwnProperty;
+var hasNativeMap = typeof Map !== "undefined";
+
+/**
+ * A data structure which is a combination of an array and a set. Adding a new
+ * member is O(1), testing for membership is O(1), and finding the index of an
+ * element is O(1). Removing elements from the set is not supported. Only
+ * strings are supported for membership.
+ */
+function ArraySet() {
+  this._array = [];
+  this._set = hasNativeMap ? new Map() : Object.create(null);
+}
+
+/**
+ * Static method for creating ArraySet instances from an existing array.
+ */
+ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
+  var set = new ArraySet();
+  for (var i = 0, len = aArray.length; i < len; i++) {
+    set.add(aArray[i], aAllowDuplicates);
+  }
+  return set;
+};
+
+/**
+ * Return how many unique items are in this ArraySet. If duplicates have been
+ * added, than those do not count towards the size.
+ *
+ * @returns Number
+ */
+ArraySet.prototype.size = function ArraySet_size() {
+  return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
+};
+
+/**
+ * Add the given string to this set.
+ *
+ * @param String aStr
+ */
+ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
+  var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+  var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
+  var idx = this._array.length;
+  if (!isDuplicate || aAllowDuplicates) {
+    this._array.push(aStr);
+  }
+  if (!isDuplicate) {
+    if (hasNativeMap) {
+      this._set.set(aStr, idx);
+    } else {
+      this._set[sStr] = idx;
+    }
+  }
+};
+
+/**
+ * Is the given string a member of this set?
+ *
+ * @param String aStr
+ */
+ArraySet.prototype.has = function ArraySet_has(aStr) {
+  if (hasNativeMap) {
+    return this._set.has(aStr);
+  } else {
+    var sStr = util.toSetString(aStr);
+    return has.call(this._set, sStr);
+  }
+};
+
+/**
+ * What is the index of the given string in the array?
+ *
+ * @param String aStr
+ */
+ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
+  if (hasNativeMap) {
+    var idx = this._set.get(aStr);
+    if (idx >= 0) {
+        return idx;
+    }
+  } else {
+    var sStr = util.toSetString(aStr);
+    if (has.call(this._set, sStr)) {
+      return this._set[sStr];
+    }
+  }
+
+  throw new Error('"' + aStr + '" is not in the set.');
+};
+
+/**
+ * What is the element at the given index?
+ *
+ * @param Number aIdx
+ */
+ArraySet.prototype.at = function ArraySet_at(aIdx) {
+  if (aIdx >= 0 && aIdx < this._array.length) {
+    return this._array[aIdx];
+  }
+  throw new Error('No element indexed by ' + aIdx);
+};
+
+/**
+ * Returns the array representation of this set (which has the proper indices
+ * indicated by indexOf). Note that this is a copy of the internal array used
+ * for storing the members so that no one can mess with internal state.
+ */
+ArraySet.prototype.toArray = function ArraySet_toArray() {
+  return this._array.slice();
+};
+
+exports.ArraySet = ArraySet;
+
+
+/***/ }),
+/* 821 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2014 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+
+var util = __webpack_require__(819);
+
+/**
+ * Determine whether mappingB is after mappingA with respect to generated
+ * position.
+ */
+function generatedPositionAfter(mappingA, mappingB) {
+  // Optimized for most common case
+  var lineA = mappingA.generatedLine;
+  var lineB = mappingB.generatedLine;
+  var columnA = mappingA.generatedColumn;
+  var columnB = mappingB.generatedColumn;
+  return lineB > lineA || lineB == lineA && columnB >= columnA ||
+         util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
+}
+
+/**
+ * A data structure to provide a sorted view of accumulated mappings in a
+ * performance conscious manner. It trades a neglibable overhead in general
+ * case for a large speedup in case of mappings being added in order.
+ */
+function MappingList() {
+  this._array = [];
+  this._sorted = true;
+  // Serves as infimum
+  this._last = {generatedLine: -1, generatedColumn: 0};
+}
+
+/**
+ * Iterate through internal items. This method takes the same arguments that
+ * `Array.prototype.forEach` takes.
+ *
+ * NOTE: The order of the mappings is NOT guaranteed.
+ */
+MappingList.prototype.unsortedForEach =
+  function MappingList_forEach(aCallback, aThisArg) {
+    this._array.forEach(aCallback, aThisArg);
+  };
+
+/**
+ * Add the given source mapping.
+ *
+ * @param Object aMapping
+ */
+MappingList.prototype.add = function MappingList_add(aMapping) {
+  if (generatedPositionAfter(this._last, aMapping)) {
+    this._last = aMapping;
+    this._array.push(aMapping);
+  } else {
+    this._sorted = false;
+    this._array.push(aMapping);
+  }
+};
+
+/**
+ * Returns the flat, sorted array of mappings. The mappings are sorted by
+ * generated position.
+ *
+ * WARNING: This method returns internal data without copying, for
+ * performance. The return value must NOT be mutated, and should be treated as
+ * an immutable borrow. If you want to take ownership, you must make your own
+ * copy.
+ */
+MappingList.prototype.toArray = function MappingList_toArray() {
+  if (!this._sorted) {
+    this._array.sort(util.compareByGeneratedPositionsInflated);
+    this._sorted = true;
+  }
+  return this._array;
+};
+
+exports.MappingList = MappingList;
+
+
+/***/ }),
+/* 822 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+
+var util = __webpack_require__(819);
+var binarySearch = __webpack_require__(823);
+var ArraySet = __webpack_require__(820).ArraySet;
+var base64VLQ = __webpack_require__(817);
+var quickSort = __webpack_require__(824).quickSort;
+
+function SourceMapConsumer(aSourceMap) {
+  var sourceMap = aSourceMap;
+  if (typeof aSourceMap === 'string') {
+    sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+  }
+
+  return sourceMap.sections != null
+    ? new IndexedSourceMapConsumer(sourceMap)
+    : new BasicSourceMapConsumer(sourceMap);
+}
+
+SourceMapConsumer.fromSourceMap = function(aSourceMap) {
+  return BasicSourceMapConsumer.fromSourceMap(aSourceMap);
+}
+
+/**
+ * The version of the source mapping spec that we are consuming.
+ */
+SourceMapConsumer.prototype._version = 3;
+
+// `__generatedMappings` and `__originalMappings` are arrays that hold the
+// parsed mapping coordinates from the source map's "mappings" attribute. They
+// are lazily instantiated, accessed via the `_generatedMappings` and
+// `_originalMappings` getters respectively, and we only parse the mappings
+// and create these arrays once queried for a source location. We jump through
+// these hoops because there can be many thousands of mappings, and parsing
+// them is expensive, so we only want to do it if we must.
+//
+// Each object in the arrays is of the form:
+//
+//     {
+//       generatedLine: The line number in the generated code,
+//       generatedColumn: The column number in the generated code,
+//       source: The path to the original source file that generated this
+//               chunk of code,
+//       originalLine: The line number in the original source that
+//                     corresponds to this chunk of generated code,
+//       originalColumn: The column number in the original source that
+//                       corresponds to this chunk of generated code,
+//       name: The name of the original symbol which generated this chunk of
+//             code.
+//     }
+//
+// All properties except for `generatedLine` and `generatedColumn` can be
+// `null`.
+//
+// `_generatedMappings` is ordered by the generated positions.
+//
+// `_originalMappings` is ordered by the original positions.
+
+SourceMapConsumer.prototype.__generatedMappings = null;
+Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+  get: function () {
+    if (!this.__generatedMappings) {
+      this._parseMappings(this._mappings, this.sourceRoot);
+    }
+
+    return this.__generatedMappings;
+  }
+});
+
+SourceMapConsumer.prototype.__originalMappings = null;
+Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+  get: function () {
+    if (!this.__originalMappings) {
+      this._parseMappings(this._mappings, this.sourceRoot);
+    }
+
+    return this.__originalMappings;
+  }
+});
+
+SourceMapConsumer.prototype._charIsMappingSeparator =
+  function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
+    var c = aStr.charAt(index);
+    return c === ";" || c === ",";
+  };
+
+/**
+ * Parse the mappings in a string in to a data structure which we can easily
+ * query (the ordered arrays in the `this.__generatedMappings` and
+ * `this.__originalMappings` properties).
+ */
+SourceMapConsumer.prototype._parseMappings =
+  function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
+    throw new Error("Subclasses must implement _parseMappings");
+  };
+
+SourceMapConsumer.GENERATED_ORDER = 1;
+SourceMapConsumer.ORIGINAL_ORDER = 2;
+
+SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
+SourceMapConsumer.LEAST_UPPER_BOUND = 2;
+
+/**
+ * Iterate over each mapping between an original source/line/column and a
+ * generated line/column in this source map.
+ *
+ * @param Function aCallback
+ *        The function that is called with each mapping.
+ * @param Object aContext
+ *        Optional. If specified, this object will be the value of `this` every
+ *        time that `aCallback` is called.
+ * @param aOrder
+ *        Either `SourceMapConsumer.GENERATED_ORDER` or
+ *        `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
+ *        iterate over the mappings sorted by the generated file's line/column
+ *        order or the original's source/line/column order, respectively. Defaults to
+ *        `SourceMapConsumer.GENERATED_ORDER`.
+ */
+SourceMapConsumer.prototype.eachMapping =
+  function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
+    var context = aContext || null;
+    var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
+
+    var mappings;
+    switch (order) {
+    case SourceMapConsumer.GENERATED_ORDER:
+      mappings = this._generatedMappings;
+      break;
+    case SourceMapConsumer.ORIGINAL_ORDER:
+      mappings = this._originalMappings;
+      break;
+    default:
+      throw new Error("Unknown order of iteration.");
+    }
+
+    var sourceRoot = this.sourceRoot;
+    mappings.map(function (mapping) {
+      var source = mapping.source === null ? null : this._sources.at(mapping.source);
+      if (source != null && sourceRoot != null) {
+        source = util.join(sourceRoot, source);
+      }
+      return {
+        source: source,
+        generatedLine: mapping.generatedLine,
+        generatedColumn: mapping.generatedColumn,
+        originalLine: mapping.originalLine,
+        originalColumn: mapping.originalColumn,
+        name: mapping.name === null ? null : this._names.at(mapping.name)
+      };
+    }, this).forEach(aCallback, context);
+  };
+
+/**
+ * Returns all generated line and column information for the original source,
+ * line, and column provided. If no column is provided, returns all mappings
+ * corresponding to a either the line we are searching for or the next
+ * closest line that has any mappings. Otherwise, returns all mappings
+ * corresponding to the given line and either the column we are searching for
+ * or the next closest column that has any offsets.
+ *
+ * The only argument is an object with the following properties:
+ *
+ *   - source: The filename of the original source.
+ *   - line: The line number in the original source.
+ *   - column: Optional. the column number in the original source.
+ *
+ * and an array of objects is returned, each with the following properties:
+ *
+ *   - line: The line number in the generated source, or null.
+ *   - column: The column number in the generated source, or null.
+ */
+SourceMapConsumer.prototype.allGeneratedPositionsFor =
+  function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
+    var line = util.getArg(aArgs, 'line');
+
+    // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
+    // returns the index of the closest mapping less than the needle. By
+    // setting needle.originalColumn to 0, we thus find the last mapping for
+    // the given line, provided such a mapping exists.
+    var needle = {
+      source: util.getArg(aArgs, 'source'),
+      originalLine: line,
+      originalColumn: util.getArg(aArgs, 'column', 0)
+    };
+
+    if (this.sourceRoot != null) {
+      needle.source = util.relative(this.sourceRoot, needle.source);
+    }
+    if (!this._sources.has(needle.source)) {
+      return [];
+    }
+    needle.source = this._sources.indexOf(needle.source);
+
+    var mappings = [];
+
+    var index = this._findMapping(needle,
+                                  this._originalMappings,
+                                  "originalLine",
+                                  "originalColumn",
+                                  util.compareByOriginalPositions,
+                                  binarySearch.LEAST_UPPER_BOUND);
+    if (index >= 0) {
+      var mapping = this._originalMappings[index];
+
+      if (aArgs.column === undefined) {
+        var originalLine = mapping.originalLine;
+
+        // Iterate until either we run out of mappings, or we run into
+        // a mapping for a different line than the one we found. Since
+        // mappings are sorted, this is guaranteed to find all mappings for
+        // the line we found.
+        while (mapping && mapping.originalLine === originalLine) {
+          mappings.push({
+            line: util.getArg(mapping, 'generatedLine', null),
+            column: util.getArg(mapping, 'generatedColumn', null),
+            lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
+          });
+
+          mapping = this._originalMappings[++index];
+        }
+      } else {
+        var originalColumn = mapping.originalColumn;
+
+        // Iterate until either we run out of mappings, or we run into
+        // a mapping for a different line than the one we were searching for.
+        // Since mappings are sorted, this is guaranteed to find all mappings for
+        // the line we are searching for.
+        while (mapping &&
+               mapping.originalLine === line &&
+               mapping.originalColumn == originalColumn) {
+          mappings.push({
+            line: util.getArg(mapping, 'generatedLine', null),
+            column: util.getArg(mapping, 'generatedColumn', null),
+            lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
+          });
+
+          mapping = this._originalMappings[++index];
+        }
+      }
+    }
+
+    return mappings;
+  };
+
+exports.SourceMapConsumer = SourceMapConsumer;
+
+/**
+ * A BasicSourceMapConsumer instance represents a parsed source map which we can
+ * query for information about the original file positions by giving it a file
+ * position in the generated source.
+ *
+ * The only parameter is the raw source map (either as a JSON string, or
+ * already parsed to an object). According to the spec, source maps have the
+ * following attributes:
+ *
+ *   - version: Which version of the source map spec this map is following.
+ *   - sources: An array of URLs to the original source files.
+ *   - names: An array of identifiers which can be referrenced by individual mappings.
+ *   - sourceRoot: Optional. The URL root from which all sources are relative.
+ *   - sourcesContent: Optional. An array of contents of the original source files.
+ *   - mappings: A string of base64 VLQs which contain the actual mappings.
+ *   - file: Optional. The generated file this source map is associated with.
+ *
+ * Here is an example source map, taken from the source map spec[0]:
+ *
+ *     {
+ *       version : 3,
+ *       file: "out.js",
+ *       sourceRoot : "",
+ *       sources: ["foo.js", "bar.js"],
+ *       names: ["src", "maps", "are", "fun"],
+ *       mappings: "AA,AB;;ABCDE;"
+ *     }
+ *
+ * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
+ */
+function BasicSourceMapConsumer(aSourceMap) {
+  var sourceMap = aSourceMap;
+  if (typeof aSourceMap === 'string') {
+    sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+  }
+
+  var version = util.getArg(sourceMap, 'version');
+  var sources = util.getArg(sourceMap, 'sources');
+  // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
+  // requires the array) to play nice here.
+  var names = util.getArg(sourceMap, 'names', []);
+  var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
+  var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
+  var mappings = util.getArg(sourceMap, 'mappings');
+  var file = util.getArg(sourceMap, 'file', null);
+
+  // Once again, Sass deviates from the spec and supplies the version as a
+  // string rather than a number, so we use loose equality checking here.
+  if (version != this._version) {
+    throw new Error('Unsupported version: ' + version);
+  }
+
+  sources = sources
+    .map(String)
+    // Some source maps produce relative source paths like "./foo.js" instead of
+    // "foo.js".  Normalize these first so that future comparisons will succeed.
+    // See bugzil.la/1090768.
+    .map(util.normalize)
+    // Always ensure that absolute sources are internally stored relative to
+    // the source root, if the source root is absolute. Not doing this would
+    // be particularly problematic when the source root is a prefix of the
+    // source (valid, but why??). See github issue #199 and bugzil.la/1188982.
+    .map(function (source) {
+      return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
+        ? util.relative(sourceRoot, source)
+        : source;
+    });
+
+  // Pass `true` below to allow duplicate names and sources. While source maps
+  // are intended to be compressed and deduplicated, the TypeScript compiler
+  // sometimes generates source maps with duplicates in them. See Github issue
+  // #72 and bugzil.la/889492.
+  this._names = ArraySet.fromArray(names.map(String), true);
+  this._sources = ArraySet.fromArray(sources, true);
+
+  this.sourceRoot = sourceRoot;
+  this.sourcesContent = sourcesContent;
+  this._mappings = mappings;
+  this.file = file;
+}
+
+BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
+BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
+
+/**
+ * Create a BasicSourceMapConsumer from a SourceMapGenerator.
+ *
+ * @param SourceMapGenerator aSourceMap
+ *        The source map that will be consumed.
+ * @returns BasicSourceMapConsumer
+ */
+BasicSourceMapConsumer.fromSourceMap =
+  function SourceMapConsumer_fromSourceMap(aSourceMap) {
+    var smc = Object.create(BasicSourceMapConsumer.prototype);
+
+    var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
+    var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
+    smc.sourceRoot = aSourceMap._sourceRoot;
+    smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
+                                                            smc.sourceRoot);
+    smc.file = aSourceMap._file;
+
+    // Because we are modifying the entries (by converting string sources and
+    // names to indices into the sources and names ArraySets), we have to make
+    // a copy of the entry or else bad things happen. Shared mutable state
+    // strikes again! See github issue #191.
+
+    var generatedMappings = aSourceMap._mappings.toArray().slice();
+    var destGeneratedMappings = smc.__generatedMappings = [];
+    var destOriginalMappings = smc.__originalMappings = [];
+
+    for (var i = 0, length = generatedMappings.length; i < length; i++) {
+      var srcMapping = generatedMappings[i];
+      var destMapping = new Mapping;
+      destMapping.generatedLine = srcMapping.generatedLine;
+      destMapping.generatedColumn = srcMapping.generatedColumn;
+
+      if (srcMapping.source) {
+        destMapping.source = sources.indexOf(srcMapping.source);
+        destMapping.originalLine = srcMapping.originalLine;
+        destMapping.originalColumn = srcMapping.originalColumn;
+
+        if (srcMapping.name) {
+          destMapping.name = names.indexOf(srcMapping.name);
+        }
+
+        destOriginalMappings.push(destMapping);
+      }
+
+      destGeneratedMappings.push(destMapping);
+    }
+
+    quickSort(smc.__originalMappings, util.compareByOriginalPositions);
+
+    return smc;
+  };
+
+/**
+ * The version of the source mapping spec that we are consuming.
+ */
+BasicSourceMapConsumer.prototype._version = 3;
+
+/**
+ * The list of original sources.
+ */
+Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
+  get: function () {
+    return this._sources.toArray().map(function (s) {
+      return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+    }, this);
+  }
+});
+
+/**
+ * Provide the JIT with a nice shape / hidden class.
+ */
+function Mapping() {
+  this.generatedLine = 0;
+  this.generatedColumn = 0;
+  this.source = null;
+  this.originalLine = null;
+  this.originalColumn = null;
+  this.name = null;
+}
+
+/**
+ * Parse the mappings in a string in to a data structure which we can easily
+ * query (the ordered arrays in the `this.__generatedMappings` and
+ * `this.__originalMappings` properties).
+ */
+BasicSourceMapConsumer.prototype._parseMappings =
+  function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
+    var generatedLine = 1;
+    var previousGeneratedColumn = 0;
+    var previousOriginalLine = 0;
+    var previousOriginalColumn = 0;
+    var previousSource = 0;
+    var previousName = 0;
+    var length = aStr.length;
+    var index = 0;
+    var cachedSegments = {};
+    var temp = {};
+    var originalMappings = [];
+    var generatedMappings = [];
+    var mapping, str, segment, end, value;
+
+    while (index < length) {
+      if (aStr.charAt(index) === ';') {
+        generatedLine++;
+        index++;
+        previousGeneratedColumn = 0;
+      }
+      else if (aStr.charAt(index) === ',') {
+        index++;
+      }
+      else {
+        mapping = new Mapping();
+        mapping.generatedLine = generatedLine;
+
+        // Because each offset is encoded relative to the previous one,
+        // many segments often have the same encoding. We can exploit this
+        // fact by caching the parsed variable length fields of each segment,
+        // allowing us to avoid a second parse if we encounter the same
+        // segment again.
+        for (end = index; end < length; end++) {
+          if (this._charIsMappingSeparator(aStr, end)) {
+            break;
+          }
+        }
+        str = aStr.slice(index, end);
+
+        segment = cachedSegments[str];
+        if (segment) {
+          index += str.length;
+        } else {
+          segment = [];
+          while (index < end) {
+            base64VLQ.decode(aStr, index, temp);
+            value = temp.value;
+            index = temp.rest;
+            segment.push(value);
+          }
+
+          if (segment.length === 2) {
+            throw new Error('Found a source, but no line and column');
+          }
+
+          if (segment.length === 3) {
+            throw new Error('Found a source and line, but no column');
+          }
+
+          cachedSegments[str] = segment;
+        }
+
+        // Generated column.
+        mapping.generatedColumn = previousGeneratedColumn + segment[0];
+        previousGeneratedColumn = mapping.generatedColumn;
+
+        if (segment.length > 1) {
+          // Original source.
+          mapping.source = previousSource + segment[1];
+          previousSource += segment[1];
+
+          // Original line.
+          mapping.originalLine = previousOriginalLine + segment[2];
+          previousOriginalLine = mapping.originalLine;
+          // Lines are stored 0-based
+          mapping.originalLine += 1;
+
+          // Original column.
+          mapping.originalColumn = previousOriginalColumn + segment[3];
+          previousOriginalColumn = mapping.originalColumn;
+
+          if (segment.length > 4) {
+            // Original name.
+            mapping.name = previousName + segment[4];
+            previousName += segment[4];
+          }
+        }
+
+        generatedMappings.push(mapping);
+        if (typeof mapping.originalLine === 'number') {
+          originalMappings.push(mapping);
+        }
+      }
+    }
+
+    quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
+    this.__generatedMappings = generatedMappings;
+
+    quickSort(originalMappings, util.compareByOriginalPositions);
+    this.__originalMappings = originalMappings;
+  };
+
+/**
+ * Find the mapping that best matches the hypothetical "needle" mapping that
+ * we are searching for in the given "haystack" of mappings.
+ */
+BasicSourceMapConsumer.prototype._findMapping =
+  function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
+                                         aColumnName, aComparator, aBias) {
+    // To return the position we are searching for, we must first find the
+    // mapping for the given position and then return the opposite position it
+    // points to. Because the mappings are sorted, we can use binary search to
+    // find the best mapping.
+
+    if (aNeedle[aLineName] <= 0) {
+      throw new TypeError('Line must be greater than or equal to 1, got '
+                          + aNeedle[aLineName]);
+    }
+    if (aNeedle[aColumnName] < 0) {
+      throw new TypeError('Column must be greater than or equal to 0, got '
+                          + aNeedle[aColumnName]);
+    }
+
+    return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
+  };
+
+/**
+ * Compute the last column for each generated mapping. The last column is
+ * inclusive.
+ */
+BasicSourceMapConsumer.prototype.computeColumnSpans =
+  function SourceMapConsumer_computeColumnSpans() {
+    for (var index = 0; index < this._generatedMappings.length; ++index) {
+      var mapping = this._generatedMappings[index];
+
+      // Mappings do not contain a field for the last generated columnt. We
+      // can come up with an optimistic estimate, however, by assuming that
+      // mappings are contiguous (i.e. given two consecutive mappings, the
+      // first mapping ends where the second one starts).
+      if (index + 1 < this._generatedMappings.length) {
+        var nextMapping = this._generatedMappings[index + 1];
+
+        if (mapping.generatedLine === nextMapping.generatedLine) {
+          mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
+          continue;
+        }
+      }
+
+      // The last mapping for each line spans the entire line.
+      mapping.lastGeneratedColumn = Infinity;
+    }
+  };
+
+/**
+ * Returns the original source, line, and column information for the generated
+ * source's line and column positions provided. The only argument is an object
+ * with the following properties:
+ *
+ *   - line: The line number in the generated source.
+ *   - column: The column number in the generated source.
+ *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
+ *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
+ *     closest element that is smaller than or greater than the one we are
+ *     searching for, respectively, if the exact element cannot be found.
+ *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
+ *
+ * and an object is returned with the following properties:
+ *
+ *   - source: The original source file, or null.
+ *   - line: The line number in the original source, or null.
+ *   - column: The column number in the original source, or null.
+ *   - name: The original identifier, or null.
+ */
+BasicSourceMapConsumer.prototype.originalPositionFor =
+  function SourceMapConsumer_originalPositionFor(aArgs) {
+    var needle = {
+      generatedLine: util.getArg(aArgs, 'line'),
+      generatedColumn: util.getArg(aArgs, 'column')
+    };
+
+    var index = this._findMapping(
+      needle,
+      this._generatedMappings,
+      "generatedLine",
+      "generatedColumn",
+      util.compareByGeneratedPositionsDeflated,
+      util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
+    );
+
+    if (index >= 0) {
+      var mapping = this._generatedMappings[index];
+
+      if (mapping.generatedLine === needle.generatedLine) {
+        var source = util.getArg(mapping, 'source', null);
+        if (source !== null) {
+          source = this._sources.at(source);
+          if (this.sourceRoot != null) {
+            source = util.join(this.sourceRoot, source);
+          }
+        }
+        var name = util.getArg(mapping, 'name', null);
+        if (name !== null) {
+          name = this._names.at(name);
+        }
+        return {
+          source: source,
+          line: util.getArg(mapping, 'originalLine', null),
+          column: util.getArg(mapping, 'originalColumn', null),
+          name: name
+        };
+      }
+    }
+
+    return {
+      source: null,
+      line: null,
+      column: null,
+      name: null
+    };
+  };
+
+/**
+ * Return true if we have the source content for every source in the source
+ * map, false otherwise.
+ */
+BasicSourceMapConsumer.prototype.hasContentsOfAllSources =
+  function BasicSourceMapConsumer_hasContentsOfAllSources() {
+    if (!this.sourcesContent) {
+      return false;
+    }
+    return this.sourcesContent.length >= this._sources.size() &&
+      !this.sourcesContent.some(function (sc) { return sc == null; });
+  };
+
+/**
+ * Returns the original source content. The only argument is the url of the
+ * original source file. Returns null if no original source content is
+ * available.
+ */
+BasicSourceMapConsumer.prototype.sourceContentFor =
+  function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
+    if (!this.sourcesContent) {
+      return null;
+    }
+
+    if (this.sourceRoot != null) {
+      aSource = util.relative(this.sourceRoot, aSource);
+    }
+
+    if (this._sources.has(aSource)) {
+      return this.sourcesContent[this._sources.indexOf(aSource)];
+    }
+
+    var url;
+    if (this.sourceRoot != null
+        && (url = util.urlParse(this.sourceRoot))) {
+      // XXX: file:// URIs and absolute paths lead to unexpected behavior for
+      // many users. We can help them out when they expect file:// URIs to
+      // behave like it would if they were running a local HTTP server. See
+      // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
+      var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
+      if (url.scheme == "file"
+          && this._sources.has(fileUriAbsPath)) {
+        return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
+      }
+
+      if ((!url.path || url.path == "/")
+          && this._sources.has("/" + aSource)) {
+        return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+      }
+    }
+
+    // This function is used recursively from
+    // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
+    // don't want to throw if we can't find the source - we just want to
+    // return null, so we provide a flag to exit gracefully.
+    if (nullOnMissing) {
+      return null;
+    }
+    else {
+      throw new Error('"' + aSource + '" is not in the SourceMap.');
+    }
+  };
+
+/**
+ * Returns the generated line and column information for the original source,
+ * line, and column positions provided. The only argument is an object with
+ * the following properties:
+ *
+ *   - source: The filename of the original source.
+ *   - line: The line number in the original source.
+ *   - column: The column number in the original source.
+ *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
+ *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
+ *     closest element that is smaller than or greater than the one we are
+ *     searching for, respectively, if the exact element cannot be found.
+ *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
+ *
+ * and an object is returned with the following properties:
+ *
+ *   - line: The line number in the generated source, or null.
+ *   - column: The column number in the generated source, or null.
+ */
+BasicSourceMapConsumer.prototype.generatedPositionFor =
+  function SourceMapConsumer_generatedPositionFor(aArgs) {
+    var source = util.getArg(aArgs, 'source');
+    if (this.sourceRoot != null) {
+      source = util.relative(this.sourceRoot, source);
+    }
+    if (!this._sources.has(source)) {
+      return {
+        line: null,
+        column: null,
+        lastColumn: null
+      };
+    }
+    source = this._sources.indexOf(source);
+
+    var needle = {
+      source: source,
+      originalLine: util.getArg(aArgs, 'line'),
+      originalColumn: util.getArg(aArgs, 'column')
+    };
+
+    var index = this._findMapping(
+      needle,
+      this._originalMappings,
+      "originalLine",
+      "originalColumn",
+      util.compareByOriginalPositions,
+      util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
+    );
+
+    if (index >= 0) {
+      var mapping = this._originalMappings[index];
+
+      if (mapping.source === needle.source) {
+        return {
+          line: util.getArg(mapping, 'generatedLine', null),
+          column: util.getArg(mapping, 'generatedColumn', null),
+          lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
+        };
+      }
+    }
+
+    return {
+      line: null,
+      column: null,
+      lastColumn: null
+    };
+  };
+
+exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
+
+/**
+ * An IndexedSourceMapConsumer instance represents a parsed source map which
+ * we can query for information. It differs from BasicSourceMapConsumer in
+ * that it takes "indexed" source maps (i.e. ones with a "sections" field) as
+ * input.
+ *
+ * The only parameter is a raw source map (either as a JSON string, or already
+ * parsed to an object). According to the spec for indexed source maps, they
+ * have the following attributes:
+ *
+ *   - version: Which version of the source map spec this map is following.
+ *   - file: Optional. The generated file this source map is associated with.
+ *   - sections: A list of section definitions.
+ *
+ * Each value under the "sections" field has two fields:
+ *   - offset: The offset into the original specified at which this section
+ *       begins to apply, defined as an object with a "line" and "column"
+ *       field.
+ *   - map: A source map definition. This source map could also be indexed,
+ *       but doesn't have to be.
+ *
+ * Instead of the "map" field, it's also possible to have a "url" field
+ * specifying a URL to retrieve a source map from, but that's currently
+ * unsupported.
+ *
+ * Here's an example source map, taken from the source map spec[0], but
+ * modified to omit a section which uses the "url" field.
+ *
+ *  {
+ *    version : 3,
+ *    file: "app.js",
+ *    sections: [{
+ *      offset: {line:100, column:10},
+ *      map: {
+ *        version : 3,
+ *        file: "section.js",
+ *        sources: ["foo.js", "bar.js"],
+ *        names: ["src", "maps", "are", "fun"],
+ *        mappings: "AAAA,E;;ABCDE;"
+ *      }
+ *    }],
+ *  }
+ *
+ * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
+ */
+function IndexedSourceMapConsumer(aSourceMap) {
+  var sourceMap = aSourceMap;
+  if (typeof aSourceMap === 'string') {
+    sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+  }
+
+  var version = util.getArg(sourceMap, 'version');
+  var sections = util.getArg(sourceMap, 'sections');
+
+  if (version != this._version) {
+    throw new Error('Unsupported version: ' + version);
+  }
+
+  this._sources = new ArraySet();
+  this._names = new ArraySet();
+
+  var lastOffset = {
+    line: -1,
+    column: 0
+  };
+  this._sections = sections.map(function (s) {
+    if (s.url) {
+      // The url field will require support for asynchronicity.
+      // See https://github.com/mozilla/source-map/issues/16
+      throw new Error('Support for url field in sections not implemented.');
+    }
+    var offset = util.getArg(s, 'offset');
+    var offsetLine = util.getArg(offset, 'line');
+    var offsetColumn = util.getArg(offset, 'column');
+
+    if (offsetLine < lastOffset.line ||
+        (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
+      throw new Error('Section offsets must be ordered and non-overlapping.');
+    }
+    lastOffset = offset;
+
+    return {
+      generatedOffset: {
+        // The offset fields are 0-based, but we use 1-based indices when
+        // encoding/decoding from VLQ.
+        generatedLine: offsetLine + 1,
+        generatedColumn: offsetColumn + 1
+      },
+      consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+    }
+  });
+}
+
+IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
+IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
+
+/**
+ * The version of the source mapping spec that we are consuming.
+ */
+IndexedSourceMapConsumer.prototype._version = 3;
+
+/**
+ * The list of original sources.
+ */
+Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
+  get: function () {
+    var sources = [];
+    for (var i = 0; i < this._sections.length; i++) {
+      for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
+        sources.push(this._sections[i].consumer.sources[j]);
+      }
+    }
+    return sources;
+  }
+});
+
+/**
+ * Returns the original source, line, and column information for the generated
+ * source's line and column positions provided. The only argument is an object
+ * with the following properties:
+ *
+ *   - line: The line number in the generated source.
+ *   - column: The column number in the generated source.
+ *
+ * and an object is returned with the following properties:
+ *
+ *   - source: The original source file, or null.
+ *   - line: The line number in the original source, or null.
+ *   - column: The column number in the original source, or null.
+ *   - name: The original identifier, or null.
+ */
+IndexedSourceMapConsumer.prototype.originalPositionFor =
+  function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
+    var needle = {
+      generatedLine: util.getArg(aArgs, 'line'),
+      generatedColumn: util.getArg(aArgs, 'column')
+    };
+
+    // Find the section containing the generated position we're trying to map
+    // to an original position.
+    var sectionIndex = binarySearch.search(needle, this._sections,
+      function(needle, section) {
+        var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
+        if (cmp) {
+          return cmp;
+        }
+
+        return (needle.generatedColumn -
+                section.generatedOffset.generatedColumn);
+      });
+    var section = this._sections[sectionIndex];
+
+    if (!section) {
+      return {
+        source: null,
+        line: null,
+        column: null,
+        name: null
+      };
+    }
+
+    return section.consumer.originalPositionFor({
+      line: needle.generatedLine -
+        (section.generatedOffset.generatedLine - 1),
+      column: needle.generatedColumn -
+        (section.generatedOffset.generatedLine === needle.generatedLine
+         ? section.generatedOffset.generatedColumn - 1
+         : 0),
+      bias: aArgs.bias
+    });
+  };
+
+/**
+ * Return true if we have the source content for every source in the source
+ * map, false otherwise.
+ */
+IndexedSourceMapConsumer.prototype.hasContentsOfAllSources =
+  function IndexedSourceMapConsumer_hasContentsOfAllSources() {
+    return this._sections.every(function (s) {
+      return s.consumer.hasContentsOfAllSources();
+    });
+  };
+
+/**
+ * Returns the original source content. The only argument is the url of the
+ * original source file. Returns null if no original source content is
+ * available.
+ */
+IndexedSourceMapConsumer.prototype.sourceContentFor =
+  function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
+    for (var i = 0; i < this._sections.length; i++) {
+      var section = this._sections[i];
+
+      var content = section.consumer.sourceContentFor(aSource, true);
+      if (content) {
+        return content;
+      }
+    }
+    if (nullOnMissing) {
+      return null;
+    }
+    else {
+      throw new Error('"' + aSource + '" is not in the SourceMap.');
+    }
+  };
+
+/**
+ * Returns the generated line and column information for the original source,
+ * line, and column positions provided. The only argument is an object with
+ * the following properties:
+ *
+ *   - source: The filename of the original source.
+ *   - line: The line number in the original source.
+ *   - column: The column number in the original source.
+ *
+ * and an object is returned with the following properties:
+ *
+ *   - line: The line number in the generated source, or null.
+ *   - column: The column number in the generated source, or null.
+ */
+IndexedSourceMapConsumer.prototype.generatedPositionFor =
+  function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
+    for (var i = 0; i < this._sections.length; i++) {
+      var section = this._sections[i];
+
+      // Only consider this section if the requested source is in the list of
+      // sources of the consumer.
+      if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) {
+        continue;
+      }