Bug 1423158 - Update Debugger Frontend (12-5). r=jdescottes, jlaster draft
authoryulia <ystartsev@mozilla.com>
Tue, 05 Dec 2017 16:23:55 +0100
changeset 709005 0c86234052b2c750392c73fc7375f1e16539cb0d
parent 707247 88b2d7276416f8b69191ca5fb1b5c670ec8178b8
child 743298 4406da95fd61e6582587a594ebe95a095b1795a9
push id92505
push userjdescottes@mozilla.com
push dateThu, 07 Dec 2017 12:02:59 +0000
reviewersjdescottes, jlaster
bugs1423158
milestone59.0a1
Bug 1423158 - Update Debugger Frontend (12-5). r=jdescottes, jlaster MozReview-Commit-ID: 9dN5czthUZT
devtools/client/debugger/new/README.mozilla
devtools/client/debugger/new/debugger.css
devtools/client/debugger/new/debugger.js
devtools/client/debugger/new/panel.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/.eslintrc
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-console-link.js
devtools/client/debugger/new/test/mochitest/browser_dbg-content-script-sources.js
devtools/client/debugger/new/test/mochitest/browser_dbg-outline.js
devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-console.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps3.js
devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js
devtools/client/debugger/new/test/mochitest/examples/doc-content-script-sources.html
devtools/client/debugger/new/test/mochitest/examples/doc-sourcemaps3.html
devtools/client/debugger/new/test/mochitest/examples/script-switching-02.js
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/.babelrc
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/.gitignore
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/bundle.js
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/bundle.js.map
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/package.json
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/sorted.js
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/test.js
devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/webpack.config.js
devtools/client/debugger/new/test/mochitest/head.js
devtools/client/jar.mn
devtools/client/locales/en-US/debugger.properties
devtools/client/preferences/debugger.js
devtools/client/themes/images/debugger/close.svg
devtools/client/themes/images/debugger/react.svg
--- 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: efa4ca367dadb1bb54525f9fe305dd38c0ec6323
+Taken from upstream commit: d2ed2927c7070e7443f297f98f1bf145a583f3c7
 
 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
@@ -436,20 +436,16 @@ body {
   box-shadow: 1px 1px 3px 1px var(--popup-shadow-color);
 }
 
 .modal .input-wrapper {
   display: flex;
   justify-content: center;
 }
 
-.modal .close-btn {
-  padding: 6px;
-}
-
 .modal .result-list {
   height: calc(100% - 28px);
   overflow-y: auto;
 }
 
 .modal.entering,
 .modal.exited {
   transform: translateY(-101%);
@@ -524,16 +520,17 @@ body {
   }
 }
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.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;
+  --icon-size: 13px;
 }
 
 :root.theme-light,
 :root .theme-light {
   --search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
   --popup-shadow-color: #d0d0d0;
 }
 
@@ -1064,16 +1061,36 @@ html .arrow.expanded svg {
   height: 15px;
   margin-right: 5px;
   vertical-align: sub;
 }
 
 .theme-dark .webpack {
   opacity: 0.5;
 }
+
+.function svg {
+  height: 10px;
+  width: 15px;
+}
+
+.function path {
+  fill: var(--theme-body-color);
+}
+
+.angular svg {
+  width: 15px;
+  height: 15px;
+  margin-right: 5px;
+  vertical-align: sub;
+}
+
+.theme-dark .angular {
+  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;
@@ -1113,62 +1130,54 @@ html[dir="rtl"] .managed-tree .tree .nod
 
 .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 {
+  width: 14px;
+  height: 14px;
+  border: 1px solid transparent;
+  border-radius: 2px;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
 }
 
 .close-btn .close {
-  width: 14px;
-  height: 14px;
+  mask: url("chrome://devtools/skin/images/debugger/close.svg") no-repeat;
+  mask-size: 100%;
+  background-color: var(--theme-comment-alt);
+  width: 8px;
+  height: 8px;
   transition: all 0.15s ease-in-out;
-  border: 1px solid transparent;
-  border-radius: 2px;
   padding: 0;
   margin-top: 0;
-  display: inline-flex;
-  justify-content: center;
-}
-
-.close-btn .close svg {
-  width: 8px;
+}
+
+.close-btn:hover img.close {
+  background-color: white;
 }
 
 .close-btn:hover {
-  display: block;
-}
-
-.close-btn:hover .close {
-  background: var(--theme-selection-background);
-}
-
-.close-btn:hover .close path {
-  fill: white;
+  background-color: var(--theme-selection-background);
 }
 
 .close-btn.big {
-  padding: 11px;
-  margin-right: 7px;
-  width: 27px;
-  height: 40px;
+  width: 16px;
+  height: 16px;
 }
 
 .close-btn.big .close {
-  width: 16px;
-  height: 16px;
-}
-
-.close-btn.big .close svg {
   width: 9px;
+  height: 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;
@@ -1354,19 +1363,23 @@ html[dir="rtl"] .managed-tree .tree .nod
 }
 
 .project-text-search .search-field {
   display: flex;
   align-self: stretch;
   flex-grow: 1;
 }
 
+.project-text-search .search-field .close-btn.big {
+  margin-top: 12px;
+}
+
 .project-text-search .managed-tree {
   overflow-y: auto;
-  height: calc(100% - 81px);
+  height: 100%;
 }
 
 .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/>. */
@@ -1473,17 +1486,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;
+  height: 30px;
 }
 
 .source-outline-tabs .tab {
   flex: 1;
   justify-content: center;
   border-bottom: 1px solid transparent;
   border-left: 1px solid transparent;
   display: inline-flex;
@@ -1570,32 +1583,31 @@ html[dir="rtl"] .managed-tree .tree .nod
   padding: 10px;
   margin: 0;
 }
 
 .outline-list__class-list {
   list-style: none;
   margin: 0;
   padding: 0;
-  padding-left: 10px;
 }
 
 .outline-list h2 {
   font-weight: normal;
   font-size: 1em;
   margin: 10px 0;
   color: var(--theme-body-color);
 }
 
 .outline-list__element {
-  color: blue;
-  padding-bottom: 0.2rem;
+  padding-bottom: 0.5rem;
   padding-right: 0.5rem;
   padding-top: 0.2rem;
   cursor: default;
+  white-space: nowrap;
 }
 
 .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/>. */
@@ -1604,17 +1616,17 @@ html[dir="rtl"] .managed-tree .tree .nod
   align-self: center;
 }
 
 .function-signature .function-name {
   color: var(--theme-highlight-blue);
 }
 
 .function-signature .param {
-  color: var(--string-color);
+  color: var(--theme-highlight-red);
 }
 
 .function-signature .paren {
   color: var(--object-color);
 }
 
 .function-signature .comma {
   color: var(--object-color);
@@ -1772,18 +1784,18 @@ html .toggle-button-end.vertical svg {
   flex-direction: column;
 }
 
 .search-bar .search-field {
   padding-left: 7px;
   height: var(--editor-searchbar-height);
 }
 
-.search-bar .close-btn {
-  padding: 6px;
+.search-field .close-btn {
+  margin-top: 7px;
 }
 
 .search-bottom-bar * {
   -moz-user-select: none;
   user-select: none;
 }
 
 .search-bottom-bar {
@@ -2201,16 +2213,24 @@ html[dir="rtl"] .arrow svg,
   position: fixed;
   z-index: 100;
 }
 
 .popover .gap {
   height: 5px;
   padding-top: 5px;
 }
+
+.popover .preview-popup {
+  margin-left: -55px;
+}
+
+.popover .add-to-expression-bar {
+  margin-left: -55px;
+}
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.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;
@@ -2398,16 +2418,17 @@ html[dir="rtl"] .arrow svg,
   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);
   border-bottom: 1px solid var(--theme-splitter-color);
+  padding-right: 16px;
 }
 
 .conditional-breakpoint-panel .prompt {
   font-size: 1.8em;
   color: var(--theme-conditional-breakpoint-color);
   padding-left: 3px;
   padding-right: 3px;
   padding-bottom: 3px;
@@ -2444,16 +2465,21 @@ html[dir="rtl"] .arrow svg,
 
 .theme-dark .editor-wrapper {
   --debug-expression-background: #54617e;
   --debug-line-border: #7786a2;
 }
 
 .editor-wrapper .CodeMirror-linewidget {
   margin-right: -7px;
+  overflow: visible;
+}
+
+.editor-wrapper .CodeMirror-sizer {
+  min-width: 0 !important;
 }
 
 .theme-dark {
   --theme-conditional-breakpoint-color: #9fa4a9;
 }
 
 .theme-light {
   --theme-conditional-breakpoint-color: var(--theme-body-color);
@@ -2849,36 +2875,32 @@ html .breakpoints-list .breakpoint.pause
 
 :root.theme-dark .expression-container:hover {
   background-color: var(--search-overlays-semitransparent);
 }
 
 .expression-container__close-btn {
   position: absolute;
   offset-inline-end: 0px;
-  top: 4px;
+  top: 0px;
 }
 
 .expression-content {
   position: relative;
 }
 
 .expression-content .tree {
   overflow-x: hidden;
   max-width: calc(100% - var(--breakpoint-expression-right-clear-space));
 }
 
 .expression-content .tree-node {
   overflow-x: hidden;
 }
 
-.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,
@@ -3199,17 +3221,17 @@ html .breakpoints-list .breakpoint.pause
 .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;
+  flex: 0 0 30px;
   border-bottom: 1px solid var(--theme-splitter-color);
   display: flex;
   overflow: hidden;
   z-index: 1;
   background-color: var(--theme-toolbar-background);
 }
 
 html[dir="rtl"] .command-bar {
@@ -3330,16 +3352,151 @@ img.resume {
 }
 .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/>. */
 
+.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;
+  top: 23px;
+  width: var(--width);
+  z-index: 1000;
+  overflow: auto;
+}
+
+html[dir="rtl"] .dropdown {
+  right: calc((var(--width) - 11px) * (-1));
+}
+
+.dropdown-block {
+  padding: 0px 2px;
+  position: relative;
+  align-self: center;
+}
+
+.dropdown-button {
+  color: var(--theme-content-color3);
+  background: none;
+  border: none;
+  padding: 0;
+  font-weight: 100;
+  font-size: 14px;
+}
+
+.dropdown li {
+  transition: all 0.25s ease;
+  padding: 2px 10px 10px 5px;
+  overflow: hidden;
+  height: 30px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.dropdown li:hover {
+  background-color: var(--search-overlays-semitransparent);
+}
+
+.dropdown-icon {
+  width: var(--icon-size);
+  height: var(--icon-size);
+  margin-right: 5px;
+  vertical-align: middle;
+}
+
+.dropdown-icon.prettyPrint {
+  mask: url("chrome://devtools/skin/images/debugger/prettyPrint.svg") no-repeat;
+  mask-size: 100%;
+  background: var(--theme-highlight-blue);
+}
+
+.dropdown-icon.blackBox {
+  mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
+  mask-size: 100%;
+  background: var(--theme-highlight-blue);
+}
+
+.dropdown-icon.file {
+  mask: url("chrome://devtools/skin/images/debugger/file.svg") no-repeat;
+  mask-size: 100%;
+}
+
+.dropdown ul {
+  list-style: none;
+  line-height: 2em;
+  font-size: 1em;
+  margin: 0;
+  padding: 0;
+}
+
+.dropdown-mask {
+  position: fixed;
+  width: 100%;
+  height: 100%;
+  background: transparent;
+  z-index: 999;
+  left: 0;
+  top: 0;
+}
+.dropdown span.icon-spacer {
+  margin-left: 8px;
+}
+
+.dropdown li.first {
+  border-bottom: 1px solid var(--theme-toolbar-background-hover);
+}
+
+img.pause-next,
+img.pause-on-exceptions,
+img.pause-uncaught-exceptions,
+img.ignore-exceptions {
+  vertical-align: middle;
+  width: 16px;
+  height: 20px;
+  display: inline-block;
+}
+
+.dropdown div > img.pause-next {
+  mask: url("chrome://devtools/skin/images/debugger/pause.svg") no-repeat;
+  background-color: var(--theme-body-color);
+}
+
+.dropdown div > img.ignore-exceptions {
+  mask: url("chrome://devtools/skin/images/debugger/pause-exceptions.svg") no-repeat;
+  background-color: var(--theme-body-color);
+}
+
+.dropdown div > img.pause-uncaught-exceptions {
+  mask: url("chrome://devtools/skin/images/debugger/pause-exceptions.svg") no-repeat;
+  background-color: var(--theme-highlight-purple);
+}
+
+.dropdown div > img.pause-on-exceptions {
+  mask: url("chrome://devtools/skin/images/debugger/pause-exceptions.svg") no-repeat;
+  background-color: var(--theme-highlight-blue);
+}
+
+.dropdown div.pause-next.active,
+.dropdown div.pause-on-exceptions.active,
+.dropdown div.pause-uncaught-exceptions.active,
+.dropdown div.ignore-exceptions.active > span.icon-spacer {
+  color: 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/>. */
+
 .object-node.default-property {
   opacity: 0.6;
 }
 
 .object-label {
   color: var(--theme-highlight-blue);
 }
 
@@ -3408,16 +3565,35 @@ img.resume {
   -moz-user-select: none;
   user-select: none;
   cursor: default;
 }
 
 .theme-dark .secondary-panes .accordion .arrow svg {
   fill: var(--theme-content-color3);
 }
+
+.secondary-panes .breakpoints-buttons {
+  display: flex;
+}
+
+.secondary-panes .accordion .plus svg {
+  width: 12px;
+  margin-top: 3px;
+  fill: var(--theme-comment-alt);
+}
+
+.secondary-panes .accordion .plus.active svg {
+  fill: var(--theme-highlight-blue);
+}
+
+.dropdown {
+  width: 20em;
+  overflow: auto;
+}
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.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 */
@@ -3500,17 +3676,17 @@ html .welcomebox .toggle-button-end.coll
 }
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.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;
+  height: 30px;
   display: flex;
   align-items: flex-end;
 }
 
 .source-header * {
   -moz-user-select: none;
   user-select: none;
 }
@@ -3538,17 +3714,17 @@ html .welcomebox .toggle-button-end.coll
   align-self: flex-start;
 }
 
 .source-tab {
   border: 1px solid transparent;
   border-top-left-radius: 2px;
   border-top-right-radius: 2px;
   display: inline-flex;
-  align-items: flex-end;
+  align-items: center;
   position: relative;
   transition: all 0.15s ease;
   min-width: 40px;
   overflow: hidden;
   padding: 5px;
   margin-inline-start: 3px;
   margin-top: 3px;
   cursor: default;
@@ -3597,16 +3773,25 @@ html .welcomebox .toggle-button-end.coll
   mask: url("chrome://devtools/skin/images/debugger/blackBox.svg") no-repeat;
   mask-size: 100%;
   padding-top: 12px;
   height: 12px;
   width: 12px;
   background: var(--theme-highlight-blue);
 }
 
+.source-tab img.react {
+  mask: url("chrome://devtools/skin/images/debugger/react.svg") no-repeat;
+  mask-size: 100%;
+  padding-top: 12px;
+  height: 14px;
+  width: 14px;
+  background: var(--theme-highlight-bluegrey);
+}
+
 .source-tab .blackBox path {
   fill: var(--theme-textbox-box-shadow);
 }
 
 .theme-dark .source-tab .blackBox circle {
   fill: var(--theme-body-color);
 }
 
@@ -3629,83 +3814,16 @@ html .welcomebox .toggle-button-end.coll
 
 .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;
-  top: 23px;
-  width: var(--width);
-  z-index: 1000;
-  overflow: auto;
-}
-
-html[dir="rtl"] .dropdown {
-  right: calc((var(--width) - 11px) * (-1));
-}
-
-.dropdown-block {
-  padding: 0px 2px;
-  position: relative;
-  align-self: center;
-}
-
-.dropdown-button {
-  color: var(--theme-content-color3);
-  background: none;
-  border: none;
-  padding: 0;
-  font-weight: 100;
-  font-size: 14px;
-}
-
-.dropdown li {
-  transition: all 0.25s ease;
-  padding: 2px 10px 10px 5px;
-  overflow: hidden;
-  height: 30px;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.dropdown li:hover {
-  background-color: var(--search-overlays-semitransparent);
-}
-
-.dropdown ul {
-  list-style: none;
-  line-height: 2em;
-  font-size: 1em;
-  margin: 0;
-  padding: 0;
-}
-
-.dropdown-mask {
-  position: fixed;
-  width: 100%;
-  height: 100%;
-  background: transparent;
-  z-index: 999;
-  left: 0;
-  top: 0;
-}
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.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 */
 }
 
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -10213,16 +10213,17 @@ Object.defineProperty(__webpack_exports_
 const { isDevelopment } = __webpack_require__(1355);
 const { Services, PrefsHelper } = __webpack_require__(1376);
 
 const prefsSchemaVersion = "1.0.3";
 
 const pref = Services.pref;
 
 if (isDevelopment()) {
+  pref("devtools.debugger.auto-pretty-print", true);
   pref("devtools.source-map.client-service.enabled", true);
   pref("devtools.debugger.pause-on-exceptions", false);
   pref("devtools.debugger.ignore-caught-exceptions", false);
   pref("devtools.debugger.call-stack-visible", false);
   pref("devtools.debugger.start-panel-collapsed", false);
   pref("devtools.debugger.end-panel-collapsed", false);
   pref("devtools.debugger.tabs", "[]");
   pref("devtools.debugger.ui.framework-grouping-on", true);
@@ -10235,19 +10236,23 @@ if (isDevelopment()) {
   pref("devtools.debugger.project-directory-root", "");
   pref("devtools.debugger.prefs-schema-version", "1.0.1");
   pref("devtools.debugger.features.project-text-search", true);
   pref("devtools.debugger.features.async-stepping", true);
   pref("devtools.debugger.features.wasm", true);
   pref("devtools.debugger.features.shortcuts", true);
   pref("devtools.debugger.features.root", true);
   pref("devtools.debugger.features.column-breakpoints", true);
+  pref("devtools.debugger.features.map-scopes", true);
+  pref("devtools.debugger.features.breakpoints-dropdown", true);
+  pref("devtools.debugger.features.remove-command-bar-options", true);
 }
 
 const prefs = new PrefsHelper("devtools", {
+  autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
   clientSourceMapsEnabled: ["Bool", "source-map.client-service.enabled"],
   pauseOnExceptions: ["Bool", "debugger.pause-on-exceptions"],
   ignoreCaughtExceptions: ["Bool", "debugger.ignore-caught-exceptions"],
   callStackVisible: ["Bool", "debugger.call-stack-visible"],
   startPanelCollapsed: ["Bool", "debugger.start-panel-collapsed"],
   endPanelCollapsed: ["Bool", "debugger.end-panel-collapsed"],
   frameworkGroupingOn: ["Bool", "debugger.ui.framework-grouping-on"],
   tabs: ["Json", "debugger.tabs", []],
@@ -10264,17 +10269,20 @@ const prefs = new PrefsHelper("devtools"
 
 
 const features = new PrefsHelper("devtools.debugger.features", {
   asyncStepping: ["Bool", "async-stepping", false],
   projectTextSearch: ["Bool", "project-text-search", true],
   wasm: ["Bool", "wasm", true],
   shortcuts: ["Bool", "shortcuts", true],
   root: ["Bool", "root", false],
-  columnBreakpoints: ["Bool", "column-breakpoints", false]
+  columnBreakpoints: ["Bool", "column-breakpoints", false],
+  mapScopes: ["Bool", "map-scopes", true],
+  breakpointsDropdown: ["Bool", "breakpoints-dropdown", true],
+  removeCommandBarOptions: ["Bool", "remove-command-bar-options", true]
 });
 /* harmony export (immutable) */ __webpack_exports__["features"] = features;
 
 
 if (prefs.debuggerPrefsSchemaVersion !== prefsSchemaVersion) {
   // clear pending Breakpoints
   prefs.pendingBreakpoints = {};
   prefs.debuggerPrefsSchemaVersion = prefsSchemaVersion;
@@ -14261,17 +14269,17 @@ module.exports = "<svg xmlns=\"http://ww
 /* 955 */,
 /* 956 */,
 /* 957 */,
 /* 958 */,
 /* 959 */,
 /* 960 */
 /***/ (function(module, exports) {
 
-module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (setDirectoryRoot): This is the text that appears in the\n# context menu to set a directory as root directory\nsetDirectoryRoot.label=Set directory root\nsetDirectoryRoot.accesskey=r\n\n# LOCALIZATION NOTE (copyFunction): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\neditor.disableBreakpoint.accesskey=D\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\neditor.addConditionalBreakpoint.accesskey=c\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\neditor.jumpToMappedLocation1.accesskey=m\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=Generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\nexpressions.label=Add watch expression\nexpressions.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.mappedSource): Text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSource=(From %S)\n\n# LOCALIZATION NOTE (sourceFooter.mappedSourceTooltip): Tooltip text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSourceTooltip=(Source mapped from %S)\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder\n# text displayed when the user searches for specific lines in a file\ngotoLineModal.placeholder=Go to line…\ngotoLineModal.key=CmdOrCtrl+Shift+;\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\nshortcuts.toggleBreakpoint.accesskey=B\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
+module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUri2): This is the text that appears in the\n# context menu to copy the source URI of file open.\ncopySourceUri2=Copy source URI\ncopySourceUri2.accesskey=u\n\n# LOCALIZATION NOTE (setDirectoryRoot): This is the text that appears in the\n# context menu to set a directory as root directory\nsetDirectoryRoot.label=Set directory root\nsetDirectoryRoot.accesskey=r\n\n# LOCALIZATION NOTE (copyFunction): This is the text that appears in the\n# context menu to copy the function the user selected\ncopyFunction.label=Copy function\ncopyFunction.accesskey=F\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy stack trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step in %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step out %S\n\n# LOCALIZATION NOTE (pauseButtonItem): The label that is displayed for the dropdown pause\n# list item when the debugger is in a running state.\npauseButtonItem=Pause on Next Statement\n\n# LOCALIZATION NOTE (ignoreExceptionsItem): The pause on exceptions button description\n# when the debugger will not pause on exceptions.\nignoreExceptionsItem=Ignore exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptionsItem): The pause on exceptions dropdown\n# item shown when a user is adding a new breakpoint.\npauseOnUncaughtExceptionsItem=Pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptionsItem): The pause on exceptions button description\n# when the debugger will pause on all exceptions.\npauseOnExceptionsItem=Pause on all exceptions\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display.\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (toggleBreakpoint.key): A key shortcut to toggle\n# breakpoints.\ntoggleBreakpoint.key=CmdOrCtrl+B\n\n# LOCALIZATION NOTE (toggleCondPanel.key): A key shortcut to toggle\n# the conditional breakpoint panel.\ntoggleCondPanel.key=CmdOrCtrl+Shift+B\n\n# LOCALIZATION NOTE (stepOut.key): A key shortcut to\n# step out.\nstepOut.key=Shift+F11\n\n# LOCALIZATION NOTE (shortcuts.header.editor): Sections header in\n# the shortcuts modal for keyboard shortcuts related to editing.\nshortcuts.header.editor=Editor\n\n# LOCALIZATION NOTE (shortcuts.header.stepping): Sections header in\n# the shortcuts modal for keyboard shortcuts related to stepping.\nshortcuts.header.stepping=Stepping\n\n# LOCALIZATION NOTE (shortcuts.header.search): Sections header in\n# the shortcuts modal for keyboard shortcuts related to search.\nshortcuts.header.search=Search\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (projectTextSearch.noResults): The center pane Text Search\n# message when the query did not match any text of all files in a project.\nprojectTextSearch.noResults=No results found\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf2.label=Enable\nbreakpointMenuItem.enableSelf2.accesskey=E\nbreakpointMenuItem.disableSelf2.label=Disable\nbreakpointMenuItem.disableSelf2.accesskey=D\nbreakpointMenuItem.deleteSelf2.label=Remove\nbreakpointMenuItem.deleteSelf2.accesskey=R\nbreakpointMenuItem.enableOthers2.label=Enable others\nbreakpointMenuItem.enableOthers2.accesskey=o\nbreakpointMenuItem.disableOthers2.label=Disable others\nbreakpointMenuItem.disableOthers2.accesskey=s\nbreakpointMenuItem.deleteOthers2.label=Remove others\nbreakpointMenuItem.deleteOthers2.accesskey=h\nbreakpointMenuItem.enableAll2.label=Enable all\nbreakpointMenuItem.enableAll2.accesskey=b\nbreakpointMenuItem.disableAll2.label=Disable all\nbreakpointMenuItem.disableAll2.accesskey=k\nbreakpointMenuItem.deleteAll2.label=Remove all\nbreakpointMenuItem.deleteAll2.accesskey=a\nbreakpointMenuItem.removeCondition2.label=Remove condition\nbreakpointMenuItem.removeCondition2.accesskey=c\nbreakpointMenuItem.addCondition2.label=Add condition\nbreakpointMenuItem.addCondition2.accesskey=A\nbreakpointMenuItem.editCondition2.label=Edit condition\nbreakpointMenuItem.editCondition2.accesskey=n\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\nbreakpointMenuItem.removeCondition.label=Remove breakpoint condition\nbreakpointMenuItem.removeCondition.accesskey=c\nbreakpointMenuItem.editCondition.label=Edit breakpoint condition\nbreakpointMenuItem.editCondition.accesskey=n\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=No results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.continueToHere.label): Editor gutter context\n# menu item for jumping to a new paused location\neditor.continueToHere.label=Continue to here\neditor.continueToHere.accesskey=H\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable breakpoint\neditor.disableBreakpoint.accesskey=D\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add conditional breakpoint\neditor.addConditionalBreakpoint.accesskey=c\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\neditor.jumpToMappedLocation1.accesskey=m\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable framework grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable framework grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add watch expression\nexpressions.label=Add watch expression\nexpressions.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close other tabs\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty print source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed source\n\n# LOCALIZATION NOTE (sourceFooter.mappedSource): Text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSource=(From %S)\n\n# LOCALIZATION NOTE (sourceFooter.mappedSourceTooltip): Tooltip text associated\n# with a mapped source. %S is replaced by the source map origin.\nsourceFooter.mappedSourceTooltip=(Source mapped from %S)\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (outline.noFunctions): Outline text when there are no functions to display\noutline.noFunctions=No functions\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText3): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText3=Error loading this URI: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(gotoLineModal.placeholder): The placeholder\n# text displayed when the user searches for specific lines in a file\ngotoLineModal.placeholder=Go to line…\ngotoLineModal.key=CmdOrCtrl+Shift+;\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n\n# LOCALIZATION NOTE (anonymous): The text that is displayed when the\n# display name is null.\nanonymous=(anonymous)\n\n# LOCALIZATION NOTE (shortcuts.toggleBreakpoint): text describing\n# keyboard shortcut action for toggling breakpoint\nshortcuts.toggleBreakpoint=Toggle Breakpoint\nshortcuts.toggleBreakpoint.accesskey=B\n\n# LOCALIZATION NOTE (shortcuts.toggleCondPanel): text describing\n# keyboard shortcut action for toggling conditional panel keyboard\nshortcuts.toggleCondPanel=Toggle Conditional Panel\n\n# LOCALIZATION NOTE (shortcuts.pauseOrResume): text describing\n# keyboard shortcut action for pause of resume\nshortcuts.pauseOrResume=Pause/Resume\n\n# LOCALIZATION NOTE (shortcuts.stepOver): text describing\n# keyboard shortcut action for stepping over\nshortcuts.stepOver=Step Over\n\n# LOCALIZATION NOTE (shortcuts.stepIn): text describing\n# keyboard shortcut action for stepping in\nshortcuts.stepIn=Step In\n\n# LOCALIZATION NOTE (shortcuts.stepOut): text describing\n# keyboard shortcut action for stepping out\nshortcuts.stepOut=Step Out\n\n# LOCALIZATION NOTE (shortcuts.fileSearch): text describing\n# keyboard shortcut action for source file search\nshortcuts.fileSearch=Source File Search\n\n# LOCALIZATION NOTE (shortcuts.searchAgain): text describing\n# keyboard shortcut action for searching again\nshortcuts.searchAgain=Search Again\n\n# LOCALIZATION NOTE (shortcuts.projectSearch): text describing\n# keyboard shortcut action for full project search\nshortcuts.projectSearch=Full Project Search\n\n# LOCALIZATION NOTE (shortcuts.functionSearch): text describing\n# keyboard shortcut action for function search\nshortcuts.functionSearch=Function Search\n\n# LOCALIZATION NOTE (shortcuts.buttonName): text describing\n# keyboard shortcut button text\nshortcuts.buttonName=Keyboard shortcuts\n"
 
 /***/ }),
 /* 961 */,
 /* 962 */,
 /* 963 */,
 /* 964 */,
 /* 965 */
 /***/ (function(module, exports) {
@@ -16484,17 +16492,17 @@ module.exports = "<svg version=\"1.1\" x
 /***/ (function(module, exports) {
 
 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/. --><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"#D92215\"><path d=\"M8 14.5c-3.6 0-6.5-2.9-6.5-6.5S4.4 1.5 8 1.5s6.5 2.9 6.5 6.5-2.9 6.5-6.5 6.5zm0-12C5 2.5 2.5 5 2.5 8S5 13.5 8 13.5 13.5 11 13.5 8 11 2.5 8 2.5z\"></path><circle cx=\"5\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><circle cx=\"9\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><path d=\"M5.5 11c-.1 0-.2 0-.3-.1-.2-.1-.3-.4-.1-.7C6 9 7 8.5 8.1 8.5c1.7.1 2.8 1.7 2.8 1.8.2.2.1.5-.1.7-.2.1-.6 0-.7-.2 0 0-.9-1.3-2-1.3-.7 0-1.4.4-2.1 1.3-.2.2-.4.2-.5.2z\"></path></svg>"
 
 /***/ }),
 /* 1348 */
 /***/ (function(module, exports) {
 
-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/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.917 7C13.44 4.162 10.973 2 8 2 4.686 2 2 4.686 2 8s2.686 6 6 6c2.22 0 4.16-1.207 5.197-3H12c-.912 1.214-2.364 2-4 2-2.76 0-5-2.24-5-5s2.24-5 5-5c2.42 0 4.437 1.718 4.9 4h1.017z\"></path><path d=\"M14 1L8 7h6V1zm-1 1L9 6h4V2z\" fill-rule=\"evenodd\"></path></svg>"
+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/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"context-fill\"><path d=\"M13.917 7C13.44 4.162 10.973 2 8 2 4.686 2 2 4.686 2 8s2.686 6 6 6c2.22 0 4.16-1.207 5.197-3H12c-.912 1.214-2.364 2-4 2-2.76 0-5-2.24-5-5s2.24-5 5-5c2.42 0 4.437 1.718 4.9 4h1.017z\"></path><path d=\"M14 1L8 7h6V1zm-1 1L9 6h4V2z\" fill-rule=\"evenodd\"></path></svg>"
 
 /***/ }),
 /* 1349 */,
 /* 1350 */,
 /* 1351 */,
 /* 1352 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -16560,41 +16568,46 @@ var quickOpen = _interopRequireWildcard(
 var _sourceTree = __webpack_require__(1426);
 
 var sourceTree = _interopRequireWildcard(_sourceTree);
 
 var _breakpointAtLocation = __webpack_require__(1503);
 
 var _breakpointAtLocation2 = _interopRequireDefault(_breakpointAtLocation);
 
-var _linesInScope = __webpack_require__(1504);
-
-var _linesInScope2 = _interopRequireDefault(_linesInScope);
-
 var _visibleBreakpoints = __webpack_require__(1427);
 
 var _visibleBreakpoints2 = _interopRequireDefault(_visibleBreakpoints);
 
 var _isSelectedFrameVisible = __webpack_require__(1505);
 
 var _isSelectedFrameVisible2 = _interopRequireDefault(_isSelectedFrameVisible);
 
+var _getCallStackFrames = __webpack_require__(1771);
+
+var _getCallStackFrames2 = _interopRequireDefault(_getCallStackFrames);
+
+var _visibleSelectedFrame = __webpack_require__(1772);
+
+var _visibleSelectedFrame2 = _interopRequireDefault(_visibleSelectedFrame);
+
 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; } }
 
 /**
  * @param object - location
  */
 
 module.exports = _extends({}, expressions, sources, pause, debuggee, breakpoints, pendingBreakpoints, eventListeners, ui, ast, coverage, fileSearch, projectTextSearch, quickOpen, sourceTree, {
   getBreakpointAtLocation: _breakpointAtLocation2.default,
-  getInScopeLines: _linesInScope2.default,
   getVisibleBreakpoints: _visibleBreakpoints2.default,
-  isSelectedFrameVisible: _isSelectedFrameVisible2.default
+  isSelectedFrameVisible: _isSelectedFrameVisible2.default,
+  getCallStackFrames: _getCallStackFrames2.default,
+  getVisibleSelectedFrame: _visibleSelectedFrame2.default
 });
 
 /***/ }),
 /* 1353 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -17104,17 +17117,17 @@ module.exports = feature;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFileURL = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = undefined;
+exports.isLoading = exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFileURL = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = exports.isMinified = undefined;
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _utils = __webpack_require__(1366);
 
 var _path = __webpack_require__(1393);
 
 var _url = __webpack_require__(334);
@@ -17294,16 +17307,72 @@ function getSourcePath(source) {
 function getSourceLineCount(source) {
   if (source.isWasm) {
     const { binary } = source.text;
     return binary.length;
   }
   return source.text != undefined ? source.text.split("\n").length : 0;
 }
 
+// Used to detect minification for automatic pretty printing
+const SAMPLE_SIZE = 50;
+const INDENT_COUNT_THRESHOLD = 5;
+const CHARACTER_LIMIT = 250;
+const _minifiedCache = new Map();
+
+/**
+ *
+ * Checks if a source is minified based on some heuristics
+ * @param key
+ * @param text
+ * @return boolean
+ * @memberof utils/source
+ * @static
+ */
+
+function isMinified(key, text) {
+  if (!key || !text) {
+    return false;
+  }
+
+  if (_minifiedCache.has(key)) {
+    return _minifiedCache.get(key);
+  }
+
+  let lineEndIndex = 0;
+  let lineStartIndex = 0;
+  let lines = 0;
+  let indentCount = 0;
+  let overCharLimit = false;
+
+  // Strip comments.
+  text = text.replace(/\/\*[\S\s]*?\*\/|\/\/(.+|\n)/g, "");
+
+  while (lines++ < SAMPLE_SIZE) {
+    lineEndIndex = text.indexOf("\n", lineStartIndex);
+    if (lineEndIndex == -1) {
+      break;
+    }
+    if (/^\s+/.test(text.slice(lineStartIndex, lineEndIndex))) {
+      indentCount++;
+    }
+    // For files with no indents but are not minified.
+    if (lineEndIndex - lineStartIndex > CHARACTER_LIMIT) {
+      overCharLimit = true;
+      break;
+    }
+    lineStartIndex = lineEndIndex + 1;
+  }
+
+  const minified = indentCount / lines * 100 < INDENT_COUNT_THRESHOLD || overCharLimit;
+
+  _minifiedCache.set(key, minified);
+  return minified;
+}
+
 /**
  *
  * Returns Code Mirror mode for source content type
  * @param contentType
  * @return String
  * @memberof utils/source
  * @static
  */
@@ -17314,16 +17383,27 @@ function getMode(source, sourceMetaData)
   if (!text || isWasm) {
     return { name: "text" };
   }
 
   if (url && url.match(/\.jsx$/i) || sourceMetaData && sourceMetaData.isReactComponent) {
     return "jsx";
   }
 
+  const languageMimeMap = [{ ext: ".c", mode: "text/x-csrc" }, { ext: ".kt", mode: "text/x-kotlin" }, { ext: ".cpp", mode: "text/x-c++src" }, { ext: ".m", mode: "text/x-objectivec" }, { ext: ".rs", mode: "text/x-rustsrc" }];
+
+  // check for C and other non JS languages
+  if (url) {
+    const result = languageMimeMap.find(({ ext }) => url.endsWith(ext));
+
+    if (result !== undefined) {
+      return result.mode;
+    }
+  }
+
   // 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.
@@ -17353,30 +17433,35 @@ function getMode(source, sourceMetaData)
   }
 
   return { name: "text" };
 }
 
 function isLoaded(source) {
   return source.loadedState === "loaded";
 }
-
+function isLoading(source) {
+  return source.loadedState === "loading";
+}
+
+exports.isMinified = isMinified;
 exports.isJavaScript = isJavaScript;
 exports.isPretty = isPretty;
 exports.isThirdParty = isThirdParty;
 exports.shouldPrettyPrint = shouldPrettyPrint;
 exports.getPrettySourceURL = getPrettySourceURL;
 exports.getRawSourceURL = getRawSourceURL;
 exports.getFilename = getFilename;
 exports.getFilenameFromURL = getFilenameFromURL;
 exports.getFileURL = getFileURL;
 exports.getSourcePath = getSourcePath;
 exports.getSourceLineCount = getSourceLineCount;
 exports.getMode = getMode;
 exports.isLoaded = isLoaded;
+exports.isLoading = isLoading;
 
 /***/ }),
 /* 1357 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -18440,27 +18525,22 @@ function initialState() {
 }
 
 function update(state = initialState(), action) {
   let location = null;
 
   switch (action.type) {
     case "ADD_SOURCE":
       {
-        const source = action.source;
-        return updateSource(state, source);
+        return updateSource(state, action.source);
       }
 
     case "ADD_SOURCES":
       {
-        action.sources.forEach(source => {
-          state = state.mergeIn(["sources", source.id], source);
-        });
-
-        return state;
+        return action.sources.reduce((newState, source) => updateSource(newState, source), state);
       }
 
     case "SELECT_SOURCE":
       if (action.status != "start") {
         return state;
       }
 
       location = _extends({}, action.location, {
@@ -18986,20 +19066,31 @@ module.exports = {
 /***/ (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/>. */
+
+/**
+ * Redux actions for the sources state
+ * @module actions/sources
+ */
+
 exports.newSource = newSource;
 exports.newSources = newSources;
 exports.selectSourceURL = selectSourceURL;
 exports.selectSource = selectSource;
+exports.selectLocation = selectLocation;
 exports.jumpToMappedLocation = jumpToMappedLocation;
 exports.addTab = addTab;
 exports.moveTab = moveTab;
 exports.closeTab = closeTab;
 exports.closeTabs = closeTabs;
 exports.togglePrettyPrint = togglePrettyPrint;
 exports.toggleBlackBox = toggleBlackBox;
 exports.loadAllSources = loadAllSources;
@@ -19015,16 +19106,18 @@ var _breakpoints = __webpack_require__(1
 var _ast = __webpack_require__(1399);
 
 var _projectTextSearch = __webpack_require__(1433);
 
 var _ui = __webpack_require__(1385);
 
 var _source2 = __webpack_require__(1356);
 
+var _location = __webpack_require__(1774);
+
 var _createPrettySource = __webpack_require__(1523);
 
 var _loadSourceText = __webpack_require__(1435);
 
 var _prefs = __webpack_require__(226);
 
 var _editor = __webpack_require__(1358);
 
@@ -19035,29 +19128,22 @@ var _selectors = __webpack_require__(135
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 // 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/>. */
-
-/**
- * Redux actions for the sources state
- * @module actions/sources
- */
+    await dispatch(selectLocation(_extends({}, pendingLocation, { sourceId: source.id })));
+  }
+}
 
 async function checkPendingBreakpoints(state, dispatch, sourceId) {
-  // source may have been modified by selectSource
+  // source may have been modified by selectLocation
   const source = (0, _selectors.getSource)(state, sourceId).toJS();
   const pendingBreakpoints = (0, _selectors.getPendingBreakpointsForSource)(state, source.url);
   if (!pendingBreakpoints.size) {
     return;
   }
 
   // load the source text if there is a pending breakpoint for it
   await dispatch((0, _loadSourceText.loadSourceText)(source));
@@ -19089,111 +19175,143 @@ function newSource(source) {
     await checkPendingBreakpoints(getState(), dispatch, source.id);
   };
 }
 
 function newSources(sources) {
   return async ({ dispatch, getState }) => {
     const filteredSources = sources.filter(source => !(0, _selectors.getSource)(getState(), source.id));
 
+    if (filteredSources.length == 0) {
+      return;
+    }
+
+    dispatch({
+      type: "ADD_SOURCES",
+      sources: filteredSources
+    });
+
     for (const source of filteredSources) {
-      await dispatch(newSource(source));
+      await dispatch(loadSourceMap(source));
+      await checkSelectedSource(getState(), dispatch, source);
+      await checkPendingBreakpoints(getState(), dispatch, source.id);
     }
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
 function loadSourceMap(generatedSource) {
   return async function ({ dispatch, getState, sourceMaps }) {
     const urls = await sourceMaps.getOriginalURLs(generatedSource);
+
     if (!urls) {
       // If this source doesn't have a sourcemap, do nothing.
       return;
     }
 
     const originalSources = urls.map(originalUrl => ({
       url: originalUrl,
       id: sourceMaps.generatedToOriginalId(generatedSource.id, originalUrl),
       isPrettyPrinted: false,
       isWasm: false,
       isBlackBoxed: false,
       loadedState: "unloaded"
     }));
 
-    dispatch({ type: "ADD_SOURCES", sources: originalSources });
-
+    // TODO: check if this line is really needed, it introduces
+    // a lot of lag to the application.
     await dispatch((0, _loadSourceText.loadSourceText)(generatedSource));
-    originalSources.forEach(async source => {
-      await checkSelectedSource(getState(), dispatch, source);
-      checkPendingBreakpoints(getState(), dispatch, source.id);
-    });
+    dispatch(newSources(originalSources));
   };
 }
 
 /**
  * Deterministically select a source that has a given URL. This will
  * work regardless of the connection status or if the source exists
  * yet. This exists mostly for external things to interact with the
  * debugger.
  *
  * @memberof actions/sources
  * @static
  */
 function selectSourceURL(url, options = {}) {
   return async ({ dispatch, getState }) => {
     const source = (0, _selectors.getSourceByURL)(getState(), url);
     if (source) {
-      await dispatch(selectSource(source.get("id"), options));
+      const sourceId = source.get("id");
+      const location = (0, _location.createLocation)(_extends({}, options.location, { sourceId }));
+      // flow is unable to comprehend that if an options.location object
+      // exists, that we have a valid Location object, and if it doesnt,
+      // we have a valid { sourceId: string } object. So we are overriding
+      // the error
+      // $FlowIgnore
+      await dispatch(selectLocation(location, options.tabIndex));
     } else {
       dispatch({
         type: "SELECT_SOURCE_URL",
         url: url,
         tabIndex: options.tabIndex,
         location: options.location
       });
     }
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
-function selectSource(id, options = {}) {
+function selectSource(sourceId, tabIndex = "") {
+  return ({ dispatch }) => {
+    const location = (0, _location.createLocation)({ sourceId });
+    return dispatch(selectLocation(location, tabIndex));
+  };
+}
+
+/**
+ * @memberof actions/sources
+ * @static
+ */
+function selectLocation(location, tabIndex = "") {
   return ({ dispatch, getState, client }) => {
     if (!client) {
       // No connection, do nothing. This happens when the debugger is
       // shut down too fast and it tries to display a default source.
       return;
     }
 
-    const source = (0, _selectors.getSource)(getState(), id);
+    const source = (0, _selectors.getSource)(getState(), location.sourceId);
     if (!source) {
       // If there is no source we deselect the current selected source
       return dispatch({ type: "CLEAR_SELECTED_SOURCE" });
     }
 
     const activeSearch = (0, _selectors.getActiveSearch)(getState());
     if (activeSearch !== "file") {
       dispatch((0, _ui.closeActiveSearch)());
     }
 
     dispatch(addTab(source.toJS(), 0));
 
     return dispatch({
       type: "SELECT_SOURCE",
       source: source.toJS(),
-      tabIndex: options.tabIndex,
-      location: options.location || {},
+      tabIndex,
+      location,
       [_promise.PROMISE]: (async () => {
         await dispatch((0, _loadSourceText.loadSourceText)(source.toJS()));
         await dispatch((0, _ast.setOutOfScopeLocations)());
+        const src = (0, _selectors.getSource)(getState(), location.sourceId).toJS();
+        const { autoPrettyPrint } = _prefs.prefs;
+        if (autoPrettyPrint && (0, _source2.shouldPrettyPrint)(src) && (0, _source2.isMinified)(src.id, src.text)) {
+          await dispatch(togglePrettyPrint(src.id));
+        }
       })()
     });
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
@@ -19207,17 +19325,17 @@ function jumpToMappedLocation(sourceLoca
     const source = (0, _selectors.getSource)(getState(), sourceLocation.sourceId);
     let pairedLocation;
     if (sourceMaps.isOriginalId(sourceLocation.sourceId)) {
       pairedLocation = await (0, _sourceMaps.getGeneratedLocation)(getState(), source.toJS(), sourceLocation, sourceMaps);
     } else {
       pairedLocation = await sourceMaps.getOriginalLocation(sourceLocation, source.toJS());
     }
 
-    return dispatch(selectSource(pairedLocation.sourceId, { location: pairedLocation }));
+    return dispatch(selectLocation(_extends({}, pairedLocation)));
   };
 }
 
 function addTab(source, tabIndex) {
   return {
     type: "ADD_TAB",
     source,
     tabIndex
@@ -19279,40 +19397,44 @@ function closeTabs(urls) {
  * @returns Promise
  *          A promise that resolves to [aSource, prettyText] or rejects to
  *          [aSource, error].
  */
 function togglePrettyPrint(sourceId) {
   return async ({ dispatch, getState, client, sourceMaps }) => {
     const source = (0, _selectors.getSource)(getState(), sourceId).toJS();
 
-    if (!source || !(0, _source2.isLoaded)(source)) {
-      return {};
+    if (!source) return {};
+
+    if (!(0, _source2.isLoaded)(source)) {
+      await dispatch((0, _loadSourceText.loadSourceText)(source));
     }
 
     (0, _assert2.default)(sourceMaps.isGeneratedId(sourceId), "Pretty-printing only allowed on generated sources");
 
     const selectedLocation = (0, _selectors.getSelectedLocation)(getState());
     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"), options));
+      const _sourceId = prettySource.get("id");
+      return dispatch(selectLocation(_extends({}, options.location, { sourceId: _sourceId })));
     }
 
     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, options));
+    await dispatch((0, _ast.setSymbols)(newPrettySource.id));
+
+    return dispatch(selectLocation(_extends({}, options.location, { sourceId: newPrettySource.id })));
   };
 }
 
 function toggleBlackBox(source) {
   return async ({ dispatch, getState, client, sourceMaps }) => {
     const { isBlackBoxed, id } = source;
 
     return dispatch({
@@ -19358,37 +19480,35 @@ function loadAllSources() {
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
-var _Svg = __webpack_require__(1359);
-
-var _Svg2 = _interopRequireDefault(_Svg);
-
 __webpack_require__(1312);
 
 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 CloseButton({ handleClick, buttonClass, tooltip }) {
   return _react2.default.createElement(
     "div",
     {
       className: buttonClass ? `close-btn ${buttonClass}` : "close-btn",
       onClick: handleClick,
       title: tooltip
     },
-    _react2.default.createElement(_Svg2.default, { name: "close" })
+    _react2.default.createElement("img", { className: "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__) {
 
@@ -20313,16 +20433,17 @@ 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;
+exports.getInScopeLines = getInScopeLines;
 
 var _immutable = __webpack_require__(146);
 
 var I = _interopRequireWildcard(_immutable);
 
 var _makeRecord = __webpack_require__(1361);
 
 var _makeRecord2 = _interopRequireDefault(_makeRecord);
@@ -20340,16 +20461,17 @@ function _interopRequireWildcard(obj) { 
  * @module reducers/ast
  */
 
 function initialState() {
   return (0, _makeRecord2.default)({
     symbols: I.Map(),
     emptyLines: I.Map(),
     outOfScopeLocations: null,
+    inScopeLines: null,
     preview: null,
     sourceMetaData: I.Map()
   })();
 }
 
 function update(state = initialState(), action) {
   switch (action.type) {
     case "SET_SYMBOLS":
@@ -20364,16 +20486,21 @@ function update(state = initialState(), 
         return state.setIn(["emptyLines", source.id], emptyLines);
       }
 
     case "OUT_OF_SCOPE_LOCATIONS":
       {
         return state.set("outOfScopeLocations", action.locations);
       }
 
+    case "IN_SCOPE_LINES":
+      {
+        return state.set("inScopeLines", action.lines);
+      }
+
     case "CLEAR_SELECTION":
       {
         return state.set("preview", null);
       }
 
     case "SET_PREVIEW":
       {
         if (action.status == "start") {
@@ -20461,18 +20588,23 @@ function getEmptyLines(state, source) {
 function getOutOfScopeLocations(state) {
   return state.ast.get("outOfScopeLocations");
 }
 
 function getPreview(state) {
   return state.ast.get("preview");
 }
 
+const emptySourceMetaData = {};
 function getSourceMetaData(state, sourceId) {
-  return state.ast.getIn(["sourceMetaData", sourceId]) || {};
+  return state.ast.getIn(["sourceMetaData", sourceId]) || emptySourceMetaData;
+}
+
+function getInScopeLines(state, sourceId) {
+  return state.ast.get("inScopeLines");
 }
 
 exports.default = update;
 
 /***/ }),
 /* 1384 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -21668,17 +21800,17 @@ function setBreakpointCondition(location
 
 function toggleBreakpoint(line, column) {
   return ({ dispatch, getState, client, sourceMaps }) => {
     const state = getState();
     const selectedSource = (0, _selectors.getSelectedSource)(state);
     const bp = (0, _selectors.getBreakpointAtLocation)(state, { line, column });
     const isEmptyLine = (0, _ast.isEmptyLineInSource)(state, line, selectedSource.toJS());
 
-    if (isEmptyLine || bp && bp.loading) {
+    if (!bp && isEmptyLine || bp && bp.loading) {
       return;
     }
 
     if (bp) {
       // NOTE: it's possible the breakpoint has slid to a column
       return dispatch(removeBreakpoint({
         sourceId: bp.location.sourceId,
         sourceUrl: bp.location.sourceUrl,
@@ -21950,16 +22082,18 @@ exports.setEmptyLines = setEmptyLines;
 exports.setOutOfScopeLocations = setOutOfScopeLocations;
 exports.clearPreview = clearPreview;
 exports.setPreview = setPreview;
 
 var _selectors = __webpack_require__(1352);
 
 var _expressions = __webpack_require__(1398);
 
+var _setInScopeLines = __webpack_require__(1773);
+
 var _promise = __webpack_require__(1653);
 
 var _parser = __webpack_require__(1365);
 
 var _ast = __webpack_require__(1638);
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
@@ -22035,35 +22169,31 @@ function setEmptyLines(sourceId) {
       emptyLines
     });
   };
 }
 
 function setOutOfScopeLocations() {
   return async ({ dispatch, getState }) => {
     const location = (0, _selectors.getSelectedLocation)(getState());
+
     if (!location) {
       return;
     }
 
     const source = (0, _selectors.getSource)(getState(), location.sourceId);
 
-    if (!location.line || !source) {
-      return dispatch({
-        type: "OUT_OF_SCOPE_LOCATIONS",
-        locations: null
-      });
-    }
-
-    const locations = await (0, _parser.getOutOfScopeLocations)(source.toJS(), location);
-
-    return dispatch({
+    const locations = !location.line || !source ? null : await (0, _parser.getOutOfScopeLocations)(source.toJS(), location);
+
+    dispatch({
       type: "OUT_OF_SCOPE_LOCATIONS",
       locations
     });
+
+    dispatch((0, _setInScopeLines.setInScopeLines)());
   };
 }
 
 function clearPreview() {
   return ({ dispatch, getState, client }) => {
     const currentSelection = (0, _selectors.getPreview)(getState());
     if (!currentSelection) {
       return;
@@ -22142,57 +22272,53 @@ function setPreview(token, tokenPos, cur
 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/>. */
 
+// eslint-disable-next-line max-len
+
+
 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);
 
+var _updateScopeBindings = __webpack_require__(1775);
+
 function updateFrameLocations(frames, sourceMaps) {
   if (!frames || frames.length == 0) {
     return Promise.resolve(frames);
   }
 
   return Promise.all(frames.map(frame => sourceMaps.getOriginalLocation(frame.location).then(loc => _extends({}, frame, {
     location: loc,
     generatedLocation: frame.location
   }))));
 }
 
-function extendScope(scope, generatedScopes, index) {
-  if (!scope) {
-    return undefined;
-  }
-  if (index >= generatedScopes.length) {
-    return 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);
-  if (!generatedScopes) {
-    return scope;
-  }
-  return extendScope(scope, generatedScopes, 0);
+async function updateScopeBindings(scope, generatedLocation, originalLocation, { getLocationScopes, loadSourceText }) {
+  return (0, _updateScopeBindings.updateScopeBindings)(scope, generatedLocation, originalLocation, {
+    async getSourceMapsScopes(location) {
+      const astScopes = await (0, _parser.getScopes)(location);
+      return getLocationScopes(location, astScopes);
+    },
+    async getOriginalSourceScopes(location) {
+      await loadSourceText(location.sourceId);
+      return (0, _parser.getScopes)(location);
+    }
+  });
 }
 
 // Map protocol pause "why" reason to a valid L10N key
 // These are the known unhandled reasons:
 // "breakpointConditionThrown", "clientEvaluated"
 // "interrupted", "attached"
 const reasons = {
   debuggerStatement: "whyPaused.debuggerStatement",
@@ -22724,16 +22850,17 @@ function getFilenameFromPath(pathname) {
     // This file does not have a name. Default should be (index).
     if (filename == "" || !filename.includes(".")) {
       filename = "(index)";
     }
   }
   return filename;
 }
 
+const NoDomain = "(no domain)";
 function getURL(sourceUrl, debuggeeUrl = "") {
   const url = sourceUrl;
   const def = { path: "", group: "", filename: "" };
   if (!url) {
     return def;
   }
 
   const { pathname, protocol, host, path } = (0, _url.parse)(url);
@@ -22748,24 +22875,39 @@ function getURL(sourceUrl, debuggeeUrl =
     case "webpack:":
       // A Webpack source is a special case
       return (0, _lodash.merge)(def, {
         path: path,
         group: "Webpack",
         filename: filename
       });
 
+    case "ng:":
+      // An Angular source is a special case
+      return (0, _lodash.merge)(def, {
+        path: path,
+        group: "Angular",
+        filename: filename
+      });
+
     case "about:":
       // An about page is a special case
       return (0, _lodash.merge)(def, {
         path: "/",
         group: url,
         filename: filename
       });
 
+    case "data:":
+      return (0, _lodash.merge)(def, {
+        path: "/",
+        group: NoDomain,
+        filename: url
+      });
+
     case null:
       if (pathname && pathname.startsWith("/")) {
         // If it's just a URL like "/foo/bar.js", resolve it to the file
         // protocol
         return (0, _lodash.merge)(def, {
           path: path,
           group: "file://",
           filename: filename
@@ -23330,17 +23472,17 @@ module.exports = function defer() {
 
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.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 { Menu, MenuItem } = __webpack_require__(1376);
+const { Menu, MenuItem } = __webpack_require__(1762);
 
 function inToolbox() {
   return window.parent.document.documentURI == "about:devtools-toolbox";
 }
 
 if (!inToolbox()) {
   __webpack_require__(1301);
 }
@@ -23578,16 +23720,20 @@ function findClosestScope(functions, loc
       return found;
     }
 
     return currNode;
   }, null);
 }
 
 async function getASTLocation(source, location) {
+  if (source.isWasm) {
+    return { name: undefined, offset: location };
+  }
+
   const symbols = await (0, _parser.getSymbols)(source);
   const functions = [...symbols.functions];
 
   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;
@@ -24086,16 +24232,24 @@ function update(state = State(), action)
 
     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);
 
+    case "CLOSE_PROJECT_SEARCH":
+      {
+        if (state.get("activeSearch") === "project") {
+          return state.set("activeSearch", null);
+        }
+        return state;
+      }
+
     default:
       {
         return state;
       }
   }
 }
 
 // NOTE: we'd like to have the app state fully typed
@@ -24319,18 +24473,20 @@ exports.default = update;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.statusType = undefined;
 exports.InitialState = InitialState;
 exports.getTextSearchResults = getTextSearchResults;
+exports.getTextSearchStatus = getTextSearchStatus;
 exports.getTextSearchQuery = getTextSearchQuery;
 
 var _immutable = __webpack_require__(146);
 
 var I = _interopRequireWildcard(_immutable);
 
 var _makeRecord = __webpack_require__(1361);
 
@@ -24339,49 +24495,75 @@ var _makeRecord2 = _interopRequireDefaul
 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/>. */
 
+// @format
+
 /**
  * Project text search reducer
  * @module reducers/project-text-search
  */
 
+const statusType = exports.statusType = {
+  initial: "INITIAL",
+  fetching: "FETCHING",
+  done: "DONE",
+  error: "ERROR"
+};
+
 function InitialState() {
-  return (0, _makeRecord2.default)({ query: "", results: I.List() })();
+  return (0, _makeRecord2.default)({
+    query: "",
+    results: I.List(),
+    status: statusType.initial
+  })();
 }
 
 function update(state = InitialState(), action) {
   switch (action.type) {
     case "ADD_QUERY":
       return state.update("query", value => action.query);
 
     case "CLEAR_QUERY":
       return state.remove("query");
 
     case "ADD_SEARCH_RESULT":
       const results = state.get("results");
       return state.merge({ results: results.push(action.result) });
 
+    case "UPDATE_STATUS":
+      return state.merge({ status: action.status });
+
     case "CLEAR_SEARCH_RESULTS":
       return state.merge({
         results: state.get("results").clear()
       });
+
+    case "CLOSE_PROJECT_SEARCH":
+      return state.merge({
+        query: "",
+        results: state.get("results").clear()
+      });
   }
   return state;
 }
 
 function getTextSearchResults(state) {
   return state.projectTextSearch.get("results");
 }
 
+function getTextSearchStatus(state) {
+  return state.projectTextSearch.get("status");
+}
+
 function getTextSearchQuery(state) {
   return state.projectTextSearch.get("query");
 }
 
 exports.default = update;
 
 /***/ }),
 /* 1425 */,
@@ -24711,17 +24893,17 @@ function bootstrapStore(client, { servic
 }
 
 function bootstrapApp(connection, { store, actions }) {
   window.appStore = store;
 
   // Expose the bound actions so external things can do things like
   // selecting a source.
   window.actions = {
-    selectSource: actions.selectSource,
+    selectLocation: actions.selectLocation,
     selectSourceURL: actions.selectSourceURL
   };
 
   (0, _devtoolsLaunchpad.renderRoot)(_react2.default, _reactDom2.default, _App2.default, store);
 }
 
 function bootstrapWorkers() {
   if (!(0, _devtoolsConfig.isFirefoxPanel)()) {
@@ -24835,62 +25017,72 @@ exports.default = _assert2.default;
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.addSearchQuery = addSearchQuery;
 exports.clearSearchQuery = clearSearchQuery;
 exports.clearSearchResults = clearSearchResults;
+exports.updateSearchStatus = updateSearchStatus;
+exports.closeProjectSearch = closeProjectSearch;
 exports.searchSources = searchSources;
 exports.searchSource = searchSource;
 
 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/>. */
+var _projectTextSearch = __webpack_require__(1424);
+
+function addSearchQuery(query) {
+  return ({ dispatch, getState }) => {
+    dispatch({ type: "ADD_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/>. */
 
 /**
  * Redux actions for the search state
  * @module actions/search
  */
 
-function addSearchQuery(query) {
-  return ({ dispatch, getState }) => {
-    dispatch({ type: "ADD_QUERY", query });
-  };
-}
-
 function clearSearchQuery() {
   return ({ dispatch, getState }) => {
     dispatch({ type: "CLEAR_QUERY" });
   };
 }
 
 function clearSearchResults() {
   return ({ dispatch, getState }) => {
     dispatch({ type: "CLEAR_SEARCH_RESULTS" });
   };
 }
 
+function updateSearchStatus(status) {
+  return { type: "UPDATE_STATUS", status };
+}
+
+function closeProjectSearch() {
+  return { type: "CLOSE_PROJECT_SEARCH" };
+}
+
 function searchSources(query) {
   return async ({ dispatch, getState }) => {
     await dispatch(clearSearchResults());
     await dispatch(addSearchQuery(query));
+    dispatch(updateSearchStatus(_projectTextSearch.statusType.fetching));
     await dispatch((0, _sources.loadAllSources)());
     const sources = (0, _selectors.getSources)(getState());
     const validSources = sources.valueSeq().filter(source => (0, _source.isLoaded)(source.toJS()) && !(0, _source.isThirdParty)(source.toJS())).toJS();
-
     for (const source of validSources) {
       await dispatch(searchSource(source.id, query));
     }
   };
 }
 
 function searchSource(sourceId, query) {
   return async ({ dispatch, getState }) => {
@@ -24904,16 +25096,19 @@ function searchSource(sourceId, query) {
     dispatch({
       type: "ADD_SEARCH_RESULT",
       result: {
         sourceId: source.id,
         filepath: source.url,
         matches
       }
     });
+    if (matches.length) {
+      dispatch(updateSearchStatus(_projectTextSearch.statusType.done));
+    }
   };
 }
 
 /***/ }),
 /* 1434 */,
 /* 1435 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -24928,58 +25123,82 @@ exports.loadSourceText = loadSourceText;
 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/>. */
+var _source = __webpack_require__(1356);
+
+const requests = new 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/>. */
 
 async function loadSource(source, { sourceMaps, client }) {
   if (sourceMaps.isOriginalId(source.id)) {
     return await sourceMaps.getOriginalSourceText(source);
   }
 
   const response = await client.sourceContents(source.id);
 
   return {
     id: source.id,
     text: response.source,
     contentType: response.contentType || "text/javascript"
   };
 }
 
+function defer() {
+  let resolve = () => {};
+  let reject = () => {};
+  const promise = new Promise((_res, _rej) => {
+    resolve = _res;
+    reject = _rej;
+  });
+
+  return { resolve, reject, promise };
+}
+
 /**
  * @memberof actions/sources
  * @static
  */
 function loadSourceText(source) {
   return async ({ dispatch, getState, client, sourceMaps }) => {
+    const deferred = defer();
+
     // Fetch the source text only once.
-    if (source.text) {
+    if ((0, _source.isLoaded)(source)) {
       return Promise.resolve(source);
     }
 
+    if ((0, _source.isLoading)(source) || requests.has(source.id)) {
+      return requests.get(source.id);
+    }
+
+    requests.set(source.id, deferred.promise);
     await dispatch({
       type: "LOAD_SOURCE_TEXT",
       source: source,
       [_promise.PROMISE]: loadSource(source, { sourceMaps, client })
     });
 
     const newSource = (0, _selectors.getSource)(getState(), source.id).toJS();
     if (newSource.isWasm) {
       return;
     }
 
     await (0, _parser.setSource)(newSource);
     dispatch((0, _ast.setSymbols)(source.id));
+
+    // signal that the action is finished
+    deferred.resolve();
+    requests.delete(source.id);
   };
 }
 
 /***/ }),
 /* 1436 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -25121,19 +25340,19 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.sanitizeInput = sanitizeInput;
 exports.wrapExpression = wrapExpression;
 exports.getValue = getValue;
 
 var _indentation = __webpack_require__(1438);
 
-// replace quotes and slashes that could interfere with the evaluation.
+// replace quotes that could interfere with the evaluation.
 function sanitizeInput(input) {
-  return input.replace(/\\/g, "\\\\").replace(/"/g, '"');
+  return input.replace(/"/g, '"');
 }
 
 /*
  * 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.
 */
@@ -25533,29 +25752,29 @@ function addSourceToNode(node, url, sour
   const isFile = !(0, _utils.isDirectory)(url);
 
   // if we have a file, and the subtree has no elements, overwrite the
   // subtree contents with the source
   if (isFile) {
     return source;
   }
 
-  const name = (0, _getURL.getFilenameFromPath)(url.path);
-  const { found: childFound, index: childIndex } = (0, _treeOrder.findNodeInContents)(node, (0, _treeOrder.createTreeNodeMatcher)(name, false, null));
+  const { filename } = url;
+  const { found: childFound, index: childIndex } = (0, _treeOrder.findNodeInContents)(node, (0, _treeOrder.createTreeNodeMatcher)(filename, false, null));
 
   // if we are readding an existing file in the node, overwrite the existing
   // file and return the node's contents
   if (childFound) {
     const existingNode = node.contents[childIndex];
     existingNode.contents = source;
     return node.contents;
   }
 
   // if this is a new file, add the new file;
-  const newNode = (0, _utils.createNode)(name, source.get("url"), source);
+  const newNode = (0, _utils.createNode)(filename, source.get("url"), source);
   const contents = node.contents.slice(0);
   contents.splice(childIndex, 0, newNode);
   return contents;
 }
 
 /**
  * @memberof utils/sources-tree
  * @static
@@ -28523,17 +28742,17 @@ 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/. */
 
 const CDP = __webpack_require__(52);
 const { getValue } = __webpack_require__(1355);
-const { networkRequest } = __webpack_require__(1473);
+const { networkRequest } = __webpack_require__(1363);
 
 let connection;
 
 function createTabs(tabs, { type, clientType } = {}) {
   return tabs.filter(tab => {
     return tab.type == type;
   }).map(tab => {
     return {
@@ -28630,204 +28849,19 @@ module.exports = {
   connectClient,
   connectNodeClient,
   connectNode,
   connectTab,
   initPage
 };
 
 /***/ }),
-/* 1473 */
-/***/ (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__(1474);
-const workerUtils = __webpack_require__(1475);
-
-module.exports = {
-  networkRequest,
-  workerUtils
-};
-
-/***/ }),
-/* 1474 */
-/***/ (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 new Promise((resolve, reject) => {
-    try {
-      const req = new XMLHttpRequest();
-
-      req.addEventListener("readystatechange", () => {
-        if (req.readyState === XMLHttpRequest.DONE) {
-          if (req.status === 200) {
-            resolve({ content: req.responseText });
-          } else {
-            let text = req.statusText || "invalid URL";
-            reject(text);
-          }
-        }
-      });
-
-      // Not working yet.
-      // if (!opts.loadFromCache) {
-      //   req.channel.loadFlags = (
-      //     Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE |
-      //       Components.interfaces.nsIRequest.INHIBIT_CACHING |
-      //       Components.interfaces.nsIRequest.LOAD_ANONYMOUS
-      //   );
-      // }
-
-      req.open("GET", url);
-      req.send();
-    } catch (e) {
-      reject(e.toString());
-    }
-  });
-}
-
-module.exports = networkRequest;
-
-/***/ }),
-/* 1475 */
-/***/ (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 }), err => self.postMessage({ id, error: err }));
-      } else {
-        self.postMessage({ id, response });
-      }
-    } catch (error) {
-      self.postMessage({ id, error });
-    }
-  };
-}
-
-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
-};
-
-/***/ }),
+/* 1473 */,
+/* 1474 */,
+/* 1475 */,
 /* 1476 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -29485,33 +29519,34 @@ module.exports = update;
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const React = __webpack_require__(0);
-const { PropTypes } = React;
+const { Component } = React;
+const PropTypes = __webpack_require__(20);
 const ImPropTypes = __webpack_require__(150);
 const { connect } = __webpack_require__(1189);
 const { bindActionCreators } = __webpack_require__(3);
 const { getTabs, getFilterString, getConfig } = __webpack_require__(1490);
 const { getValue } = __webpack_require__(1355);
 const LandingPage = React.createFactory(__webpack_require__(1491));
 
-const LaunchpadApp = React.createClass({
-  displayName: "LaunchpadApp",
-
-  propTypes: {
-    tabs: ImPropTypes.map.isRequired,
-    filterString: PropTypes.string,
-    actions: PropTypes.object,
-    config: PropTypes.object
-  },
+class LaunchpadApp extends Component {
+  static get propTypes() {
+    return {
+      tabs: ImPropTypes.map.isRequired,
+      filterString: PropTypes.string,
+      actions: PropTypes.object,
+      config: PropTypes.object
+    };
+  }
 
   render() {
     const {
       filterString,
       actions: { setValue, filterTabs }, config } = this.props;
 
     return LandingPage({
       tabs: this.props.tabs,
@@ -29522,17 +29557,17 @@ const LaunchpadApp = React.createClass({
       onFilterChange: filterTabs,
       onTabClick: url => {
         window.location = url;
       },
       config,
       setValue
     });
   }
-});
+}
 
 function mapStateToProps(state) {
   return {
     tabs: getTabs(state),
     filterString: getFilterString(state),
     config: getConfig(state)
   };
 }
@@ -29600,17 +29635,19 @@ 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/. */
 
 const React = __webpack_require__(0);
 
 __webpack_require__(1298);
-const { DOM: dom } = React;
+const { Component } = React;
+const PropTypes = __webpack_require__(20);
+const dom = __webpack_require__(1759);
 const ImPropTypes = __webpack_require__(150);
 const configMap = __webpack_require__(1377).sidePanelItems;
 const Tabs = React.createFactory(__webpack_require__(1492));
 const Sidebar = React.createFactory(__webpack_require__(1493));
 const Settings = React.createFactory(__webpack_require__(1496));
 
 const githubUrl = "https://github.com/devtools-html/debugger.html/blob/master";
 
@@ -29620,83 +29657,96 @@ function getTabsByClientType(tabs, clien
 
 function firstTimeMessage(title, urlPart) {
   return dom.div({ className: "footer-note" }, `First time connecting to ${title}? Checkout out the `, dom.a({
     href: `${githubUrl}/docs/getting-setup.md#starting-${urlPart}`,
     target: "_blank"
   }, "docs"), ".");
 }
 
-const LandingPage = React.createClass({
-  displayName: "LandingPage",
-
-  propTypes: {
-    tabs: ImPropTypes.map.isRequired,
-    supportsFirefox: React.PropTypes.bool.isRequired,
-    supportsChrome: React.PropTypes.bool.isRequired,
-    title: React.PropTypes.string.isRequired,
-    filterString: React.PropTypes.string,
-    onFilterChange: React.PropTypes.func.isRequired,
-    onTabClick: React.PropTypes.func.isRequired,
-    config: React.PropTypes.object.isRequired,
-    setValue: React.PropTypes.func.isRequired
-  },
-
-  getInitialState() {
+class LandingPage extends Component {
+  static get propTypes() {
     return {
+      tabs: ImPropTypes.map.isRequired,
+      supportsFirefox: PropTypes.bool.isRequired,
+      supportsChrome: PropTypes.bool.isRequired,
+      title: PropTypes.string.isRequired,
+      filterString: PropTypes.string,
+      onFilterChange: PropTypes.func.isRequired,
+      onTabClick: PropTypes.func.isRequired,
+      config: PropTypes.object.isRequired,
+      setValue: PropTypes.func.isRequired
+    };
+  }
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
       selectedPane: configMap.Firefox.name,
       firefoxConnected: false,
       chromeConnected: false
     };
-  },
+
+    this.onFilterChange = this.onFilterChange.bind(this);
+    this.onSideBarItemClick = this.onSideBarItemClick.bind(this);
+    this.renderLaunchOptions = this.renderLaunchOptions.bind(this);
+    this.renderLaunchButton = this.renderLaunchButton.bind(this);
+    this.renderExperimentalMessage = this.renderExperimentalMessage.bind(this);
+    this.launchBrowser = this.launchBrowser.bind(this);
+    this.renderEmptyPanel = this.renderEmptyPanel.bind(this);
+    this.renderSettings = this.renderSettings.bind(this);
+    this.renderFilter = this.renderFilter.bind(this);
+    this.renderPanel = this.renderPanel.bind(this);
+  }
 
   componentDidUpdate() {
     if (this.refs.filterInput) {
       this.refs.filterInput.focus();
     }
-  },
+  }
 
   onFilterChange(newFilterString) {
     this.props.onFilterChange(newFilterString);
-  },
+  }
 
   onSideBarItemClick(itemTitle) {
     if (itemTitle !== this.state.selectedPane) {
       this.setState({ selectedPane: itemTitle });
     }
-  },
+  }
 
   renderLaunchOptions() {
     const { selectedPane } = this.state;
     const { name, isUnderConstruction } = configMap[selectedPane];
 
     const isConnected = name === configMap.Firefox.name ? this.state.firefoxConnected : this.state.chromeConnected;
     const isNodeSelected = name === configMap.Node.name;
 
     if (isNodeSelected) {
       return dom.div({ className: "launch-action-container" }, dom.h3({}, "Run a node script in the terminal with `--inspect`"), isUnderConstruction ? this.renderExperimentalMessage(name) : null);
     }
 
     const connectedStateText = isNodeSelected ? null : `Please open a tab in ${name}`;
 
     return isConnected ? connectedStateText : this.renderLaunchButton(name, isUnderConstruction);
-  },
+  }
 
   renderLaunchButton(browserName, isUnderConstruction) {
     return dom.div({ className: "launch-action-container" }, dom.button({ onClick: () => this.launchBrowser(browserName) }, `Launch ${browserName}`), isUnderConstruction ? this.renderExperimentalMessage(browserName) : null);
-  },
+  }
 
   renderExperimentalMessage(browserName) {
     const underConstructionMessage = "Debugging is experimental and certain features won't work (i.e, seeing variables, attaching breakpoints)"; // eslint-disable-line max-len
 
     return dom.div({ className: "under-construction" }, dom.div({ className: "under-construction-message" }, dom.p({}, underConstructionMessage), dom.img({ src: "/assets/under_construction.png" }), dom.a({
       className: "github-link",
       target: "_blank"
     }, "Help us make it happen")));
-  },
+  }
 
   launchBrowser(browser) {
     fetch("/launch", {
       body: JSON.stringify({ browser }),
       headers: {
         "Content-Type": "application/json"
       },
       method: "post"
@@ -29704,27 +29754,27 @@ const LandingPage = React.createClass({
       if (browser === configMap.Firefox.name) {
         this.setState({ firefoxConnected: true });
       } else {
         this.setState({ chromeConnected: true });
       }
     }).catch(err => {
       alert(`Error launching ${browser}. ${err.message}`);
     });
-  },
+  }
 
   renderEmptyPanel() {
     return dom.div({ className: "hero" }, this.renderLaunchOptions());
-  },
+  }
 
   renderSettings() {
     const { config, setValue } = this.props;
 
     return dom.div({}, dom.header({}, dom.h1({}, configMap.Settings.name)), Settings({ config, setValue }));
-  },
+  }
 
   renderFilter() {
     const { selectedPane } = this.state;
 
     const { tabs, filterString = "" } = this.props;
 
     const { clientType, paramName } = configMap[selectedPane];
 
@@ -29738,17 +29788,17 @@ const LandingPage = React.createClass({
       type: "search",
       onChange: e => this.onFilterChange(e.target.value),
       onKeyDown: e => {
         if (targets.size === 1 && e.keyCode === 13) {
           this.onTabClick(targets.first(), paramName);
         }
       }
     }));
-  },
+  }
 
   renderPanel() {
     const { onTabClick, tabs } = this.props;
     const { selectedPane } = this.state;
 
     const { name, clientType, paramName } = configMap[selectedPane];
 
     const clientTargets = getTabsByClientType(tabs, clientType);
@@ -29761,17 +29811,17 @@ const LandingPage = React.createClass({
       return this.renderSettings();
     }
 
     if (!tabsDetected) {
       return this.renderEmptyPanel();
     }
 
     return dom.div({}, this.renderFilter(), Tabs({ targets, paramName, onTabClick }));
-  },
+  }
 
   render() {
     const { supportsFirefox, supportsChrome, title } = this.props;
     const { selectedPane } = this.state;
     const { onSideBarItemClick } = this;
 
     const { name, docsUrlPart } = configMap[selectedPane];
 
@@ -29780,17 +29830,17 @@ const LandingPage = React.createClass({
     }, Sidebar({
       supportsFirefox,
       supportsChrome,
       title,
       selectedPane,
       onSideBarItemClick
     }), dom.main({ className: "panel" }, this.renderPanel(), firstTimeMessage(name, docsUrlPart)));
   }
-});
+}
 
 module.exports = LandingPage;
 
 /***/ }),
 /* 1492 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -29798,36 +29848,43 @@ module.exports = LandingPage;
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const React = __webpack_require__(0);
 
 __webpack_require__(1299);
-const { DOM: dom } = React;
+const { Component } = React;
+const dom = __webpack_require__(1759);
+const PropTypes = __webpack_require__(20);
 const classnames = __webpack_require__(175);
 
 function getTabURL(tab, paramName) {
   const tabID = tab.get("id");
-  return `/?${paramName}=${tabID}`;
-}
-
-const Tabs = React.createClass({
-  displayName: "Tabs",
-
-  propTypes: {
-    targets: React.PropTypes.object.isRequired,
-    paramName: React.PropTypes.string.isRequired,
-    onTabClick: React.PropTypes.func.isRequired
-  },
+  return `/?react_perf&${paramName}=${tabID}`;
+}
+
+class Tabs extends Component {
+  static get propTypes() {
+    return {
+      targets: PropTypes.object.isRequired,
+      paramName: PropTypes.string.isRequired,
+      onTabClick: PropTypes.func.isRequired
+    };
+  }
+
+  constructor(props) {
+    super(props);
+    this.onTabClick = this.onTabClick.bind(this);
+  }
 
   onTabClick(tab, paramName) {
     this.props.onTabClick(getTabURL(tab, paramName));
-  },
+  }
 
   render() {
     const { targets, paramName } = this.props;
 
     if (!targets || targets.count() == 0) {
       return dom.div({}, "");
     }
 
@@ -29846,97 +29903,105 @@ const Tabs = React.createClass({
       onClick: () => this.onTabClick(tab, paramName),
       onKeyDown: e => {
         if (e.keyCode === 13) {
           this.onTabClick(tab, paramName);
         }
       }
     }, dom.div({ className: "tab-title" }, tab.get("title")), dom.div({ className: "tab-url" }, tab.get("url"))))));
   }
-
-});
+}
 
 module.exports = Tabs;
 
 /***/ }),
 /* 1493 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const React = __webpack_require__(0);
 __webpack_require__(1300);
-const { DOM: dom } = React;
+const { Component } = React;
+const dom = __webpack_require__(1759);
+const PropTypes = __webpack_require__(20);
 const classnames = __webpack_require__(175);
 const Svg = __webpack_require__(1494);
-const Sidebar = React.createClass({
-  displayName: "Sidebar",
-
-  propTypes: {
-    supportsFirefox: React.PropTypes.bool.isRequired,
-    supportsChrome: React.PropTypes.bool.isRequired,
-    title: React.PropTypes.string.isRequired,
-    selectedPane: React.PropTypes.string.isRequired,
-    onSideBarItemClick: React.PropTypes.func.isRequired
-  },
+
+class Sidebar extends Component {
+  static get propTypes() {
+    return {
+      supportsFirefox: PropTypes.bool.isRequired,
+      supportsChrome: PropTypes.bool.isRequired,
+      title: PropTypes.string.isRequired,
+      selectedPane: PropTypes.string.isRequired,
+      onSideBarItemClick: PropTypes.func.isRequired
+    };
+  }
+
+  constructor(props) {
+    super(props);
+    this.renderTitle = this.renderTitle.bind(this);
+    this.renderItem = this.renderItem.bind(this);
+  }
 
   renderTitle(title) {
     return dom.div({ className: "title-wrapper" }, dom.h1({}, title), dom.div({ className: "launchpad-container" }, Svg({ name: "rocket" }), dom.h2({ className: "launchpad-container-title" }, "Launchpad")));
-  },
+  }
 
   renderItem(title) {
     return dom.li({
       className: classnames({
         selected: title == this.props.selectedPane
       }),
       key: title,
       tabIndex: 0,
       role: "button",
       onClick: () => this.props.onSideBarItemClick(title),
       onKeyDown: e => {
         if (e.keyCode === 13) {
           this.props.onSideBarItemClick(title);
         }
       }
     }, dom.a({}, title));
-  },
+  }
 
   render() {
     let connections = [];
 
     if (this.props.supportsFirefox) {
       connections.push("Firefox");
     }
 
     if (this.props.supportsChrome) {
       connections.push("Chrome", "Node");
     }
 
     return dom.aside({
       className: "sidebar"
     }, this.renderTitle(this.props.title), dom.ul({}, connections.map(title => this.renderItem(title)), this.renderItem("Settings")));
   }
-});
+}
 
 module.exports = Sidebar;
 
 /***/ }),
 /* 1494 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
-const InlineSVG = __webpack_require__(1495);
+const { default: InlineSVG } = __webpack_require__(1769);
 const { isDevelopment } = __webpack_require__(1355);
 
 const svg = {
   rocket: __webpack_require__(1126)
 };
 
 function Svg({ name, className, onClick, "aria-label": ariaLabel }) {
   className = `${name} ${className || ""}`;
@@ -29951,242 +30016,48 @@ function Svg({ name, className, onClick,
   return React.createElement(InlineSVG, props);
 }
 
 Svg.displayName = "Svg";
 
 module.exports = Svg;
 
 /***/ }),
-/* 1495 */
-/***/ (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 _createClass = function () {
-    function defineProperties(target, props) {
-        for (var i = 0; i < props.length; i++) {
-            var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ('value' in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
-        }
-    }return function (Constructor, protoProps, staticProps) {
-        if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
-    };
-}();
-
-var _get = function get(_x, _x2, _x3) {
-    var _again = true;_function: while (_again) {
-        var object = _x,
-            property = _x2,
-            receiver = _x3;_again = false;if (object === null) object = Function.prototype;var desc = Object.getOwnPropertyDescriptor(object, property);if (desc === undefined) {
-            var parent = Object.getPrototypeOf(object);if (parent === null) {
-                return undefined;
-            } else {
-                _x = parent;_x2 = property;_x3 = receiver;_again = true;desc = parent = undefined;continue _function;
-            }
-        } else if ('value' in desc) {
-            return desc.value;
-        } else {
-            var getter = desc.get;if (getter === undefined) {
-                return undefined;
-            }return getter.call(receiver);
-        }
-    }
-};
-
-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 _classCallCheck(instance, Constructor) {
-    if (!(instance instanceof Constructor)) {
-        throw new TypeError('Cannot call a class as a function');
-    }
-}
-
-function _inherits(subClass, superClass) {
-    if (typeof superClass !== 'function' && superClass !== null) {
-        throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
-    }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
-}
-
-var _react = __webpack_require__(0);
-
-var _react2 = _interopRequireDefault(_react);
-
-var DOMParser = typeof window !== 'undefined' && window.DOMParser;
-var process = process || {};
-process.env = process.env || {};
-var parserAvailable = typeof DOMParser !== 'undefined' && DOMParser.prototype != null && DOMParser.prototype.parseFromString != null;
-
-if ("production" !== process.env.NODE_ENV && !parserAvailable) {
-    console.info('<InlineSVG />: `raw` prop works only when `window.DOMParser` exists.');
-}
-
-function isParsable(src) {
-    // kinda naive but meh, ain't gonna use full-blown parser for this
-    return parserAvailable && typeof src === 'string' && src.trim().substr(0, 4) === '<svg';
-}
-
-// parse SVG string using `DOMParser`
-function parseFromSVGString(src) {
-    var parser = new DOMParser();
-    return parser.parseFromString(src, "image/svg+xml");
-}
-
-// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
-function switchSVGAttrToReactProp(propName) {
-    switch (propName) {
-        case 'class':
-            return 'className';
-        default:
-            return propName;
-    }
-}
-
-var InlineSVG = function (_React$Component) {
-    _inherits(InlineSVG, _React$Component);
-
-    _createClass(InlineSVG, null, [{
-        key: 'defaultProps',
-        value: {
-            element: 'i',
-            raw: false,
-            src: ''
-        },
-        enumerable: true
-    }, {
-        key: 'propTypes',
-        value: {
-            src: _react2['default'].PropTypes.string.isRequired,
-            element: _react2['default'].PropTypes.string,
-            raw: _react2['default'].PropTypes.bool
-        },
-        enumerable: true
-    }]);
-
-    function InlineSVG(props) {
-        _classCallCheck(this, InlineSVG);
-
-        _get(Object.getPrototypeOf(InlineSVG.prototype), 'constructor', this).call(this, props);
-        this._extractSVGProps = this._extractSVGProps.bind(this);
-    }
-
-    // Serialize `Attr` objects in `NamedNodeMap`
-
-    _createClass(InlineSVG, [{
-        key: '_serializeAttrs',
-        value: function _serializeAttrs(map) {
-            var ret = {};
-            var prop = undefined;
-            for (var i = 0; i < map.length; i++) {
-                prop = switchSVGAttrToReactProp(map[i].name);
-                ret[prop] = map[i].value;
-            }
-            return ret;
-        }
-
-        // get <svg /> element props
-    }, {
-        key: '_extractSVGProps',
-        value: function _extractSVGProps(src) {
-            var map = parseFromSVGString(src).documentElement.attributes;
-            return map.length > 0 ? this._serializeAttrs(map) : null;
-        }
-
-        // get content inside <svg> element.
-    }, {
-        key: '_stripSVG',
-        value: function _stripSVG(src) {
-            return parseFromSVGString(src).documentElement.innerHTML;
-        }
-    }, {
-        key: 'componentWillReceiveProps',
-        value: function componentWillReceiveProps(_ref) {
-            var children = _ref.children;
-
-            if ("production" !== process.env.NODE_ENV && children != null) {
-                console.info('<InlineSVG />: `children` prop will be ignored.');
-            }
-        }
-    }, {
-        key: 'render',
-        value: function render() {
-            var Element = undefined,
-                __html = undefined,
-                svgProps = undefined;
-            var _props = this.props;
-            var element = _props.element;
-            var raw = _props.raw;
-            var src = _props.src;
-
-            var otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
-
-            if (raw === true && isParsable(src)) {
-                Element = 'svg';
-                svgProps = this._extractSVGProps(src);
-                __html = this._stripSVG(src);
-            }
-            __html = __html || src;
-            Element = Element || element;
-            svgProps = svgProps || {};
-
-            return _react2['default'].createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
-                dangerouslySetInnerHTML: { __html: __html } }));
-        }
-    }]);
-
-    return InlineSVG;
-}(_react2['default'].Component);
-
-exports['default'] = InlineSVG;
-module.exports = exports['default'];
-
-/***/ }),
+/* 1495 */,
 /* 1496 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const React = __webpack_require__(0);
-const { DOM: dom } = React;
+const { Component } = React;
+const dom = __webpack_require__(1759);
+const PropTypes = __webpack_require__(20);
 const { showMenu, buildMenu } = __webpack_require__(1413);
 
-const Settings = React.createClass({
-  displayName: "Settings",
-
-  propTypes: {
-    config: React.PropTypes.object.isRequired,
-    setValue: React.PropTypes.func.isRequired
-  },
+class Settings extends Component {
+  static get propTypes() {
+    return {
+      config: PropTypes.object.isRequired,
+      setValue: PropTypes.func.isRequired
+    };
+  }
+
+  constructor(props) {
+    super(props);
+    this.onConfigContextMenu = this.onConfigContextMenu.bind(this);
+    this.onInputHandler = this.onInputHandler.bind(this);
+    this.renderConfig = this.renderConfig.bind(this);
+    this.renderFeatures = this.renderFeatures.bind(this);
+  }
 
   onConfigContextMenu(event, key) {
     event.preventDefault();
 
     const { setValue, config } = this.props;
 
     const setConfig = (path, value) => {
       setValue(path, value);
@@ -30227,22 +30098,22 @@ const Settings = React.createClass({
       click: () => setConfig(key, "firebug")
     };
 
     const items = {
       "dir": [{ item: ltrMenuItem }, { item: rtlMenuItem }],
       "theme": [{ item: lightMenuItem }, { item: darkMenuItem }, { item: firebugMenuItem }]
     };
     showMenu(event, buildMenu(items[key]));
-  },
+  }
 
   onInputHandler(e, path) {
     const { setValue } = this.props;
     setValue(path, e.target.checked);
-  },
+  }
 
   renderConfig(config) {
     const configs = [{ name: "dir", label: "direction" }, { name: "theme", label: "theme"
       // Hiding hotReloading option for now. See Issue #242
       // { name: "hotReloading", label: "hot reloading", bool: true }
     }];
 
     return dom.ul({ className: "tab-list" }, configs.map(c => {
@@ -30250,35 +30121,35 @@ const Settings = React.createClass({
         type: "checkbox",
         defaultChecked: config[c.name],
         onChange: e => this.onInputHandler(e, c.name)
       }, null) : dom.div({
         className: "tab-value",
         onClick: e => this.onConfigContextMenu(e, c.name)
       }, config[c.name]));
     }));
-  },
+  }
 
   renderFeatures(features) {
     return dom.ul({ className: "tab-list" }, Object.keys(features).map(key => dom.li({
       className: "tab tab-sides",
       key
     }, dom.div({ className: "tab-title" }, typeof features[key] == "object" ? features[key].label : key), dom.div({ className: "tab-value" }, dom.input({
       type: "checkbox",
       defaultChecked: features[key].enabled,
       onChange: e => this.onInputHandler(e, `features.${key}.enabled`)
     })))));
-  },
+  }
 
   render() {
     const { config } = this.props;
 
     return dom.div({ className: "tab-group" }, dom.h3({}, "Configurations"), this.renderConfig(config), config.features ? (dom.h3({}, "Features"), this.renderFeatures(config.features)) : null);
   }
-});
+}
 
 module.exports = Settings;
 
 /***/ }),
 /* 1497 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -31061,66 +30932,17 @@ function findBreakpointAtLocation(breakp
 function getBreakpointAtLocation(state, location) {
   const selectedSource = (0, _sources.getSelectedSource)(state);
   const breakpoints = getBreakpointsForSource(state, selectedSource);
 
   return findBreakpointAtLocation(breakpoints, selectedSource, location);
 }
 
 /***/ }),
-/* 1504 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-exports.default = getInScopeLines;
-
-var _ast = __webpack_require__(1383);
-
-var _sources = __webpack_require__(1369);
-
-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;
-  }
-
-  const linesOutOfScope = getOutOfScopeLines(outOfScopeLocations, source.toJS());
-
-  const sourceNumLines = (0, _source.getSourceLineCount)(source.toJS());
-  const sourceLines = (0, _lodash.range)(1, sourceNumLines + 1);
-
-  if (!linesOutOfScope) {
-    return sourceLines;
-  }
-
-  return (0, _lodash.without)(sourceLines, ...linesOutOfScope);
-}
-
-/***/ }),
+/* 1504 */,
 /* 1505 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -31153,23 +30975,27 @@ function isSelectedFrameVisible(state) {
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.clientEvents = exports.setupEvents = undefined;
 
+var _lodash = __webpack_require__(2);
+
 var _create = __webpack_require__(1428);
 
 var _devtoolsConfig = __webpack_require__(1355);
 
-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/>. */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 CALL_STACK_PAGE_SIZE = 1000;
 
 let threadClient;
 let actions;
 let supportsWasm;
 
 function setupEvents(dependencies) {
   threadClient = dependencies.threadClient;
   actions = dependencies.actions;
@@ -31191,26 +31017,34 @@ async function paused(_, packet) {
     return;
   }
 
   // Eagerly fetch the frames
   const response = await threadClient.getFrames(0, CALL_STACK_PAGE_SIZE);
 
   if (why.type != "alreadyPaused") {
     const pause = (0, _create.createPause)(packet, response);
+    newSources.flush();
     actions.paused(pause);
   }
 }
 
 function resumed(_, packet) {
   actions.resumed(packet);
 }
 
+let pendingSources = [];
+const newSources = (0, _lodash.throttle)(() => {
+  actions.newSources(pendingSources.map(source => (0, _create.createSource)(source, { supportsWasm })));
+  pendingSources = [];
+}, 100);
+
 function newSource(_, { source }) {
-  actions.newSource((0, _create.createSource)(source, { supportsWasm }));
+  pendingSources.push(source);
+  newSources();
 
   if ((0, _devtoolsConfig.isEnabled)("eventListeners")) {
     actions.fetchEventListeners();
   }
 }
 
 const clientEvents = {
   paused,
@@ -33678,28 +33512,30 @@ class ProjectSearch extends _react.Compo
   isProjectSearchEnabled() {
     return this.props.activeSearch === "project";
   }
 
   renderTextSearch() {
     const {
       sources,
       results,
+      status,
       searchSources,
-      closeActiveSearch,
-      selectSource,
+      closeProjectSearch,
+      selectLocation,
       textSearchQuery
     } = this.props;
 
     return _react2.default.createElement(_TextSearch2.default, {
       sources: sources,
       results: results.toJS(),
+      status: status,
       searchSources: searchSources,
-      closeActiveSearch: closeActiveSearch,
-      selectSource: selectSource,
+      closeProjectSearch: closeProjectSearch,
+      selectLocation: selectLocation,
       query: textSearchQuery
     });
   }
 
   render() {
     if (!this.isProjectSearchEnabled()) {
       return null;
     }
@@ -33713,43 +33549,49 @@ class ProjectSearch extends _react.Compo
 }
 
 ProjectSearch.propTypes = {
   sources: _propTypes2.default.object.isRequired,
   results: _propTypes2.default.object,
   textSearchQuery: _propTypes2.default.string,
   setActiveSearch: _propTypes2.default.func.isRequired,
   closeActiveSearch: _propTypes2.default.func.isRequired,
+  closeProjectSearch: _propTypes2.default.func.isRequired,
   searchSources: _propTypes2.default.func,
   activeSearch: _propTypes2.default.string,
-  selectSource: _propTypes2.default.func.isRequired
+  selectLocation: _propTypes2.default.func.isRequired
 };
 
 ProjectSearch.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
 exports.default = (0, _reactRedux.connect)(state => ({
   sources: (0, _selectors.getSources)(state),
   activeSearch: (0, _selectors.getActiveSearch)(state),
   results: (0, _selectors.getTextSearchResults)(state),
-  textSearchQuery: (0, _selectors.getTextSearchQuery)(state)
+  textSearchQuery: (0, _selectors.getTextSearchQuery)(state),
+  status: (0, _selectors.getTextSearchStatus)(state)
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(ProjectSearch);
 
 /***/ }),
 /* 1539 */
 /***/ (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/>. */
+
 var _propTypes = __webpack_require__(20);
 
 var _propTypes2 = _interopRequireDefault(_propTypes);
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
@@ -33770,16 +33612,18 @@ var _SearchInput = __webpack_require__(1
 var _SearchInput2 = _interopRequireDefault(_SearchInput);
 
 __webpack_require__(1314);
 
 var _sourcesTree = __webpack_require__(1442);
 
 var _highlight = __webpack_require__(1547);
 
+var _projectTextSearch = __webpack_require__(1424);
+
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 class TextSearch extends _react.Component {
   constructor(props) {
     super(props);
     this.state = {
       inputValue: this.props.query || ""
     };
@@ -33799,18 +33643,17 @@ class TextSearch extends _react.Componen
   }
 
   componentWillUnmount() {
     const shortcuts = this.context.shortcuts;
     shortcuts.off("Enter", this.onEnterPress);
   }
 
   selectMatchItem(matchItem) {
-    const { line, column } = matchItem;
-    this.props.selectSource(matchItem.sourceId, { location: { line, column } });
+    this.props.selectLocation(_extends({}, matchItem));
   }
 
   getResults() {
     const { results } = this.props;
     return results.filter(result => result.filepath && result.matches.length > 0);
   }
 
   getResultCount() {
@@ -33899,35 +33742,42 @@ class TextSearch extends _react.Componen
 
   renderMatchValue(lineMatch) {
     return (0, _highlight.highlightMatches)(lineMatch);
   }
 
   renderResults() {
     const results = this.getResults().filter(result => result.matches.length > 0);
 
+    const { status } = this.props;
+
     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);
     };
-
-    if (results.length) {
+    if (results.length && status === _projectTextSearch.statusType.done) {
       return _react2.default.createElement(_ManagedTree2.default, {
         getRoots: () => results,
         getChildren: file => file.matches || [],
         itemHeight: 24,
         autoExpand: 1,
         autoExpandDepth: 1,
         getParent: item => null,
         getPath: getFilePath,
         renderItem: renderItem
       });
+    } else if (status === _projectTextSearch.statusType.fetching) {
+      return _react2.default.createElement(
+        "div",
+        { className: "no-result-msg absolute-center" },
+        "Loading..."
+      );
     } else if (this.props.query && !results.length) {
       return _react2.default.createElement(
         "div",
         { className: "no-result-msg absolute-center" },
         L10N.getStr("projectTextSearch.noResults")
       );
     }
   }
@@ -33940,17 +33790,17 @@ class TextSearch extends _react.Componen
       count: resultCount,
       placeholder: L10N.getStr("projectTextSearch.placeholder"),
       size: "big",
       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,
+      handleClose: this.props.closeProjectSearch,
       ref: "searchInput"
     });
   }
 
   render() {
     const { searchBottomBar } = this.props;
     return _react2.default.createElement(
       "div",
@@ -33961,30 +33811,17 @@ class TextSearch extends _react.Componen
         this.renderInput(),
         searchBottomBar
       ),
       this.renderResults()
     );
   }
 }
 
-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
-};
-
+exports.default = TextSearch;
 TextSearch.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
 /***/ }),
 /* 1540 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -34005,16 +33842,17 @@ const svg = {
   "column-breakpoint": __webpack_require__(998),
   "case-match": __webpack_require__(351),
   close: __webpack_require__(352),
   choo: __webpack_require__(1290),
   dojo: __webpack_require__(806),
   domain: __webpack_require__(353),
   file: __webpack_require__(354),
   folder: __webpack_require__(355),
+  function: __webpack_require__(1777),
   globe: __webpack_require__(356),
   jquery: __webpack_require__(999),
   underscore: __webpack_require__(1117),
   lodash: __webpack_require__(1118),
   ember: __webpack_require__(1119),
   vuejs: __webpack_require__(1174),
   "magnifying-glass": __webpack_require__(357),
   "arrow-up": __webpack_require__(919),
@@ -35078,27 +34916,27 @@ class PrimaryPanes extends _react.Compon
 
     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", {
+        className: (0, _classnames2.default)("tab sources-tab", {
           active: this.props.selectedTab === "sources"
         }),
         onClick: () => this.showPane("sources"),
         key: "sources-tab"
       },
       sources
     ), _react2.default.createElement(
       "div",
       {
-        className: (0, _classnames2.default)("tab", {
+        className: (0, _classnames2.default)("tab outline-tab", {
           active: this.props.selectedTab === "outline"
         }),
         onClick: () => this.showPane("outline"),
         key: "outline-tab"
       },
       outline
     )];
   }
@@ -35123,26 +34961,26 @@ class PrimaryPanes extends _react.Compon
         "span",
         { className: "sources-header-info", dir: "ltr", onClick: onClick },
         L10N.getFormatStr("sources.search", (0, _text.formatKeyShortcut)(L10N.getStr("sources.search.key2")))
       );
     }
   }
 
   renderOutline() {
-    const { selectSource } = this.props;
-
-    const outlineComp = (0, _devtoolsConfig.isEnabled)("outline") ? _react2.default.createElement(_Outline2.default, { selectSource: selectSource }) : null;
+    const { selectLocation } = this.props;
+
+    const outlineComp = (0, _devtoolsConfig.isEnabled)("outline") ? _react2.default.createElement(_Outline2.default, { selectLocation: selectLocation }) : null;
 
     return outlineComp;
   }
 
   renderSources() {
-    const { sources, selectSource } = this.props;
-    return _react2.default.createElement(_SourcesTree2.default, { sources: sources, selectSource: selectSource });
+    const { sources, selectLocation } = this.props;
+    return _react2.default.createElement(_SourcesTree2.default, { sources: sources, selectLocation: selectLocation });
   }
 
   render() {
     const { selectedTab } = this.props;
 
     return _react2.default.createElement(
       "div",
       { className: "sources-panel" },
@@ -35181,39 +35019,39 @@ var _redux = __webpack_require__(3);
 var _reactRedux = __webpack_require__(1189);
 
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(1352);
 
+var _Svg = __webpack_require__(1359);
+
+var _Svg2 = _interopRequireDefault(_Svg);
+
 __webpack_require__(1319);
 
 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;
+    const { selectedSource, selectLocation } = this.props;
     if (!selectedSource) {
       return;
     }
     const selectedSourceId = selectedSource.get("id");
     const startLine = location.start.line;
-    selectSource(selectedSourceId, { line: startLine });
+    selectLocation({ sourceId: selectedSourceId, line: startLine });
   }
 
   renderPlaceholder() {
     return _react2.default.createElement(
       "div",
       { className: "outline-pane-info" },
       L10N.getStr("outline.noFunctions")
     );
@@ -35224,16 +35062,17 @@ class Outline extends _react.Component {
 
     return _react2.default.createElement(
       "li",
       {
         key: `${name}:${location.start.line}:${location.start.column}`,
         className: "outline-list__element",
         onClick: () => this.selectItem(location)
       },
+      _react2.default.createElement(_Svg2.default, { name: "function" }),
       _react2.default.createElement(_PreviewFunction2.default, { func: { name, parameterNames } })
     );
   }
 
   renderClassFunctions(functions) {
     const classFunctions = functions.filter(func => func.name != "anonymous" && !!func.klass);
 
     if (classFunctions.length == 0) {
@@ -35280,17 +35119,20 @@ class Outline extends _react.Component {
     return _react2.default.createElement(
       "div",
       { className: "outline" },
       symbolsToDisplay.length > 0 ? this.renderFunctions(symbols.functions) : this.renderPlaceholder()
     );
   }
 }
 
-exports.Outline = Outline;
+exports.Outline = Outline; /* This Source Code Form is subject to the terms of the Mozilla Public
+                            * License, v. 2.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 {
     symbols: (0, _selectors.getSymbols)(state, selectedSource && selectedSource.toJS()),
     selectedSource
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Outline);
 
@@ -35439,33 +35281,37 @@ class SourcesTree extends _react.Compone
   }
 
   focusItem(item) {
     this.setState({ focusedItem: item });
   }
 
   selectItem(item) {
     if (!(0, _sourcesTree.nodeHasChildren)(item)) {
-      this.props.selectSource(item.contents.get("id"));
+      this.props.selectLocation({ sourceId: item.contents.get("id") });
     }
   }
 
   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 (item.path === "/Angular") {
+      return _react2.default.createElement(_Svg2.default, { name: "angular" });
+    }
+
     if (depth === 0) {
       return _react2.default.createElement("img", {
         className: (0, _classnames2.default)("domain", {
           debuggee: debuggeeUrl && debuggeeUrl.includes(item.name)
         })
       });
     }
 
@@ -35641,17 +35487,17 @@ const mapStateToProps = state => {
     expanded: (0, _selectors.getExpandedState)(state),
     projectRoot: (0, _selectors.getProjectDirectoryRoot)(state),
     sources: (0, _selectors.getSources)(state)
   };
 };
 
 const actionCreators = {
   setExpandedState: _sourceTree.setExpandedState,
-  selectSource: _sources.selectSource
+  selectLocation: _sources.selectLocation
 };
 
 exports.default = (0, _reactRedux.connect)(mapStateToProps, actionCreators)(SourcesTree);
 
 /***/ }),
 /* 1554 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -35767,27 +35613,30 @@ const cssVars = {
 
 class Editor extends _react.PureComponent {
 
   constructor() {
     super();
 
     this.onToggleBreakpoint = (key, e) => {
       e.preventDefault();
-      const { selectedSource } = this.props;
+      const { selectedSource, conditionalPanelLine } = this.props;
 
       if (!selectedSource) {
         return;
       }
 
       const line = this.getCurrentLine();
 
       if (e.shiftKey) {
         this.toggleConditionalPanel(line);
+      } else if (!conditionalPanelLine) {
+        this.props.toggleBreakpoint(line);
       } else {
+        this.toggleConditionalPanel(line);
         this.props.toggleBreakpoint(line);
       }
     };
 
     this.onEscape = (key, e) => {
       if (!this.state.editor) {
         return;
       }
@@ -36888,18 +36737,16 @@ exports.default = (0, _reactRedux.connec
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
-var _redux = __webpack_require__(3);
-
 var _reactRedux = __webpack_require__(1189);
 
 var _lodash = __webpack_require__(2);
 
 var _Popup = __webpack_require__(1559);
 
 var _Popup2 = _interopRequireDefault(_Popup);
 
@@ -36908,20 +36755,16 @@ 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);
@@ -36997,24 +36840,38 @@ class Preview extends _react.PureCompone
       editor: this.props.editor,
       range: editorRange,
       expression: expression,
       popoverPos: cursorPos,
       extra: extra,
       onClose: e => this.onClose(e)
     });
   }
-}
+} /* This Source Code Form is subject to the terms of the Mozilla Public
+   * License, v. 2.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 {
+  addExpression,
+  loadObjectProperties,
+  setPreview,
+  clearPreview
+} = _actions2.default;
 
 exports.default = (0, _reactRedux.connect)(state => ({
   preview: (0, _selectors.getPreview)(state),
   selectedSource: (0, _selectors.getSelectedSource)(state),
   linesInScope: (0, _selectors.getInScopeLines)(state),
   selectedFrameVisible: (0, _selectors.isSelectedFrameVisible)(state)
-}), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Preview);
+}), {
+  addExpression,
+  loadObjectProperties,
+  setPreview,
+  clearPreview
+})(Preview);
 
 /***/ }),
 /* 1559 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -37024,18 +36881,16 @@ Object.defineProperty(exports, "__esModu
 exports.Popup = undefined;
 
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _reactRedux = __webpack_require__(1189);
 
-var _redux = __webpack_require__(3);
-
 var _devtoolsConfig = __webpack_require__(1355);
 
 var _devtoolsReps = __webpack_require__(1408);
 
 var _devtoolsReps2 = _interopRequireDefault(_devtoolsReps);
 
 var _actions = __webpack_require__(1354);
 
@@ -37052,20 +36907,21 @@ 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; /* This Source Code Form is subject to the terms of the Mozilla Public
-                                                                               * License, v. 2.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 { REPS: { Rep }, MODE, ObjectInspectorUtils } = _devtoolsReps2.default;
 const { ObjectInspector } = _devtoolsReps2.default;
 const { getChildren } = ObjectInspectorUtils;
 
 function isReactComponent(roots) {
   return roots.some(root => root.name === "_reactInternalInstance");
 }
 
 class Popup extends _react.Component {
@@ -37260,19 +37116,33 @@ class Popup extends _react.Component {
       _Popover2.default,
       { targetPosition: popoverPos, onMouseLeave: onClose, type: type },
       this.renderPreview(expression, value, extra)
     );
   }
 }
 
 exports.Popup = Popup;
+const {
+  addExpression,
+  selectSourceURL,
+  selectLocation,
+  loadObjectProperties,
+  openLink
+} = _actions2.default;
+
 exports.default = (0, _reactRedux.connect)(state => ({
   loadedObjects: (0, _selectors.getLoadedObjects)(state)
-}), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Popup);
+}), {
+  addExpression,
+  selectSourceURL,
+  selectLocation,
+  loadObjectProperties,
+  openLink
+})(Popup);
 
 /***/ }),
 /* 1560 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -39773,17 +39643,16 @@ class Popover extends _react.Component {
       return;
     }
 
     onMouseLeave();
   }
 
   renderPopover() {
     const { top, left, orientation, targetMid } = this.state;
-
     const arrow = this.getPopoverArrow(orientation, targetMid);
 
     return _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("popover", { up: orientation === "up" }),
         onMouseLeave: this.onMouseLeave,
         style: { top, left }
@@ -39874,30 +39743,24 @@ exports.default = BracketArrow;
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _reactRedux = __webpack_require__(1189);
 
-var _redux = __webpack_require__(3);
-
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _Breakpoint = __webpack_require__(1589);
 
 var _Breakpoint2 = _interopRequireDefault(_Breakpoint);
 
-var _actions = __webpack_require__(1354);
-
-var _actions2 = _interopRequireDefault(_actions);
-
 var _selectors = __webpack_require__(1352);
 
 var _visibleBreakpoints = __webpack_require__(1427);
 
 var _visibleBreakpoints2 = _interopRequireDefault(_visibleBreakpoints);
 
 var _breakpoint = __webpack_require__(1364);
 
@@ -39936,17 +39799,17 @@ class Breakpoints extends _react.Compone
   }
 } /* This Source Code Form is subject to the terms of the Mozilla Public
    * License, v. 2.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)
-}), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Breakpoints);
+}))(Breakpoints);
 
 /***/ }),
 /* 1589 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -40153,18 +40016,16 @@ var _extends = Object.assign || function
                                                                                                                                                                                                                                                                    * 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);
-
 var _prefs = __webpack_require__(226);
 
 var _lodash = __webpack_require__(2);
 
 var _CallSite = __webpack_require__(1592);
 
 var _CallSite2 = _interopRequireDefault(_CallSite);
 
@@ -40342,32 +40203,37 @@ function getCallSites(symbols, breakpoin
     if (breakpointId) {
       return bpLocationMap[breakpointId];
     }
   }
 
   return callSites.filter(({ location }) => location.start.line === location.end.line).map(callSite => _extends({}, callSite, { breakpoint: findBreakpoint(callSite) }));
 }
 
+const { addBreakpoint, removeBreakpoint } = _actions2.default;
+
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedLocation = (0, _selectors.getSelectedLocation)(state);
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   const sourceId = selectedLocation && selectedLocation.sourceId;
   const source = selectedSource && selectedSource.toJS();
 
   const symbols = (0, _selectors.getSymbols)(state, source);
   const breakpoints = (0, _selectors.getBreakpointsForSource)(state, sourceId);
 
   return {
     selectedLocation,
     selectedSource,
     callSites: getCallSites(symbols, breakpoints),
     breakpoints: breakpoints
   };
-}, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(CallSites);
+}, {
+  addBreakpoint,
+  removeBreakpoint
+})(CallSites);
 
 /***/ }),
 /* 1592 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -40482,40 +40348,40 @@ var _selectors = __webpack_require__(135
 
 class DebugLine extends _react.Component {
   constructor() {
     super();
     this.state = { debugExpression: { clear: () => {} } };
   }
 
   componentDidMount() {
-    this.setDebugLine(this.props.pauseInfo, this.props.selectedFrame, this.props.selectedLocation, this.props.editor);
+    this.setDebugLine(this.props.pauseInfo, this.props.selectedFrame, this.props.editor);
   }
 
   componentWillReceiveProps(nextProps) {
     this.clearDebugLine(this.props.selectedFrame, this.props.editor);
-    this.setDebugLine(nextProps.pauseInfo, nextProps.selectedFrame, nextProps.selectedLocation, nextProps.editor);
+    this.setDebugLine(nextProps.pauseInfo, nextProps.selectedFrame, nextProps.editor);
   }
 
   componentWillUnmount() {
     this.clearDebugLine(this.props.selectedFrame, this.props.editor);
   }
 
-  setDebugLine(pauseInfo, selectedFrame, selectedLocation, editor) {
+  setDebugLine(pauseInfo, selectedFrame, editor) {
     if (!selectedFrame) {
       return;
     }
 
-    const { location, location: { sourceId } } = selectedFrame;
+    const sourceId = selectedFrame.location.sourceId;
     const doc = (0, _sourceDocuments.getDocument)(sourceId);
     if (!doc) {
       return;
     }
 
-    const { line, column } = (0, _editor.toEditorPosition)(sourceId, location);
+    const { line, column } = (0, _editor.toEditorPosition)(sourceId, selectedFrame.location);
 
     // make sure the line is visible
     if (editor && editor.alignLine) {
       editor.alignLine(line);
     }
 
     const { markTextClass, lineClass } = this.getTextClasses(pauseInfo);
     doc.addLineClass(line, "line", lineClass);
@@ -40562,50 +40428,41 @@ class DebugLine extends _react.Component
   }
 }
 
 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),
+  selectedFrame: (0, _selectors.getVisibleSelectedFrame)(state),
   pauseInfo: (0, _selectors.getPause)(state)
 }))(DebugLine);
 
 /***/ }),
 /* 1594 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _reactRedux = __webpack_require__(1189);
 
-var _redux = __webpack_require__(3);
-
-var _react = __webpack_require__(0);
-
-var _actions = __webpack_require__(1354);
-
-var _actions2 = _interopRequireDefault(_actions);
+var _react = __webpack_require__(0);
 
 var _selectors = __webpack_require__(1352);
 
 var _editor = __webpack_require__(1358);
 
 __webpack_require__(1330);
 
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
 class EmptyLines extends _react.Component {
 
   componentDidMount() {
     this.disableEmptyLines();
   }
 
   componentDidUpdate() {
     this.disableEmptyLines();
@@ -40647,17 +40504,17 @@ class EmptyLines extends _react.Componen
    * 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);
+})(EmptyLines);
 
 /***/ }),
 /* 1595 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -40833,28 +40690,26 @@ exports.default = (0, _reactRedux.connec
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 
 var _react = __webpack_require__(0);
 
-var _devtoolsContextmenu = __webpack_require__(1413);
+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);
 
@@ -40874,17 +40729,18 @@ function getMenuItems(event, {
   selectedSource,
   showSource,
   onGutterContextMenu,
   jumpToMappedLocation,
   toggleBlackBox,
   addExpression,
   getFunctionText,
   getFunctionLocation,
-  flashLineRange
+  flashLineRange,
+  hasPrettyPrint
 }) {
   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");
@@ -40914,23 +40770,26 @@ function getMenuItems(event, {
   const { line } = editor.codeMirror.coordsChar({
     left: event.clientX,
     top: event.clientY
   });
 
   const sourceLocation = (0, _editor.getSourceLocationFromMouseEvent)(editor, selectedLocation, event);
 
   const isOriginal = (0, _devtoolsSourceMap.isOriginalId)(selectedLocation.sourceId);
-  const hasSourceMap = selectedSource.get("sourceMapURL");
+  const hasSourceMap = !!selectedSource.get("sourceMapURL");
   const isPrettyPrinted = (0, _source.isPretty)(selectedSource.toJS());
 
+  const isPrettified = isPrettyPrinted || hasPrettyPrint;
+  const isMapped = isOriginal || hasSourceMap;
+
   const jumpLabel = {
     id: "node-menu-jump",
     accesskey: L10N.getStr("editor.jumpToMappedLocation1.accesskey"),
-    disabled: _devtoolsSourceMap.isGeneratedId && !hasSourceMap,
+    disabled: !isMapped && !isPrettified,
     label: L10N.getFormatStr("editor.jumpToMappedLocation1", isOriginal ? L10N.getStr("generated") : L10N.getStr("original")),
     click: () => jumpToMappedLocation(sourceLocation)
   };
 
   const watchExpressionLabel = {
     id: "node-menu-add-watch-expression",
     accesskey: L10N.getStr("expressions.accesskey"),
     label: L10N.getStr("expressions.label"),
@@ -40997,37 +40856,54 @@ class EditorMenu extends _react.PureComp
     this.props.setContextMenu("", null);
     return this.showMenu(nextProps);
   }
 
   showMenu(nextProps) {
     const { contextMenu } = nextProps,
           options = _objectWithoutProperties(nextProps, ["contextMenu"]);
     const { event } = contextMenu;
-    (0, _devtoolsContextmenu.showMenu)(event, getMenuItems(event, options));
+    (0, _devtoolsLaunchpad.showMenu)(event, getMenuItems(event, options));
   }
 
   render() {
     return null;
   }
 }
 
+const {
+  addExpression,
+  jumpToMappedLocation,
+  toggleBlackBox,
+  setContextMenu,
+  showSource,
+  flashLineRange
+} = _actions2.default;
+
 exports.default = (0, _reactRedux.connect)(state => {
   const selectedSource = (0, _selectors.getSelectedSource)(state);
   return {
     selectedLocation: (0, _selectors.getSelectedLocation)(state),
     selectedSource,
+    hasPrettyPrint: !!(0, _selectors.getPrettySource)(state, selectedSource.get("id")),
     contextMenu: (0, _selectors.getContextMenu)(state),
     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);
+}, {
+  addExpression,
+  jumpToMappedLocation,
+  toggleBlackBox,
+  setContextMenu,
+  showSource,
+  flashLineRange
+})(EditorMenu);
 
 /***/ }),
 /* 1597 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -41076,18 +40952,16 @@ exports.ConditionalPanel = undefined;
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _reactDom = __webpack_require__(4);
 
 var _reactDom2 = _interopRequireDefault(_reactDom);
 
-var _redux = __webpack_require__(3);
-
 var _reactRedux = __webpack_require__(1189);
 
 var _Close = __webpack_require__(1374);
 
 var _Close2 = _interopRequireDefault(_Close);
 
 __webpack_require__(1331);
 
@@ -41096,16 +40970,20 @@ var _editor = __webpack_require__(1358);
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 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 ConditionalPanel extends _react.PureComponent {
 
   constructor() {
     super();
 
     this.saveAndClose = () => {
       if (this.input) {
         this.setBreakpoint(this.input.value);
@@ -41117,16 +40995,23 @@ class ConditionalPanel extends _react.Pu
     this.onKey = e => {
       if (e.key === "Enter") {
         this.saveAndClose();
       } else if (e.key === "Escape") {
         this.props.closeConditionalPanel();
       }
     };
 
+    this.repositionOnScroll = () => {
+      if (this.panelNode && this.scrollParent) {
+        const { scrollLeft } = this.scrollParent;
+        this.panelNode.style.transform = `translateX(${scrollLeft}px)`;
+      }
+    };
+
     this.cbPanel = null;
   }
 
   keepFocusOnInput() {
     if (this.input) {
       this.input.focus();
     }
   }
@@ -41138,49 +41023,80 @@ class ConditionalPanel extends _react.Pu
     return this.props.setBreakpointCondition(location, { condition });
   }
 
   clearConditionalPanel() {
     if (this.cbPanel) {
       this.cbPanel.clear();
       this.cbPanel = null;
     }
+    if (this.scrollParent) {
+      this.scrollParent.removeEventListener("scroll", this.repositionOnScroll);
+    }
+  }
+
+  componentWillMount() {
+    if (this.props.line) {
+      return this.renderToWidget(this.props);
+    }
   }
 
   componentWillUpdate(nextProps) {
     if (nextProps.line) {
       return this.renderToWidget(nextProps);
     }
     return this.clearConditionalPanel();
   }
 
+  componentWillUnmount() {
+    // This is called if CodeMirror is re-initializing itself before the
+    // user closes the conditional panel. Clear the widget, and re-render it
+    // as soon as this component gets remounted
+    return this.clearConditionalPanel();
+  }
+
   renderToWidget(props) {
     const { selectedLocation, line, editor } = props;
     const sourceId = selectedLocation ? selectedLocation.sourceId : "";
 
     const editorLine = (0, _editor.toEditorLine)(sourceId, line);
     this.cbPanel = editor.codeMirror.addLineWidget(editorLine, this.renderConditionalPanel(props), {
       coverGutter: true,
       noHScroll: false
     });
     if (this.input) {
+      let parent = this.input.parentNode;
+      while (parent) {
+        if (parent instanceof HTMLElement && parent.classList.contains("CodeMirror-scroll")) {
+          this.scrollParent = parent;
+          break;
+        }
+        parent = parent.parentNode;
+      }
+
+      if (this.scrollParent) {
+        this.scrollParent.addEventListener("scroll", this.repositionOnScroll);
+        this.repositionOnScroll();
+      }
+
       this.input.focus();
     }
   }
 
   renderConditionalPanel(props) {
     const { breakpoint } = props;
     const condition = breakpoint ? breakpoint.condition : "";
     const panel = document.createElement("div");
     _reactDom2.default.render(_react2.default.createElement(
       "div",
       {
         className: "conditional-breakpoint-panel",
         onClick: () => this.keepFocusOnInput(),
-        onBlur: this.props.closeConditionalPanel
+        onBlur: this.props.closeConditionalPanel,
+        ref: node => this.panelNode = node
       },
       _react2.default.createElement(
         "div",
         { className: "prompt" },
         "\xBB"
       ),
       _react2.default.createElement("input", {
         defaultValue: condition,
@@ -41197,29 +41113,36 @@ class ConditionalPanel extends _react.Pu
     return panel;
   }
 
   render() {
     return null;
   }
 }
 
-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.ConditionalPanel = ConditionalPanel;
+const {
+  setBreakpointCondition,
+  openConditionalPanel,
+  closeConditionalPanel
+} = _actions2.default;
 
 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
   };
-}, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(ConditionalPanel);
+}, {
+  setBreakpointCondition,
+  openConditionalPanel,
+  closeConditionalPanel
+})(ConditionalPanel);
 
 /***/ }),
 /* 1599 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
@@ -41284,31 +41207,37 @@ var _Accordion2 = _interopRequireDefault
 var _CommandBar = __webpack_require__(1608);
 
 var _CommandBar2 = _interopRequireDefault(_CommandBar);
 
 var _UtilsBar = __webpack_require__(1609);
 
 var _UtilsBar2 = _interopRequireDefault(_UtilsBar);
 
+var _BreakpointsDropdown = __webpack_require__(1778);
+
+var _BreakpointsDropdown2 = _interopRequireDefault(_BreakpointsDropdown);
+
 var _ChromeScopes = __webpack_require__(1610);
 
 var _ChromeScopes2 = _interopRequireDefault(_ChromeScopes);
 
 var _Scopes2 = __webpack_require__(1611);
 
 var _Scopes3 = _interopRequireDefault(_Scopes2);
 
 __webpack_require__(1342);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const Scopes = (0, _devtoolsConfig.isEnabled)("chromeScopes") ? _ChromeScopes2.default : _Scopes3.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/>. */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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}`,
       key: type,
@@ -41321,28 +41250,28 @@ function debugBtn(onClick, type, classNa
 class SecondaryPanes extends _react.Component {
   renderBreakpointsToggle() {
     const {
       toggleAllBreakpoints,
       breakpoints,
       breakpointsDisabled,
       breakpointsLoading
     } = this.props;
-    const boxClassName = "breakpoints-toggle";
     const isIndeterminate = !breakpointsDisabled && breakpoints.some(x => x.disabled);
 
     if (breakpoints.size == 0) {
       return null;
     }
 
     const inputProps = {
       type: "checkbox",
       "aria-label": breakpointsDisabled ? L10N.getStr("breakpoints.enable") : L10N.getStr("breakpoints.disable"),
-      className: boxClassName,
+      className: "breakpoints-toggle",
       disabled: breakpointsLoading,
+      key: "breakpoints-toggle",
       onChange: e => {
         e.stopPropagation();
         toggleAllBreakpoints(!breakpointsDisabled);
       },
       onClick: e => e.stopPropagation(),
       checked: !breakpointsDisabled && !isIndeterminate,
       ref: input => {
         if (input) {
@@ -41382,22 +41311,38 @@ class SecondaryPanes extends _react.Comp
       header: L10N.getStr("watchExpressions.header"),
       className: "watch-expressions-pane",
       buttons: this.watchExpressionHeaderButtons(),
       component: _Expressions2.default,
       opened: true
     };
   }
 
+  breakpointDropdown() {
+    if (!_prefs.features.breakpointsDropdown) {
+      return;
+    }
+
+    const {
+      breakOnNext,
+      pauseOnExceptions,
+      shouldPauseOnExceptions,
+      shouldIgnoreCaughtExceptions,
+      isWaitingOnBreak
+    } = this.props;
+
+    return (0, _BreakpointsDropdown2.default)(breakOnNext, pauseOnExceptions, shouldPauseOnExceptions, shouldIgnoreCaughtExceptions, isWaitingOnBreak);
+  }
+
   getStartItems() {
     const scopesContent = this.props.horizontal ? this.getScopeItem() : null;
     const items = [{
       header: L10N.getStr("breakpoints.header"),
       className: "breakpoints-pane",
-      buttons: this.renderBreakpointsToggle(),
+      buttons: [this.breakpointDropdown(), 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 => {
@@ -41490,28 +41435,34 @@ class SecondaryPanes extends _react.Comp
 SecondaryPanes.propTypes = {
   evaluateExpressions: _propTypes2.default.func.isRequired,
   pauseData: _propTypes2.default.object,
   horizontal: _propTypes2.default.bool,
   breakpoints: _propTypes2.default.object,
   breakpointsDisabled: _propTypes2.default.bool,
   breakpointsLoading: _propTypes2.default.bool,
   toggleAllBreakpoints: _propTypes2.default.func.isRequired,
-  toggleShortcutsModal: _propTypes2.default.func
+  toggleShortcutsModal: _propTypes2.default.func,
+  isWaitingOnBreak: _propTypes2.default.bool,
+  shouldPauseOnExceptions: _propTypes2.default.bool,
+  shouldIgnoreCaughtExceptions: _propTypes2.default.bool
 };
 
 SecondaryPanes.contextTypes = {
   shortcuts: _propTypes2.default.object
 };
 
 exports.default = (0, _reactRedux.connect)(state => ({
   pauseData: (0, _selectors.getPause)(state),
   breakpoints: (0, _selectors.getBreakpoints)(state),
   breakpointsDisabled: (0, _selectors.getBreakpointsDisabled)(state),
-  breakpointsLoading: (0, _selectors.getBreakpointsLoading)(state)
+  breakpointsLoading: (0, _selectors.getBreakpointsLoading)(state),
+  isWaitingOnBreak: (0, _selectors.getIsWaitingOnBreak)(state),
+  shouldPauseOnExceptions: (0, _selectors.getShouldPauseOnExceptions)(state),
+  shouldIgnoreCaughtExceptions: (0, _selectors.getShouldIgnoreCaughtExceptions)(state)
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(SecondaryPanes);
 
 /***/ }),
 /* 1600 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -41790,19 +41741,17 @@ class Breakpoints extends _react.PureCom
       item: removeCondition,
       hidden: () => !breakpoint.condition
     }];
 
     (0, _devtoolsContextmenu.showMenu)(e, (0, _devtoolsContextmenu.buildMenu)(items));
   }
 
   selectBreakpoint(breakpoint) {
-    const sourceId = breakpoint.location.sourceId;
-    const { location } = breakpoint;
-    this.props.selectSource(sourceId, { location });
+    this.props.selectLocation(breakpoint.location);
   }
 
   removeBreakpoint(event, breakpoint) {
     event.stopPropagation();
     this.props.removeBreakpoint(breakpoint.location);
   }
 
   renderBreakpoint(breakpoint) {
@@ -42104,38 +42053,24 @@ 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/>. */
-
-exports.getAndProcessFrames = getAndProcessFrames;
-
-var _propTypes = __webpack_require__(20);
-
-var _propTypes2 = _interopRequireDefault(_propTypes);
-
 var _react = __webpack_require__(0);
 
 var _react2 = _interopRequireDefault(_react);
 
 var _redux = __webpack_require__(3);
 
 var _reactRedux = __webpack_require__(1189);
 
-var _reselect = __webpack_require__(993);
-
-var _lodash = __webpack_require__(2);
-
 var _Frame = __webpack_require__(1453);
 
 var _Frame2 = _interopRequireDefault(_Frame);
 
 var _Group = __webpack_require__(1603);
 
 var _Group2 = _interopRequireDefault(_Group);
 
@@ -42152,17 +42087,19 @@ var _frame = __webpack_require__(1380);
 var _clipboard = __webpack_require__(1388);
 
 var _selectors = __webpack_require__(1352);
 
 __webpack_require__(1338);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-const NUM_FRAMES_SHOWN = 7;
+const NUM_FRAMES_SHOWN = 7; /* This Source Code Form is subject to the terms of the Mozilla Public
+                             * License, v. 2.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 Frames extends _react.Component {
 
   constructor(props) {
     super(props);
 
     this.state = {
       showAllFrames: false
@@ -42282,48 +42219,18 @@ class Frames extends _react.Component {
       { className: "pane frames" },
       this.renderFrames(frames),
       (0, _WhyPaused2.default)({ pause }),
       this.renderToggleButton(frames)
     );
   }
 }
 
-Frames.propTypes = {
-  frames: _propTypes2.default.array,
-  frameworkGroupingOn: _propTypes2.default.bool.isRequired,
-  toggleFrameworkGrouping: _propTypes2.default.func.isRequired,
-  selectedFrame: _propTypes2.default.object,
-  selectFrame: _propTypes2.default.func.isRequired,
-  toggleBlackBox: _propTypes2.default.func,
-  pause: _propTypes2.default.object
-};
-
-function getSourceForFrame(sources, frame) {
-  return (0, _selectors.getSourceInSources)(sources, frame.location.sourceId);
-}
-
-function appendSource(sources, frame) {
-  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);
-
-  return processedFrames;
-}
-
-const getAndProcessFramesSelector = (0, _reselect.createSelector)(_selectors.getFrames, _selectors.getSources, getAndProcessFrames);
-
 exports.default = (0, _reactRedux.connect)(state => ({
-  frames: getAndProcessFramesSelector(state),
+  frames: (0, _selectors.getCallStackFrames)(state),
   frameworkGroupingOn: (0, _selectors.getFrameworkGroupingState)(state),
   selectedFrame: (0, _selectors.getSelectedFrame)(state),
   pause: (0, _selectors.getPause)(state)
 }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Frames);
 
 /***/ }),
 /* 1603 */
 /***/ (function(module, exports, __webpack_require__) {
@@ -42620,17 +42527,17 @@ class EventListeners extends _react.Comp
   renderListener({ type, selector, line, sourceId, breakpoint }) {
     const checked = breakpoint && !breakpoint.disabled;
     const location = { sourceId, line };
 
     return _react2.default.createElement(
       "div",
       {
         className: "listener",
-        onClick: () => this.props.selectSource(sourceId, { line }),
+        onClick: () => this.props.selectLocation({ sourceId, line }),
         key: `${type}.${selector}.${sourceId}.${line}`
       },
       _react2.default.createElement("input", {
         type: "checkbox",
         className: "listener-checkbox",
         checked: checked,
         onChange: () => this.handleCheckbox(breakpoint, location)
       }),
@@ -42885,16 +42792,18 @@ var _react2 = _interopRequireDefault(_re
 var _reactRedux = __webpack_require__(1189);
 
 var _redux = __webpack_require__(3);
 
 var _classnames = __webpack_require__(175);
 
 var _classnames2 = _interopRequireDefault(_classnames);
 
+var _prefs = __webpack_require__(226);
+
 var _selectors = __webpack_require__(1352);
 
 var _text = __webpack_require__(1387);
 
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
@@ -42949,23 +42858,23 @@ function formatKey(action) {
   if (isMacOS) {
     const winKey = getKeyForOS("WINNT", `${action}Display`) || getKeyForOS("WINNT", action);
     // display both Windows type and Mac specific keys
     return (0, _text.formatKeyShortcut)([key, winKey].join(" "));
   }
   return (0, _text.formatKeyShortcut)(key);
 }
 
-function debugBtn(onClick, type, className, tooltip, disabled = false) {
+function debugBtn(onClick, type, className, tooltip, disabled = false, ariaPressed = false) {
   const props = {
     onClick,
     key: type,
-    "aria-label": tooltip,
     title: tooltip,
-    disabled
+    disabled,
+    "aria-pressed": ariaPressed
   };
 
   return _react2.default.createElement(
     "button",
     _extends({ className: (0, _classnames2.default)(type, className) }, props),
     _react2.default.createElement("img", { className: type })
   );
 }
@@ -42998,55 +42907,67 @@ class CommandBar extends _react.Componen
     this.props[action]();
   }
 
   renderStepButtons() {
     const isPaused = this.props.pause;
     const className = isPaused ? "active" : "disabled";
     const isDisabled = !this.props.pause;
 
+    if (!isPaused && _prefs.features.removeCommandBarOptions) {
+      return;
+    }
+
     return [debugBtn(this.props.stepOver, "stepOver", className, L10N.getFormatStr("stepOverTooltip", formatKey("stepOver")), isDisabled), debugBtn(this.props.stepIn, "stepIn", className, L10N.getFormatStr("stepInTooltip", formatKey("stepIn")), isDisabled), debugBtn(this.props.stepOut, "stepOut", className, L10N.getFormatStr("stepOutTooltip", formatKey("stepOut")), isDisabled)];
   }
 
   renderPauseButton() {
     const { pause, breakOnNext, isWaitingOnBreak } = this.props;
 
     if (pause) {
       return debugBtn(this.props.resume, "resume", "active", L10N.getFormatStr("resumeButtonTooltip", formatKey("resume")));
     }
 
+    if (_prefs.features.removeCommandBarOptions) {
+      return;
+    }
+
     if (isWaitingOnBreak) {
       return debugBtn(null, "pause", "disabled", L10N.getStr("pausePendingButtonTooltip"), true);
     }
 
     return debugBtn(breakOnNext, "pause", "active", L10N.getFormatStr("pauseButtonTooltip", formatKey("pause")));
   }
 
   /*
    * The pause on exception button has three states in this order:
    *  1. don't pause on exceptions      [false, false]
    *  2. pause on uncaught exceptions   [true, true]
    *  3. pause on all exceptions        [true, false]
   */
   renderPauseOnExceptions() {
+    if (_prefs.features.breakpointsDropdown) {
+      return;
+    }
+
     const {
       shouldPauseOnExceptions,
       shouldIgnoreCaughtExceptions,
       pauseOnExceptions
     } = this.props;
 
     if (!shouldPauseOnExceptions && !shouldIgnoreCaughtExceptions) {
-      return debugBtn(() => pauseOnExceptions(true, true), "pause-exceptions", "enabled", L10N.getStr("ignoreExceptions"));
+      return debugBtn(() => pauseOnExceptions(true, true), "pause-exceptions", "enabled", L10N.getStr("ignoreExceptions"), false, false);
     }
 
     if (shouldPauseOnExceptions && shouldIgnoreCaughtExceptions) {
-      return debugBtn(() => pauseOnExceptions(true, false), "pause-exceptions", "uncaught enabled", L10N.getStr("pauseOnUncaughtExceptions"));
-    }
-
-    return debugBtn(() => pauseOnExceptions(false, false), "pause-exceptions", "all enabled", L10N.getStr("pauseOnExceptions"));
+      return debugBtn(() => pauseOnExceptions(true, false), "pause-exceptions", "uncaught enabled", L10N.getStr("pauseOnUncaughtExceptions"), false, true);
+    }
+
+    return debugBtn(() => pauseOnExceptions(false, false), "pause-exceptions", "all enabled", L10N.getStr("pauseOnExceptions"), false, true);
   }
 
   render() {
     return _react2.default.createElement(
       "div",
       {
         className: (0, _classnames2.default)("command-bar", {
           vertical: !this.props.horizontal
@@ -43393,17 +43314,17 @@ var _redux = __webpack_require__(3);
 var _reactRedux = __webpack_require__(1189);
 
 var _actions = __webpack_require__(1354);
 
 var _actions2 = _interopRequireDefault(_actions);
 
 var _selectors = __webpack_require__(1352);
 
-var _scopes = __webpack_require__(1612);
+var _scopes = __webpack_require__(1780);
 
 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
@@ -43476,208 +43397,17 @@ exports.default = (0, _reactRedux.connec
     selectedFrame,
     pauseInfo: (0, _selectors.getPause)(state),
     frameScopes: frameScopes,
     loadedObjects: (0, _selectors.getLoadedObjects)(state)
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Scopes);
 
 /***/ }),
-/* 1612 */
-/***/ (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.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.
-
-
-// VarAndBindingsPair actually is [name: string, contents: ScopeBindings]
-function getBindingVariables(bindings, parentName) {
-  const args = bindings.arguments.map(arg => (0, _lodash.toPairs)(arg)[0]);
-  const variables = (0, _lodash.toPairs)(bindings.variables);
-
-  return args.concat(variables).map(binding => {
-    const name = binding[0];
-    const contents = binding[1];
-    return {
-      name,
-      path: `${parentName}/${name}`,
-      contents
-    };
-  });
-}
-
-function getSourceBindingVariables(bindings, sourceBindings, parentName) {
-  const result = getBindingVariables(bindings, parentName);
-  const index = Object.create(null);
-  result.forEach(entry => {
-    index[entry.name] = { used: false, entry };
-  });
-  // Find and replace variables that is present in sourceBindings.
-  const bound = Object.keys(sourceBindings).map(name => {
-    const generatedName = sourceBindings[name];
-    const foundMap = index[generatedName];
-    let contents;
-    if (foundMap) {
-      foundMap.used = true;
-      contents = foundMap.entry.contents;
-    } else {
-      contents = { value: { type: "undefined" } };
-    }
-    return {
-      name,
-      generatedName,
-      path: `${parentName}/${generatedName}`,
-      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 getFramePopVariables(pauseInfo, path) {
-  const vars = [];
-
-  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: "<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;
-
-  if (!this_) {
-    return null;
-  }
-
-  return {
-    name: "<this>",
-    path: `${path}/<this>`,
-    contents: { value: this_ }
-  };
-}
-
-function getScopes(pauseInfo, selectedFrame, selectedScope) {
-  if (!pauseInfo || !selectedFrame) {
-    return null;
-  }
-
-  // NOTE: it's possible that we're inspecting an old server
-  // that does not support getting frame scopes directly
-  selectedScope = selectedScope || selectedFrame.scope;
-
-  if (!selectedScope) {
-    return null;
-  }
-
-  const scopes = [];
-
-  let scope = selectedScope;
-  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;
-      let title;
-      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);
-
-      // 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_);
-        }
-      }
-
-      if (vars && vars.length) {
-        vars.sort((a, b) => a.name.localeCompare(b.name));
-        scopes.push({
-          name: title,
-          path: key,
-          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 = _extends({}, scope.object, { displayClass: "Global" });
-      }
-      scopes.push({
-        name: scope.object.class,
-        path: key,
-        contents: { value }
-      });
-    }
-    scopeIndex++;
-  } while (scope = scope.parent); // eslint-disable-line no-cond-assign
-
-  return scopes;
-}
-
-/***/ }),
+/* 1612 */,
 /* 1613 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
@@ -44089,24 +43819,31 @@ class SourceTabs extends _react.PureComp
   }
 
   toggleSourcesDropdown(e) {
     this.setState({
       dropdownShown: !this.state.dropdownShown
     });
   }
 
+  getIconClass(source) {
+    if ((0, _source.isPretty)(source.toJS())) return "prettyPrint";
+    if (source.get("isBlackBoxed")) return "blackBox";
+    return "file";
+  }
+
   renderDropdownSource(source) {
-    const { selectSource } = this.props;
+    const { selectLocation } = this.props;
     const filename = (0, _source.getFilename)(source.toJS());
 
-    const onClick = () => selectSource(source.get("id"));
+    const onClick = () => selectLocation({ sourceId: source.get("id"), line: 0 });
     return _react2.default.createElement(
       "li",
       { key: source.get("id"), onClick: onClick },
+      _react2.default.createElement("img", { className: "dropdown-icon " + this.getIconClass(source) }),
       filename
     );
   }
 
   renderTabs() {
     const { sourceTabs } = this.props;
     if (!sourceTabs) {
       return;
@@ -44161,17 +43898,17 @@ class SourceTabs extends _react.PureComp
       _react2.default.createElement(_Close2.default, {
         handleClick: onClickClose,
         tooltip: L10N.getStr("sourceTabs.closeTabButtonTooltip")
       })
     );
   }
 
   renderSourceTab(source) {
-    const { selectedSource, selectSource, closeTab } = this.props;
+    const { selectedSource, selectLocation, closeTab } = this.props;
     const filename = (0, _source.getFilename)(source.toJS());
     const active = selectedSource && source.get("id") == selectedSource.get("id") && !this.isProjectSearchEnabled() && !this.isSourceSearchEnabled();
     const isPrettyCode = (0, _source.isPretty)(source.toJS());
     const sourceAnnotation = this.getSourceAnnotation(source);
 
     function onClickClose(ev) {
       ev.stopPropagation();
       closeTab(source.get("url"));
@@ -44182,17 +43919,17 @@ class SourceTabs extends _react.PureComp
       pretty: isPrettyCode
     });
 
     return _react2.default.createElement(
       "div",
       {
         className: className,
         key: source.get("id"),
-        onClick: () => selectSource(source.get("id")),
+        onClick: () => selectLocation({ sourceId: source.get("id") }),
         onContextMenu: e => this.onTabContextMenu(e, source.get("id")),
         title: (0, _source.getFileURL)(source.toJS())
       },
       sourceAnnotation,
       _react2.default.createElement(
         "div",
         { className: "filename" },
         filename
@@ -44211,17 +43948,17 @@ class SourceTabs extends _react.PureComp
     }
 
     const Panel = _react2.default.createElement(
       "ul",
       null,
       hiddenSourceTabs.map(this.renderDropdownSource)
     );
 
-    return _react2.default.createElement(_Dropdown2.default, { panel: Panel });
+    return _react2.default.createElement(_Dropdown2.default, { panel: Panel, icon: "»" });
   }
 
   renderStartPanelToggleButton() {
     return _react2.default.createElement(_PaneToggle2.default, {
       position: "start",
       collapsed: !this.props.startPanelCollapsed,
       handleClick: this.props.togglePaneCollapse
     });
@@ -44237,17 +43974,22 @@ class SourceTabs extends _react.PureComp
       collapsed: !this.props.endPanelCollapsed,
       handleClick: this.props.togglePaneCollapse,
       horizontal: this.props.horizontal
     });
   }
 
   getSourceAnnotation(source) {
     const sourceObj = source.toJS();
-
+    const sourceId = source.get("id");
+    const sourceMetaData = this.props.sourceTabsMetaData[sourceId];
+
+    if (sourceMetaData && sourceMetaData.isReactComponent) {
+      return _react2.default.createElement("img", { className: "react" });
+    }
     if ((0, _source.isPretty)(sourceObj)) {
       return _react2.default.createElement("img", { className: "prettyPrint" });
     }
     if (sourceObj.isBlackBoxed) {
       return _react2.default.createElement("img", { className: "blackBox" });
     }
   }
 
@@ -44259,22 +44001,30 @@ class SourceTabs extends _react.PureComp
       this.renderTabs(),
       this.renderDropdown(),
       this.renderEndPanelToggleButton()
     );
   }
 }
 
 exports.default = (0, _reactRedux.connect)(state => {
+  const sourceTabs = (0, _selectors.getSourcesForTabs)(state);
+  const sourceTabsMetaData = {};
+  sourceTabs.forEach(source => {
+    const sourceId = source ? source.get("id") : "";
+    sourceTabsMetaData[sourceId] = (0, _selectors.getSourceMetaData)(state, sourceId);
+  });
+
   return {
     selectedSource: (0, _selectors.getSelectedSource)(state),
     searchTabs: (0, _selectors.getSearchTabs)(state),
-    sourceTabs: (0, _selectors.getSourcesForTabs)(state),
+    sourceTabs: sourceTabs,
     activeSearch: (0, _selectors.getActiveSearch)(state),
-    searchOn: (0, _selectors.getActiveSearch)(state) === "source"
+    searchOn: (0, _selectors.getActiveSearch)(state) === "source",
+    sourceTabsMetaData: sourceTabsMetaData
   };
 }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(SourceTabs);
 
 /***/ }),
 /* 1615 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -44327,17 +44077,17 @@ class Dropdown extends _react.Component 
       this.props.panel
     );
   }
 
   renderButton() {
     return _react2.default.createElement(
       "button",
       { className: "dropdown-button", onClick: this.toggleDropdown },
-      "\xBB"
+      this.props.icon
     );
   }
 
   renderMask() {
     return _react2.default.createElement("div", {
       className: "dropdown-mask",
       onClick: this.toggleDropdown,
       style: { display: this.state.dropdownShown ? "block" : "none" }
@@ -44867,18 +44617,17 @@ function paused(pauseInfo) {
     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, { location: { line, column } }));
+    await dispatch((0, _sources.selectLocation)(frame.location));
 
     dispatch((0, _ui.togglePaneCollapse)("end", false));
     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/>. */
 
@@ -45087,18 +44836,17 @@ var _fetchScopes = __webpack_require__(1
  */
 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, _sources.selectLocation)(frame.location));
 
     dispatch((0, _expressions.evaluateExpressions)());
     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/>. */
 
@@ -45261,51 +45009,49 @@ class QuickOpenModal extends _react.Comp
       }
       return this.searchSources(query);
     };
 
     this.selectResultItem = (e, item) => {
       if (item == null) {
         return;
       }
-      const { selectSource, selectedSource, query, searchType } = this.props;
+      const { selectLocation, selectedSource, query, searchType } = this.props;
       if (this.isSymbolSearch()) {
         if (selectedSource == null) {
           return;
         }
-        selectSource(selectedSource.get("id"), {
-          location: _extends({}, item.location != null ? { line: item.location.start.line } : {})
-        });
+        const line = item.location && item.location.start ? item.location.start.line : 0;
+        selectLocation({ sourceId: selectedSource.get("id"), line });
       } else if (searchType === "gotoSource") {
         const location = (0, _quickOpen.parseLineColumn)(query);
         if (location != null) {
-          selectSource(item.id, { location });
+          selectLocation(_extends({}, location, { sourceId: item.id }));
         }
       } else {
-        selectSource(item.id);
+        selectLocation({ sourceId: item.id, line: 0 });
       }
 
       this.closeModal();
     };
 
     this.onSelectResultItem = item => {
       const {
-        selectSource,
+        selectLocation,
         selectedSource,
         highlightLineRange,
         searchType
       } = this.props;
       if (!this.isSymbolSearch() || selectedSource == null) {
         return;
       }
 
       if (searchType === "variables") {
-        selectSource(selectedSource.get("id"), {
-          location: _extends({}, item.location != null ? { line: item.location.start.line } : {})
-        });
+        const line = item.location && item.location.start ? item.location.start.line : 0;
+        selectLocation({ sourceId: selectedSource.get("id"), line });
       }
 
       if (searchType === "functions") {
         highlightLineRange(_extends({}, item.location != null ? { start: item.location.start.line, end: item.location.end.line } : {}, {
           sourceId: selectedSource.get("id")
         }));
       }
     };
@@ -45330,17 +45076,17 @@ class QuickOpenModal extends _react.Comp
       if (this.isSymbolSearch() && noSource) {
         return;
       }
       this.updateResults(e.target.value);
     };
 
     this.onKeyDown = e => {
       const {
-        selectSource,
+        selectLocation,
         selectedSource,
         enabled,
         query,
         searchType
       } = this.props;
       const { results, selectedIndex } = this.state;
 
       if (!enabled || !results) {
@@ -45354,17 +45100,17 @@ class QuickOpenModal extends _react.Comp
         return this.traverseResults(1);
       } else if (e.key === "Enter") {
         if (searchType === "goto") {
           if (!selectedSource) {
             return;
           }
           const location = (0, _quickOpen.parseLineColumn)(query);
           if (location != null) {
-            selectSource(selectedSource.get("id"), { location });
+            selectLocation(_extends({}, location, { sourceId: selectedSource.get("id") }));
           }
         } else {
           this.selectResultItem(e, results[selectedIndex]);
         }
         return this.closeModal();
       } else if (e.key === "Tab") {
         return this.closeModal();
       }
@@ -45552,54 +45298,80 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.fetchScopes = fetchScopes;
 
 var _selectors = __webpack_require__(1352);
 
 var _pause = __webpack_require__(1400);
 
+var _prefs = __webpack_require__(226);
+
 var _devtoolsSourceMap = __webpack_require__(1360);
 
+var _loadSourceText = __webpack_require__(1435);
+
+function mapScopes(scopes, frame) {
+  return async function ({ dispatch, getState, client, sourceMaps }) {
+    const mappedScopes = await (0, _pause.updateScopeBindings)(scopes, frame.generatedLocation, frame.location, {
+      async getLocationScopes(location, astScopes) {
+        return sourceMaps.getLocationScopes(location, astScopes);
+      },
+      async loadSourceText(sourceId) {
+        const source = (0, _selectors.getSource)(getState(), sourceId).toJS();
+        await dispatch((0, _loadSourceText.loadSourceText)(source));
+      }
+    });
+
+    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/>. */
+
 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")) {
+    const generatedSourceRecord = (0, _selectors.getSource)(getState(), frame.generatedLocation.sourceId);
+
+    if (generatedSourceRecord.get("isWasm")) {
+      return;
+    }
+
+    const sourceRecord = (0, _selectors.getSource)(getState(), frame.location.sourceId);
+
+    if (sourceRecord.get("isPrettyPrinted")) {
       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/>. */
+    if (_prefs.features.mapScopes) {
+      dispatch(mapScopes(scopes, frame));
+    }
+  };
+}
 
 /***/ }),
 /* 1656 */,
 /* 1657 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -46112,11 +45884,2258 @@ exports.default = Badge;
 /* 1730 */,
 /* 1731 */,
 /* 1732 */,
 /* 1733 */
 /***/ (function(module, exports) {
 
 module.exports = "<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" viewBox=\"0 0 1200 1200\" style=\"enable-background:new 0 0 1200 1200;\" xml:space=\"preserve\"><style type=\"text/css\"> .st0{clip-path:url(#SVGID_2_);} .st1{fill:url(#SVGID_3_);} .st2{fill:url(#SVGID_4_);} .st3{opacity:0.28;fill:#C24411;} .st4{fill:#FFFFFF;} </style><g><defs><path id=\"SVGID_1_\" d=\"M1088.7,1165.5H111.3c-42.4,0-76.7-34.4-76.7-76.7V111.3c0-42.4,34.4-76.7,76.7-76.7h977.4 c42.4,0,76.7,34.4,76.7,76.7v977.4C1165.5,1131.1,1131.1,1165.5,1088.7,1165.5z\"></path></defs><clipPath id=\"SVGID_2_\"><use xlink:href=\"#SVGID_1_\" style=\"overflow:visible;\"></use></clipPath><g class=\"st0\"><linearGradient id=\"SVGID_3_\" gradientUnits=\"userSpaceOnUse\" x1=\"426.6738\" y1=\"482.4993\" x2=\"1284.413\" y2=\"1239.9835\"><stop offset=\"0\" style=\"stop-color:#F77122\"></stop><stop offset=\"1\" style=\"stop-color:#D6560A\"></stop></linearGradient><polygon class=\"st1\" points=\"573.6,1896.7 -87.9,1286.6 1204.5,-115 1866,495 \"></polygon><linearGradient id=\"SVGID_4_\" gradientUnits=\"userSpaceOnUse\" x1=\"1128.9907\" y1=\"-135.8044\" x2=\"-496.2911\" y2=\"788.1552\"><stop offset=\"0\" style=\"stop-color:#D6560A\"></stop><stop offset=\"1\" style=\"stop-color:#F77122\"></stop></linearGradient><polygon class=\"st2\" points=\"-66.9,1307.6 -644.1,775.5 648.4,-626.1 1225.5,-94 \"></polygon><rect x=\"-143.7\" y=\"-143.6\" transform=\"matrix(0.9658 -0.2591 0.2591 0.9658 -201.3159 92.1307)\" class=\"st3\" width=\"785\" height=\"1906.5\"></rect></g></g><g><path class=\"st4\" d=\"M384.9,900.1H245.4v-45.3h85.6V345.2h-85.6v-45.3h139.5V900.1z\"></path><path class=\"st4\" d=\"M745.7,463c-16.1,60.4-35,118.2-56.7,173.6c-21.7,55.4-42.7,105-62.9,148.8H574 c-20.3-43.8-41.2-93.4-62.9-148.8c-21.7-55.4-40.6-113.2-56.7-173.6h62c5,20.3,10.8,41.9,17.7,64.8s14,45.7,21.7,68.2 c7.6,22.5,15.4,44.3,23.2,65.4c7.8,21.1,15.3,39.9,22.3,56.4c7-16.5,14.5-35.3,22.3-56.4c7.8-21.1,15.6-42.9,23.2-65.4 c7.6-22.5,14.9-45.3,21.7-68.2s12.7-44.5,17.7-64.8H745.7z\"></path><path class=\"st4\" d=\"M815.1,299.9h139.5v45.3h-85.6v509.6h85.6v45.3H815.1V299.9z\"></path></g></svg>"
 
+/***/ }),
+/* 1734 */,
+/* 1735 */,
+/* 1736 */,
+/* 1737 */,
+/* 1738 */,
+/* 1739 */,
+/* 1740 */,
+/* 1741 */,
+/* 1742 */,
+/* 1743 */,
+/* 1744 */,
+/* 1745 */,
+/* 1746 */,
+/* 1747 */,
+/* 1748 */,
+/* 1749 */,
+/* 1750 */,
+/* 1751 */,
+/* 1752 */,
+/* 1753 */,
+/* 1754 */,
+/* 1755 */,
+/* 1756 */,
+/* 1757 */,
+/* 1758 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 EventEmitter = function EventEmitter() {};
+module.exports = EventEmitter;
+
+const promise = __webpack_require__(1764);
+
+/**
+ * Decorate an object with event emitter functionality.
+ *
+ * @param Object aObjectToDecorate
+ *        Bind all public methods of EventEmitter to
+ *        the aObjectToDecorate object.
+ */
+EventEmitter.decorate = function EventEmitter_decorate(aObjectToDecorate) {
+  let emitter = new EventEmitter();
+  aObjectToDecorate.on = emitter.on.bind(emitter);
+  aObjectToDecorate.off = emitter.off.bind(emitter);
+  aObjectToDecorate.once = emitter.once.bind(emitter);
+  aObjectToDecorate.emit = emitter.emit.bind(emitter);
+};
+
+EventEmitter.prototype = {
+  /**
+   * Connect a listener.
+   *
+   * @param string aEvent
+   *        The event name to which we're connecting.
+   * @param function aListener
+   *        Called when the event is fired.
+   */
+  on: function EventEmitter_on(aEvent, aListener) {
+    if (!this._eventEmitterListeners) this._eventEmitterListeners = new Map();
+    if (!this._eventEmitterListeners.has(aEvent)) {
+      this._eventEmitterListeners.set(aEvent, []);
+    }
+    this._eventEmitterListeners.get(aEvent).push(aListener);
+  },
+
+  /**
+   * Listen for the next time an event is fired.
+   *
+   * @param string aEvent
+   *        The event name to which we're connecting.
+   * @param function aListener
+   *        (Optional) Called when the event is fired. Will be called at most
+   *        one time.
+   * @return promise
+   *        A promise which is resolved when the event next happens. The
+   *        resolution value of the promise is the first event argument. If
+   *        you need access to second or subsequent event arguments (it's rare
+   *        that this is needed) then use aListener
+   */
+  once: function EventEmitter_once(aEvent, aListener) {
+    let deferred = promise.defer();
+
+    let handler = (aEvent, aFirstArg, ...aRest) => {
+      this.off(aEvent, handler);
+      if (aListener) {
+        aListener.apply(null, [aEvent, aFirstArg, ...aRest]);
+      }
+      deferred.resolve(aFirstArg);
+    };
+
+    handler._originalListener = aListener;
+    this.on(aEvent, handler);
+
+    return deferred.promise;
+  },
+
+  /**
+   * Remove a previously-registered event listener.  Works for events
+   * registered with either on or once.
+   *
+   * @param string aEvent
+   *        The event name whose listener we're disconnecting.
+   * @param function aListener
+   *        The listener to remove.
+   */
+  off: function EventEmitter_off(aEvent, aListener) {
+    if (!this._eventEmitterListeners) return;
+    let listeners = this._eventEmitterListeners.get(aEvent);
+    if (listeners) {
+      this._eventEmitterListeners.set(aEvent, listeners.filter(l => {
+        return l !== aListener && l._originalListener !== aListener;
+      }));
+    }
+  },
+
+  /**
+   * Emit an event.  All arguments to this method will
+   * be sent to listener functions.
+   */
+  emit: function EventEmitter_emit(aEvent) {
+    if (!this._eventEmitterListeners || !this._eventEmitterListeners.has(aEvent)) {
+      return;
+    }
+
+    let originalListeners = this._eventEmitterListeners.get(aEvent);
+    for (let listener of this._eventEmitterListeners.get(aEvent)) {
+      // If the object was destroyed during event emission, stop
+      // emitting.
+      if (!this._eventEmitterListeners) {
+        break;
+      }
+
+      // If listeners were removed during emission, make sure the
+      // event handler we're going to fire wasn't removed.
+      if (originalListeners === this._eventEmitterListeners.get(aEvent) || this._eventEmitterListeners.get(aEvent).some(l => l === listener)) {
+        try {
+          listener.apply(null, arguments);
+        } catch (ex) {
+          // Prevent a bad listener from interfering with the others.
+          let msg = ex + ": " + ex.stack;
+          //console.error(msg);
+          console.log(msg);
+        }
+      }
+    }
+  }
+};
+
+/***/ }),
+/* 1759 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+(function(f) {
+  if (true) {
+    module.exports = f(__webpack_require__(0));
+    /* global define */
+  } else if (typeof define === 'function' && define.amd) {
+    define(['react'], f);
+  } else {
+    var g;
+    if (typeof window !== 'undefined') {
+      g = window;
+    } else if (typeof global !== 'undefined') {
+      g = global;
+    } else if (typeof self !== 'undefined') {
+      g = self;
+    } else {
+      g = this;
+    }
+
+    if (typeof g.React === 'undefined') {
+      throw Error('React module should be required before ReactDOMFactories');
+    }
+
+    g.ReactDOMFactories = f(g.React);
+  }
+})(function(React) {
+  /**
+   * Create a factory that creates HTML tag elements.
+   */
+  function createDOMFactory(type) {
+    var factory = React.createElement.bind(null, type);
+    // Expose the type on the factory and the prototype so that it can be
+    // easily accessed on elements. E.g. `<Foo />.type === Foo`.
+    // This should not be named `constructor` since this may not be the function
+    // that created the element, and it may not even be a constructor.
+    factory.type = type;
+    return factory;
+  };
+
+  /**
+   * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
+   */
+  var ReactDOMFactories = {
+    a: createDOMFactory('a'),
+    abbr: createDOMFactory('abbr'),
+    address: createDOMFactory('address'),
+    area: createDOMFactory('area'),
+    article: createDOMFactory('article'),
+    aside: createDOMFactory('aside'),
+    audio: createDOMFactory('audio'),
+    b: createDOMFactory('b'),
+    base: createDOMFactory('base'),
+    bdi: createDOMFactory('bdi'),
+    bdo: createDOMFactory('bdo'),
+    big: createDOMFactory('big'),
+    blockquote: createDOMFactory('blockquote'),
+    body: createDOMFactory('body'),
+    br: createDOMFactory('br'),
+    button: createDOMFactory('button'),
+    canvas: createDOMFactory('canvas'),
+    caption: createDOMFactory('caption'),
+    cite: createDOMFactory('cite'),
+    code: createDOMFactory('code'),
+    col: createDOMFactory('col'),
+    colgroup: createDOMFactory('colgroup'),
+    data: createDOMFactory('data'),
+    datalist: createDOMFactory('datalist'),
+    dd: createDOMFactory('dd'),
+    del: createDOMFactory('del'),
+    details: createDOMFactory('details'),
+    dfn: createDOMFactory('dfn'),
+    dialog: createDOMFactory('dialog'),
+    div: createDOMFactory('div'),
+    dl: createDOMFactory('dl'),
+    dt: createDOMFactory('dt'),
+    em: createDOMFactory('em'),
+    embed: createDOMFactory('embed'),
+    fieldset: createDOMFactory('fieldset'),
+    figcaption: createDOMFactory('figcaption'),
+    figure: createDOMFactory('figure'),
+    footer: createDOMFactory('footer'),
+    form: createDOMFactory('form'),
+    h1: createDOMFactory('h1'),
+    h2: createDOMFactory('h2'),
+    h3: createDOMFactory('h3'),
+    h4: createDOMFactory('h4'),
+    h5: createDOMFactory('h5'),
+    h6: createDOMFactory('h6'),
+    head: createDOMFactory('head'),
+    header: createDOMFactory('header'),
+    hgroup: createDOMFactory('hgroup'),
+    hr: createDOMFactory('hr'),
+    html: createDOMFactory('html'),
+    i: createDOMFactory('i'),
+    iframe: createDOMFactory('iframe'),
+    img: createDOMFactory('img'),
+    input: createDOMFactory('input'),
+    ins: createDOMFactory('ins'),
+    kbd: createDOMFactory('kbd'),
+    keygen: createDOMFactory('keygen'),
+    label: createDOMFactory('label'),
+    legend: createDOMFactory('legend'),
+    li: createDOMFactory('li'),
+    link: createDOMFactory('link'),
+    main: createDOMFactory('main'),
+    map: createDOMFactory('map'),
+    mark: createDOMFactory('mark'),
+    menu: createDOMFactory('menu'),
+    menuitem: createDOMFactory('menuitem'),
+    meta: createDOMFactory('meta'),
+    meter: createDOMFactory('meter'),
+    nav: createDOMFactory('nav'),
+    noscript: createDOMFactory('noscript'),
+    object: createDOMFactory('object'),
+    ol: createDOMFactory('ol'),
+    optgroup: createDOMFactory('optgroup'),
+    option: createDOMFactory('option'),
+    output: createDOMFactory('output'),
+    p: createDOMFactory('p'),
+    param: createDOMFactory('param'),
+    picture: createDOMFactory('picture'),
+    pre: createDOMFactory('pre'),
+    progress: createDOMFactory('progress'),
+    q: createDOMFactory('q'),
+    rp: createDOMFactory('rp'),
+    rt: createDOMFactory('rt'),
+    ruby: createDOMFactory('ruby'),
+    s: createDOMFactory('s'),
+    samp: createDOMFactory('samp'),
+    script: createDOMFactory('script'),
+    section: createDOMFactory('section'),
+    select: createDOMFactory('select'),
+    small: createDOMFactory('small'),
+    source: createDOMFactory('source'),
+    span: createDOMFactory('span'),
+    strong: createDOMFactory('strong'),
+    style: createDOMFactory('style'),
+    sub: createDOMFactory('sub'),
+    summary: createDOMFactory('summary'),
+    sup: createDOMFactory('sup'),
+    table: createDOMFactory('table'),
+    tbody: createDOMFactory('tbody'),
+    td: createDOMFactory('td'),
+    textarea: createDOMFactory('textarea'),
+    tfoot: createDOMFactory('tfoot'),
+    th: createDOMFactory('th'),
+    thead: createDOMFactory('thead'),
+    time: createDOMFactory('time'),
+    title: createDOMFactory('title'),
+    tr: createDOMFactory('tr'),
+    track: createDOMFactory('track'),
+    u: createDOMFactory('u'),
+    ul: createDOMFactory('ul'),
+    var: createDOMFactory('var'),
+    video: createDOMFactory('video'),
+    wbr: createDOMFactory('wbr'),
+
+    // SVG
+    circle: createDOMFactory('circle'),
+    clipPath: createDOMFactory('clipPath'),
+    defs: createDOMFactory('defs'),
+    ellipse: createDOMFactory('ellipse'),
+    g: createDOMFactory('g'),
+    image: createDOMFactory('image'),
+    line: createDOMFactory('line'),
+    linearGradient: createDOMFactory('linearGradient'),
+    mask: createDOMFactory('mask'),
+    path: createDOMFactory('path'),
+    pattern: createDOMFactory('pattern'),
+    polygon: createDOMFactory('polygon'),
+    polyline: createDOMFactory('polyline'),
+    radialGradient: createDOMFactory('radialGradient'),
+    rect: createDOMFactory('rect'),
+    stop: createDOMFactory('stop'),
+    svg: createDOMFactory('svg'),
+    text: createDOMFactory('text'),
+    tspan: createDOMFactory('tspan'),
+  };
+
+  // due to wrapper and conditionals at the top, this will either become
+  // `module.exports ReactDOMFactories` if that is available,
+  // otherwise it will be defined via `define(['react'], ReactDOMFactories)`
+  // if that is available,
+  // otherwise it will be defined as global variable.
+  return ReactDOMFactories;
+});
+
+
+
+/***/ }),
+/* 1760 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.getSourceBindingVariables = getSourceBindingVariables;
+exports.getBindingVariables = getBindingVariables;
+
+var _lodash = __webpack_require__(2);
+
+// VarAndBindingsPair actually is [name: string, contents: BindingContents]
+
+
+// Scope's bindings field which holds variables and arguments
+function getSourceBindingVariables(bindings, sourceBindings, parentName) {
+  const result = getBindingVariables(bindings, parentName);
+  const index = Object.create(null);
+  result.forEach(entry => {
+    index[entry.name] = { used: false, entry };
+  });
+  // Find and replace variables that is present in sourceBindings.
+  const bound = Object.keys(sourceBindings).map(name => {
+    const generatedName = sourceBindings[name];
+    const foundMap = index[generatedName];
+    let contents;
+    if (foundMap) {
+      foundMap.used = true;
+      contents = foundMap.entry.contents;
+    } else {
+      contents = { value: { type: "undefined" } };
+    }
+    return {
+      name,
+      generatedName,
+      path: `${parentName}/${generatedName}`,
+      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);
+}
+
+// Create the tree nodes representing all the variables and arguments
+// for the bindings from a scope.
+/* eslint max-nested-callbacks: ["error", 4] */
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+function getBindingVariables(bindings, parentName) {
+  const args = bindings.arguments.map(arg => (0, _lodash.toPairs)(arg)[0]);
+  const variables = (0, _lodash.toPairs)(bindings.variables);
+
+  return args.concat(variables).map(binding => {
+    const name = binding[0];
+    const contents = binding[1];
+    return {
+      name,
+      path: `${parentName}/${name}`,
+      contents
+    };
+  });
+}
+
+/***/ }),
+/* 1761 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.getFramePopVariables = getFramePopVariables;
+exports.getThisVariable = getThisVariable;
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 getFramePopVariables(pauseInfo, path) {
+  const vars = [];
+
+  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: "<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;
+
+  if (!this_) {
+    return null;
+  }
+
+  return {
+    name: "<this>",
+    path: `${path}/<this>`,
+    contents: { value: this_ }
+  };
+}
+
+/***/ }),
+/* 1762 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 Menu = __webpack_require__(1763);
+const MenuItem = __webpack_require__(1765);
+const { PrefsHelper } = __webpack_require__(1766);
+const Services = __webpack_require__(22);
+const KeyShortcuts = __webpack_require__(1767);
+const { ZoomKeys } = __webpack_require__(1768);
+const EventEmitter = __webpack_require__(1758);
+
+module.exports = {
+  KeyShortcuts,
+  Menu,
+  MenuItem,
+  PrefsHelper,
+  Services,
+  ZoomKeys,
+  EventEmitter
+};
+
+/***/ }),
+/* 1763 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 EventEmitter = __webpack_require__(1758);
+
+function inToolbox() {
+  return window.parent.document.documentURI == "about:devtools-toolbox";
+}
+
+/**
+ * A partial implementation of the Menu API provided by electron:
+ * https://github.com/electron/electron/blob/master/docs/api/menu.md.
+ *
+ * Extra features:
+ *  - Emits an 'open' and 'close' event when the menu is opened/closed
+
+ * @param String id (non standard)
+ *        Needed so tests can confirm the XUL implementation is working
+ */
+function Menu({ id = null } = {}) {
+  this.menuitems = [];
+  this.id = id;
+
+  Object.defineProperty(this, "items", {
+    get() {
+      return this.menuitems;
+    }
+  });
+
+  EventEmitter.decorate(this);
+}
+
+/**
+ * Add an item to the end of the Menu
+ *
+ * @param {MenuItem} menuItem
+ */
+Menu.prototype.append = function (menuItem) {
+  this.menuitems.push(menuItem);
+};
+
+/**
+ * Add an item to a specified position in the menu
+ *
+ * @param {int} pos
+ * @param {MenuItem} menuItem
+ */
+Menu.prototype.insert = function (pos, menuItem) {
+  throw Error("Not implemented");
+};
+
+/**
+ * Show the Menu at a specified location on the screen
+ *
+ * Missing features:
+ *   - browserWindow - BrowserWindow (optional) - Default is null.
+ *   - positioningItem Number - (optional) OS X
+ *
+ * @param {int} screenX
+ * @param {int} screenY
+ * @param Toolbox toolbox (non standard)
+ *        Needed so we in which window to inject XUL
+ */
+Menu.prototype.popup = function (screenX, screenY, toolbox) {
+  let doc = toolbox.doc;
+  let popupset = doc.querySelector("popupset");
+  // See bug 1285229, on Windows, opening the same popup multiple times in a
+  // row ends up duplicating the popup. The newly inserted popup doesn't
+  // dismiss the old one. So remove any previously displayed popup before
+  // opening a new one.
+  let popup = popupset.querySelector("menupopup[menu-api=\"true\"]");
+  if (popup) {
+    popup.hidePopup();
+  }
+
+  popup = this.createPopup(doc);
+  popup.setAttribute("menu-api", "true");
+
+  if (this.id) {
+    popup.id = this.id;
+  }
+  this._createMenuItems(popup);
+
+  // Remove the menu from the DOM once it's hidden.
+  popup.addEventListener("popuphidden", e => {
+    if (e.target === popup) {
+      popup.remove();
+      this.emit("close", popup);
+    }
+  });
+
+  popup.addEventListener("popupshown", e => {
+    if (e.target === popup) {
+      this.emit("open", popup);
+    }
+  });
+
+  popupset.appendChild(popup);
+  popup.openPopupAtScreen(screenX, screenY, true);
+};
+
+Menu.prototype.createPopup = function (doc) {
+  return doc.createElement("menupopup");
+};
+
+Menu.prototype._createMenuItems = function (parent) {
+  let doc = parent.ownerDocument;
+  this.menuitems.forEach(item => {
+    if (!item.visible) {
+      return;
+    }
+
+    if (item.submenu) {
+      let menupopup = doc.createElement("menupopup");
+      item.submenu._createMenuItems(menupopup);
+
+      let menuitem = doc.createElement("menuitem");
+      menuitem.setAttribute("label", item.label);
+      if (!inToolbox()) {
+        menuitem.textContent = item.label;
+      }
+
+      let menu = doc.createElement("menu");
+      menu.appendChild(menuitem);
+      menu.appendChild(menupopup);
+      if (item.disabled) {
+        menu.setAttribute("disabled", "true");
+      }
+      if (item.accesskey) {
+        menu.setAttribute("accesskey", item.accesskey);
+      }
+      if (item.id) {
+        menu.id = item.id;
+      }
+      parent.appendChild(menu);
+    } else if (item.type === "separator") {
+      let menusep = doc.createElement("menuseparator");
+      parent.appendChild(menusep);
+    } else {
+      let menuitem = doc.createElement("menuitem");
+      menuitem.setAttribute("label", item.label);
+
+      if (!inToolbox()) {
+        menuitem.textContent = item.label;
+      }
+
+      menuitem.addEventListener("command", () => item.click());
+
+      if (item.type === "checkbox") {
+        menuitem.setAttribute("type", "checkbox");
+      }
+      if (item.type === "radio") {
+        menuitem.setAttribute("type", "radio");
+      }
+      if (item.disabled) {
+        menuitem.setAttribute("disabled", "true");
+      }
+      if (item.checked) {
+        menuitem.setAttribute("checked", "true");
+      }
+      if (item.accesskey) {
+        menuitem.setAttribute("accesskey", item.accesskey);
+      }
+      if (item.id) {
+        menuitem.id = item.id;
+      }
+
+      parent.appendChild(menuitem);
+    }
+  });
+};
+
+Menu.setApplicationMenu = () => {
+  throw Error("Not implemented");
+};
+
+Menu.sendActionToFirstResponder = () => {
+  throw Error("Not implemented");
+};
+
+Menu.buildFromTemplate = () => {
+  throw Error("Not implemented");
+};
+
+module.exports = Menu;
+
+/***/ }),
+/* 1764 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/Promise.jsm
+ */
+
+/**
+ * Promise.jsm is mostly the Promise web API with a `defer` method. Just drop this in here,
+ * and use the native web API (although building with webpack/babel, it may replace this
+ * with it's own version if we want to target environments that do not have `Promise`.
+ */
+
+let p = typeof window != "undefined" ? window.Promise : Promise;
+p.defer = function defer() {
+  var resolve, reject;
+  var promise = new Promise(function () {
+    resolve = arguments[0];
+    reject = arguments[1];
+  });
+  return {
+    resolve: resolve,
+    reject: reject,
+    promise: promise
+  };
+};
+
+module.exports = p;
+
+/***/ }),
+/* 1765 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * A partial implementation of the MenuItem API provided by electron:
+ * https://github.com/electron/electron/blob/master/docs/api/menu-item.md.
+ *
+ * Missing features:
+ *   - id String - Unique within a single menu. If defined then it can be used
+ *                 as a reference to this item by the position attribute.
+ *   - role String - Define the action of the menu item; when specified the
+ *                   click property will be ignored
+ *   - sublabel String
+ *   - accelerator Accelerator
+ *   - icon NativeImage
+ *   - position String - This field allows fine-grained definition of the
+ *                       specific location within a given menu.
+ *
+ * Implemented features:
+ *  @param Object options
+ *    Function click
+ *      Will be called with click(menuItem, browserWindow) when the menu item
+ *       is clicked
+ *    String type
+ *      Can be normal, separator, submenu, checkbox or radio
+ *    String label
+ *    Boolean enabled
+ *      If false, the menu item will be greyed out and unclickable.
+ *    Boolean checked
+ *      Should only be specified for checkbox or radio type menu items.
+ *    Menu submenu
+ *      Should be specified for submenu type menu items. If submenu is specified,
+ *      the type: 'submenu' can be omitted. If the value is not a Menu then it
+ *      will be automatically converted to one using Menu.buildFromTemplate.
+ *    Boolean visible
+ *      If false, the menu item will be entirely hidden.
+ */
+function MenuItem({
+  accesskey = null,
+  checked = false,
+  click = () => {},
+  disabled = false,
+  label = "",
+  id = null,
+  submenu = null,
+  type = "normal",
+  visible = true
+} = {}) {
+  this.accesskey = accesskey;
+  this.checked = checked;
+  this.click = click;
+  this.disabled = disabled;
+  this.id = id;
+  this.label = label;
+  this.submenu = submenu;
+  this.type = type;
+  this.visible = visible;
+}
+
+module.exports = MenuItem;
+
+/***/ }),
+/* 1766 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Services = __webpack_require__(22);
+const EventEmitter = __webpack_require__(1758);
+
+/**
+ * Shortcuts for lazily accessing and setting various preferences.
+ * Usage:
+ *   let prefs = new Prefs("root.path.to.branch", {
+ *     myIntPref: ["Int", "leaf.path.to.my-int-pref"],
+ *     myCharPref: ["Char", "leaf.path.to.my-char-pref"],
+ *     myJsonPref: ["Json", "leaf.path.to.my-json-pref"],
+ *     myFloatPref: ["Float", "leaf.path.to.my-float-pref"]
+ *     ...
+ *   });
+ *
+ * Get/set:
+ *   prefs.myCharPref = "foo";
+ *   let aux = prefs.myCharPref;
+ *
+ * Observe:
+ *   prefs.registerObserver();
+ *   prefs.on("pref-changed", (prefName, prefValue) => {
+ *     ...
+ *   });
+ *
+ * @param string prefsRoot
+ *        The root path to the required preferences branch.
+ * @param object prefsBlueprint
+ *        An object containing { accessorName: [prefType, prefName, prefDefault] } keys.
+ */
+function PrefsHelper(prefsRoot = "", prefsBlueprint = {}) {
+  EventEmitter.decorate(this);
+
+  let cache = new Map();
+
+  for (let accessorName in prefsBlueprint) {
+    let [prefType, prefName, prefDefault] = prefsBlueprint[accessorName];
+    map(this, cache, accessorName, prefType, prefsRoot, prefName, prefDefault);
+  }
+
+  let observer = makeObserver(this, cache, prefsRoot, prefsBlueprint);
+  this.registerObserver = () => observer.register();
+  this.unregisterObserver = () => observer.unregister();
+}
+
+/**
+ * Helper method for getting a pref value.
+ *
+ * @param Map cache
+ * @param string prefType
+ * @param string prefsRoot
+ * @param string prefName
+ * @return any
+ */
+function get(cache, prefType, prefsRoot, prefName) {
+  let cachedPref = cache.get(prefName);
+  if (cachedPref !== undefined) {
+    return cachedPref;
+  }
+  let value = Services.prefs["get" + prefType + "Pref"]([prefsRoot, prefName].join("."));
+  cache.set(prefName, value);
+  return value;
+}
+
+/**
+ * Helper method for setting a pref value.
+ *
+ * @param Map cache
+ * @param string prefType
+ * @param string prefsRoot
+ * @param string prefName
+ * @param any value
+ */
+function set(cache, prefType, prefsRoot, prefName, value) {
+  Services.prefs["set" + prefType + "Pref"]([prefsRoot, prefName].join("."), value);
+  cache.set(prefName, value);
+}
+
+/**
+ * Maps a property name to a pref, defining lazy getters and setters.
+ * Supported types are "Bool", "Char", "Int", "Float" (sugar around "Char"
+ * type and casting), and "Json" (which is basically just sugar for "Char"
+ * using the standard JSON serializer).
+ *
+ * @param PrefsHelper self
+ * @param Map cache
+ * @param string accessorName
+ * @param string prefType
+ * @param string prefsRoot
+ * @param string prefName
+ * @param string prefDefault
+ * @param array serializer [optional]
+ */
+function map(self, cache, accessorName, prefType, prefsRoot, prefName, prefDefault, serializer = { in: e => e, out: e => e }) {
+  if (prefName in self) {
+    throw new Error(`Can't use ${prefName} because it overrides a property` + "on the instance.");
+  }
+  if (prefType == "Json") {
+    map(self, cache, accessorName, "String", prefsRoot, prefName, prefDefault, {
+      in: JSON.parse,
+      out: JSON.stringify
+    });
+    return;
+  }
+  if (prefType == "Float") {
+    map(self, cache, accessorName, "Char", prefsRoot, prefName, prefDefault, {
+      in: Number.parseFloat,
+      out: n => n + ""
+    });
+    return;
+  }
+
+  Object.defineProperty(self, accessorName, {
+    get: () => {
+      try {
+        return serializer.in(get(cache, prefType, prefsRoot, prefName));
+      } catch (e) {
+        if (typeof prefDefault !== 'undefined') {
+          return prefDefault;
+        }
+        throw e;
+      }
+    },
+    set: e => set(cache, prefType, prefsRoot, prefName, serializer.out(e))
+  });
+}
+
+/**
+ * Finds the accessor for the provided pref, based on the blueprint object
+ * used in the constructor.
+ *
+ * @param PrefsHelper self
+ * @param object prefsBlueprint
+ * @return string
+ */
+function accessorNameForPref(somePrefName, prefsBlueprint) {
+  for (let accessorName in prefsBlueprint) {
+    let [, prefName] = prefsBlueprint[accessorName];
+    if (somePrefName == prefName) {
+      return accessorName;
+    }
+  }
+  return "";
+}
+
+/**
+ * Creates a pref observer for `self`.
+ *
+ * @param PrefsHelper self
+ * @param Map cache
+ * @param string prefsRoot
+ * @param object prefsBlueprint
+ * @return object
+ */
+function makeObserver(self, cache, prefsRoot, prefsBlueprint) {
+  return {
+    register: function () {
+      this._branch = Services.prefs.getBranch(prefsRoot + ".");
+      this._branch.addObserver("", this);
+    },
+    unregister: function () {
+      this._branch.removeObserver("", this);
+    },
+    observe: function (subject, topic, prefName) {
+      // If this particular pref isn't handled by the blueprint object,
+      // even though it's in the specified branch, ignore it.
+      let accessorName = accessorNameForPref(prefName, prefsBlueprint);
+      if (!(accessorName in self)) {
+        return;
+      }
+      cache.delete(prefName);
+      self.emit("pref-changed", accessorName, self[accessorName]);
+    }
+  };
+}
+
+exports.PrefsHelper = PrefsHelper;
+
+/***/ }),
+/* 1767 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 { appinfo } = __webpack_require__(22);
+const EventEmitter = __webpack_require__(1758);
+const isOSX = appinfo.OS === "Darwin";
+
+// List of electron keys mapped to DOM API (DOM_VK_*) key code
+const ElectronKeysMapping = {
+  "F1": "DOM_VK_F1",
+  "F2": "DOM_VK_F2",
+  "F3": "DOM_VK_F3",
+  "F4": "DOM_VK_F4",
+  "F5": "DOM_VK_F5",
+  "F6": "DOM_VK_F6",
+  "F7": "DOM_VK_F7",
+  "F8": "DOM_VK_F8",
+  "F9": "DOM_VK_F9",
+  "F10": "DOM_VK_F10",
+  "F11": "DOM_VK_F11",
+  "F12": "DOM_VK_F12",
+  "F13": "DOM_VK_F13",
+  "F14": "DOM_VK_F14",
+  "F15": "DOM_VK_F15",
+  "F16": "DOM_VK_F16",
+  "F17": "DOM_VK_F17",
+  "F18": "DOM_VK_F18",
+  "F19": "DOM_VK_F19",
+  "F20": "DOM_VK_F20",
+  "F21": "DOM_VK_F21",
+  "F22": "DOM_VK_F22",
+  "F23": "DOM_VK_F23",
+  "F24": "DOM_VK_F24",
+  "Space": "DOM_VK_SPACE",
+  "Backspace": "DOM_VK_BACK_SPACE",
+  "Delete": "DOM_VK_DELETE",
+  "Insert": "DOM_VK_INSERT",
+  "Return": "DOM_VK_RETURN",
+  "Enter": "DOM_VK_RETURN",
+  "Up": "DOM_VK_UP",
+  "Down": "DOM_VK_DOWN",
+  "Left": "DOM_VK_LEFT",
+  "Right": "DOM_VK_RIGHT",
+  "Home": "DOM_VK_HOME",
+  "End": "DOM_VK_END",
+  "PageUp": "DOM_VK_PAGE_UP",
+  "PageDown": "DOM_VK_PAGE_DOWN",
+  "Escape": "DOM_VK_ESCAPE",
+  "Esc": "DOM_VK_ESCAPE",
+  "Tab": "DOM_VK_TAB",
+  "VolumeUp": "DOM_VK_VOLUME_UP",
+  "VolumeDown": "DOM_VK_VOLUME_DOWN",
+  "VolumeMute": "DOM_VK_VOLUME_MUTE",
+  "PrintScreen": "DOM_VK_PRINTSCREEN"
+};
+
+/**
+ * Helper to listen for keyboard events decribed in .properties file.
+ *
+ * let shortcuts = new KeyShortcuts({
+ *   window
+ * });
+ * shortcuts.on("Ctrl+F", event => {
+ *   // `event` is the KeyboardEvent which relates to the key shortcuts
+ * });
+ *
+ * @param DOMWindow window
+ *        The window object of the document to listen events from.
+ * @param DOMElement target
+ *        Optional DOM Element on which we should listen events from.
+ *        If omitted, we listen for all events fired on `window`.
+ */
+function KeyShortcuts({ window, target }) {
+  this.window = window;
+  this.target = target || window;
+  this.keys = new Map();
+  this.eventEmitter = new EventEmitter();
+  this.target.addEventListener("keydown", this);
+}
+
+/*
+ * Parse an electron-like key string and return a normalized object which
+ * allow efficient match on DOM key event. The normalized object matches DOM
+ * API.
+ *
+ * @param DOMWindow window
+ *        Any DOM Window object, just to fetch its `KeyboardEvent` object
+ * @param String str
+ *        The shortcut string to parse, following this document:
+ *        https://github.com/electron/electron/blob/master/docs/api/accelerator.md
+ */
+KeyShortcuts.parseElectronKey = function (window, str) {
+  let modifiers = str.split("+");
+  let key = modifiers.pop();
+
+  let shortcut = {
+    ctrl: false,
+    meta: false,
+    alt: false,
+    shift: false,
+    // Set for character keys
+    key: undefined,
+    // Set for non-character keys
+    keyCode: undefined
+  };
+  for (let mod of modifiers) {
+    if (mod === "Alt") {
+      shortcut.alt = true;
+    } else if (["Command", "Cmd"].includes(mod)) {
+      shortcut.meta = true;
+    } else if (["CommandOrControl", "CmdOrCtrl"].includes(mod)) {
+      if (isOSX) {
+        shortcut.meta = true;
+      } else {
+        shortcut.ctrl = true;
+      }
+    } else if (["Control", "Ctrl"].includes(mod)) {
+      shortcut.ctrl = true;
+    } else if (mod === "Shift") {
+      shortcut.shift = true;
+    } else {
+      console.error("Unsupported modifier:", mod, "from key:", str);
+      return null;
+    }
+  }
+
+  // Plus is a special case. It's a character key and shouldn't be matched
+  // against a keycode as it is only accessible via Shift/Capslock
+  if (key === "Plus") {
+    key = "+";
+  }
+
+  if (typeof key === "string" && key.length === 1) {
+    // Match any single character
+    shortcut.key = key.toLowerCase();
+  } else if (key in ElectronKeysMapping) {
+    // Maps the others manually to DOM API DOM_VK_*
+    key = ElectronKeysMapping[key];
+    shortcut.keyCode = window.KeyboardEvent[key];
+    // Used only to stringify the shortcut
+    shortcut.keyCodeString = key;
+    shortcut.key = key;
+  } else {
+    console.error("Unsupported key:", key);
+    return null;
+  }
+
+  return shortcut;
+};
+
+KeyShortcuts.stringify = function (shortcut) {
+  let list = [];
+  if (shortcut.alt) {
+    list.push("Alt");
+  }
+  if (shortcut.ctrl) {
+    list.push("Ctrl");
+  }
+  if (shortcut.meta) {
+    list.push("Cmd");
+  }
+  if (shortcut.shift) {
+    list.push("Shift");
+  }
+  let key;
+  if (shortcut.key) {
+    key = shortcut.key.toUpperCase();
+  } else {
+    key = shortcut.keyCodeString;
+  }
+  list.push(key);
+  return list.join("+");
+};
+
+KeyShortcuts.prototype = {
+  destroy() {
+    this.target.removeEventListener("keydown", this);
+    this.keys.clear();
+  },
+
+  doesEventMatchShortcut(event, shortcut) {
+    if (shortcut.meta != event.metaKey) {
+      return false;
+    }
+    if (shortcut.ctrl != event.ctrlKey) {
+      return false;
+    }
+    if (shortcut.alt != event.altKey) {
+      return false;
+    }
+    // Shift is a special modifier, it may implicitely be required if the
+    // expected key is a special character accessible via shift.
+    if (shortcut.shift != event.shiftKey && event.key && event.key.match(/[a-zA-Z]/)) {
+      return false;
+    }
+    if (shortcut.keyCode) {
+      return event.keyCode == shortcut.keyCode;
+    } else if (event.key in ElectronKeysMapping) {
+      return ElectronKeysMapping[event.key] === shortcut.key;
+    }
+
+    // get the key from the keyCode if key is not provided.
+    let key = event.key || String.fromCharCode(event.keyCode);
+
+    // For character keys, we match if the final character is the expected one.
+    // But for digits we also accept indirect match to please azerty keyboard,
+    // which requires Shift to be pressed to get digits.
+    return key.toLowerCase() == shortcut.key || shortcut.key.match(/^[0-9]$/) && event.keyCode == shortcut.key.charCodeAt(0);
+  },
+
+  handleEvent(event) {
+    for (let [key, shortcut] of this.keys) {
+      if (this.doesEventMatchShortcut(event, shortcut)) {
+        this.eventEmitter.emit(key, event);
+      }
+    }
+  },
+
+  on(key, listener) {
+    if (typeof listener !== "function") {
+      throw new Error("KeyShortcuts.on() expects a function as " + "second argument");
+    }
+    if (!this.keys.has(key)) {
+      let shortcut = KeyShortcuts.parseElectronKey(this.window, key);
+      // The key string is wrong and we were unable to compute the key shortcut
+      if (!shortcut) {
+        return;
+      }
+      this.keys.set(key, shortcut);
+    }
+    this.eventEmitter.on(key, listener);
+  },
+
+  off(key, listener) {
+    this.eventEmitter.off(key, listener);
+  }
+};
+module.exports = KeyShortcuts;
+
+/***/ }),
+/* 1768 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 shim for "devtools/client/shared/zoom-keys" module
+ *
+ * Based on nsIMarkupDocumentViewer.fullZoom API
+ * https://developer.mozilla.org/en-US/Firefox/Releases/3/Full_page_zoom
+ */
+
+exports.register = function (window) {};
+
+/***/ }),
+/* 1769 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+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 _createClass = function () {
+    function defineProperties(target, props) {
+        for (var i = 0; i < props.length; i++) {
+            var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
+        }
+    }return function (Constructor, protoProps, staticProps) {
+        if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
+    };
+}();
+
+var _react = __webpack_require__(0);
+
+var _react2 = _interopRequireDefault(_react);
+
+var _propTypes = __webpack_require__(20);
+
+var _util = __webpack_require__(1770);
+
+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 _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+        throw new TypeError("Cannot call a class as a function");
+    }
+}
+
+function _possibleConstructorReturn(self, call) {
+    if (!self) {
+        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+    }return call && ((typeof call === "undefined" ? "undefined" : _typeof(call)) === "object" || typeof call === "function") ? call : self;
+}
+
+function _inherits(subClass, superClass) {
+    if (typeof superClass !== "function" && superClass !== null) {
+        throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : _typeof(superClass)));
+    }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
+}
+
+var process = process || { env: {} };
+
+var InlineSVG = function (_React$Component) {
+    _inherits(InlineSVG, _React$Component);
+
+    function InlineSVG() {
+        _classCallCheck(this, InlineSVG);
+
+        return _possibleConstructorReturn(this, (InlineSVG.__proto__ || Object.getPrototypeOf(InlineSVG)).apply(this, arguments));
+    }
+
+    _createClass(InlineSVG, [{
+        key: 'componentWillReceiveProps',
+        value: function componentWillReceiveProps(_ref) {
+            var children = _ref.children;
+
+            if ("production" !== process.env.NODE_ENV && children != null) {
+                console.info('<InlineSVG />: `children` prop will be ignored.');
+            }
+        }
+    }, {
+        key: 'render',
+        value: function render() {
+            var Element = void 0,
+                __html = void 0,
+                svgProps = void 0;
+
+            var _props = this.props,
+                element = _props.element,
+                raw = _props.raw,
+                src = _props.src,
+                otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
+
+            if (raw === true) {
+                Element = 'svg';
+                svgProps = (0, _util.extractSVGProps)(src);
+                __html = (0, _util.getSVGFromSource)(src).innerHTML;
+            }
+            __html = __html || src;
+            Element = Element || element;
+            svgProps = svgProps || {};
+
+            return _react2.default.createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
+                dangerouslySetInnerHTML: { __html: __html } }));
+        }
+    }]);
+
+    return InlineSVG;
+}(_react2.default.Component);
+
+exports.default = InlineSVG;
+
+InlineSVG.defaultProps = {
+    element: 'i',
+    raw: false,
+    src: ''
+};
+
+InlineSVG.propTypes = {
+    src: _propTypes.string.isRequired,
+    element: _propTypes.string,
+    raw: _propTypes.bool
+};
+
+/***/ }),
+/* 1770 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+exports.convertReactSVGDOMProperty = convertReactSVGDOMProperty;
+exports.startsWith = startsWith;
+exports.serializeAttrs = serializeAttrs;
+exports.getSVGFromSource = getSVGFromSource;
+exports.extractSVGProps = extractSVGProps;
+// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
+
+function convertReactSVGDOMProperty(str) {
+    return str.replace(/[-|:]([a-z])/g, function (g) {
+        return g[1].toUpperCase();
+    });
+}
+
+function startsWith(str, substring) {
+    return str.indexOf(substring) === 0;
+}
+
+var DataPropPrefix = 'data-';
+// Serialize `Attr` objects in `NamedNodeMap`
+function serializeAttrs(map) {
+    var ret = {};
+    for (var prop, i = 0; i < map.length; i++) {
+        var key = map[i].name;
+        if (!startsWith(key, DataPropPrefix)) {
+            prop = convertReactSVGDOMProperty(key);
+        }
+        ret[prop] = map[i].value;
+    }
+    return ret;
+}
+
+function getSVGFromSource(src) {
+    var svgContainer = document.createElement('div');
+    svgContainer.innerHTML = src;
+    var svg = svgContainer.firstElementChild;
+    svg.remove(); // deref from parent element
+    return svg;
+}
+
+// get <svg /> element props
+function extractSVGProps(src) {
+    var map = getSVGFromSource(src).attributes;
+    return map.length > 0 ? serializeAttrs(map) : null;
+}
+
+/***/ }),
+/* 1771 */
+/***/ (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.formatCallStackFrames = formatCallStackFrames;
+exports.default = getCallStackFrames;
+
+var _sources = __webpack_require__(1369);
+
+var _pause = __webpack_require__(1394);
+
+var _frame = __webpack_require__(1380);
+
+var _devtoolsSourceMap = __webpack_require__(1360);
+
+var _lodash = __webpack_require__(2);
+
+function getLocation(frame, isGeneratedSource) {
+  return isGeneratedSource ? frame.generatedLocation || frame.location : frame.location;
+}
+
+function getSourceForFrame(sources, frame, isGeneratedSource) {
+  const sourceId = getLocation(frame, isGeneratedSource).sourceId;
+  return (0, _sources.getSourceInSources)(sources, sourceId);
+}
+
+function appendSource(sources, frame, selectedSource) {
+  const isGeneratedSource = selectedSource && !(0, _devtoolsSourceMap.isOriginalId)(selectedSource.get("id"));
+  return _extends({}, frame, {
+    location: getLocation(frame, isGeneratedSource),
+    source: getSourceForFrame(sources, frame, isGeneratedSource).toJS()
+  });
+}
+
+function formatCallStackFrames(frames, sources, selectedSource) {
+  if (!frames) {
+    return null;
+  }
+
+  return frames.filter(frame => getSourceForFrame(sources, frame)).map(frame => appendSource(sources, frame, selectedSource)).filter(frame => !(0, _lodash.get)(frame, "source.isBlackBoxed")).map(_frame.annotateFrame);
+}
+
+function getCallStackFrames(state) {
+  const selectedSource = (0, _sources.getSelectedSource)(state);
+  const sources = (0, _sources.getSources)(state);
+  const frames = (0, _pause.getFrames)(state);
+
+  return formatCallStackFrames(frames, sources, selectedSource);
+}
+
+/***/ }),
+/* 1772 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = getVisibleSelectedFrame;
+
+var _sources = __webpack_require__(1369);
+
+var _pause = __webpack_require__(1394);
+
+var _devtoolsSourceMap = __webpack_require__(1360);
+
+function getLocation(frame, isGeneratedSource) {
+  return isGeneratedSource ? frame.generatedLocation || frame.location : frame.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 getVisibleSelectedFrame(state) {
+  const selectedLocation = (0, _sources.getSelectedLocation)(state);
+  const isGeneratedSource = !(0, _devtoolsSourceMap.isOriginalId)(selectedLocation.sourceId);
+  const selectedFrame = (0, _pause.getSelectedFrame)(state);
+
+  if (!selectedFrame) {
+    return;
+  }
+
+  return {
+    location: getLocation(selectedFrame, isGeneratedSource)
+  };
+}
+
+/***/ }),
+/* 1773 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.setInScopeLines = setInScopeLines;
+
+var _selectors = __webpack_require__(1352);
+
+var _source = __webpack_require__(1356);
+
+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 getOutOfScopeLines(outOfScopeLocations) {
+  if (!outOfScopeLocations) {
+    return null;
+  }
+
+  return (0, _lodash.uniq)((0, _lodash.flatMap)(outOfScopeLocations, location => (0, _lodash.range)(location.start.line, location.end.line)));
+}
+
+function setInScopeLines() {
+  return ({ dispatch, getState }) => {
+    const source = (0, _selectors.getSelectedSource)(getState());
+    const outOfScopeLocations = (0, _selectors.getOutOfScopeLocations)(getState());
+
+    if (!source || !source.get("text")) {
+      return;
+    }
+
+    const linesOutOfScope = getOutOfScopeLines(outOfScopeLocations, source.toJS());
+
+    const sourceNumLines = (0, _source.getSourceLineCount)(source.toJS());
+    const sourceLines = (0, _lodash.range)(1, sourceNumLines + 1);
+
+    const inScopeLines = !linesOutOfScope ? sourceLines : (0, _lodash.without)(sourceLines, ...linesOutOfScope);
+
+    dispatch({
+      type: "IN_SCOPE_LINES",
+      lines: inScopeLines
+    });
+  };
+}
+
+/***/ }),
+/* 1774 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.createLocation = createLocation;
+function createLocation({
+  sourceId,
+  line,
+  column,
+  sourceUrl
+}) {
+  return {
+    sourceId,
+    line: line || 0,
+    column: column || 0,
+    sourceUrl: sourceUrl || null
+  };
+}
+
+/***/ }),
+/* 1775 */
+/***/ (function(module, exports, __webpack_require__) {
+
+let updateScopeBindings = (() => {
+  var _ref = _asyncToGenerator(function* (scope, location, originalLocation, scopesDataSource) {
+    const generatedScopes = yield scopesDataSource.getSourceMapsScopes(location);
+    if (!generatedScopes) {
+      return scope;
+    }
+    const originalScopes = yield scopesDataSource.getOriginalSourceScopes(originalLocation);
+    const remapedScopes = remapScopes(originalScopes, generatedScopes);
+    return extendScope(scope, generatedScopes, 0, remapedScopes, 0);
+  });
+
+  return function updateScopeBindings(_x, _x2, _x3, _x4) {
+    return _ref.apply(this, arguments);
+  };
+})();
+
+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"); }); }; }
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 { remapScopes } = __webpack_require__(1776);
+
+function extendScope(scope, generatedScopes, index, remapedScopes, remapedScopesIndex) {
+  if (!scope) {
+    return undefined;
+  }
+  if (index >= generatedScopes.length) {
+    return scope;
+  }
+
+  let syntheticScopes;
+  if (remapedScopes && remapedScopesIndex < remapedScopes.length) {
+    if (index >= remapedScopes[remapedScopesIndex].end) {
+      remapedScopesIndex++;
+    }
+    if (remapedScopesIndex < remapedScopes.length) {
+      const remapedScope = remapedScopes[remapedScopesIndex];
+      syntheticScopes = {
+        scopes: remapedScope.scopes,
+        groupIndex: index - remapedScope.start,
+        groupLength: remapedScope.end - remapedScope.start
+      };
+    }
+  }
+
+  const parent = extendScope(scope.parent, generatedScopes, index + 1, remapedScopes, remapedScopesIndex);
+  return Object.assign({}, scope, {
+    parent,
+    sourceBindings: generatedScopes[index].bindings,
+    syntheticScopes
+  });
+}
+
+module.exports = {
+  updateScopeBindings
+};
+
+/***/ }),
+/* 1776 */
+/***/ (function(module, exports) {
+
+
+
+// Chunk split source scopes on function/closure boundary
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 rollupFunctionScopes(scopes) {
+  const { result } = scopes.reduce(({ isLast, result }, scope) => {
+    if (isLast) {
+      result.push([]);
+    }
+    result[result.length - 1].push(scope);
+    return {
+      isLast: scope.type === "function",
+      result
+    };
+  }, { isLast: true, result: [] });
+  return result;
+}
+
+function getBindingNames(summarizedScopes) {
+  return summarizedScopes.reduce((acc, { bindingsNames }) => acc.concat(bindingsNames), []);
+}
+
+// Performs mapping of the original parsed scopes to the locals mappings
+// based on the generated source parse and source map data.
+function remapScopes(scopes, generatedScopes) {
+  if (!scopes || scopes.length === 0) {
+    return null;
+  }
+  const scopeChunks = rollupFunctionScopes(scopes);
+  const { result: assigned } = scopeChunks.reduce(({ result, searchIn, searchOffset }, scopeChunk) => {
+    if (searchIn.length === 0) {
+      return { result, searchIn, searchOffset };
+    }
+    // Process chunk of original parsed scopes: create used original names
+    // binding summary per scope and entire chunk.
+    const summarizedScopes = scopeChunk.map(({ type, bindings }) => ({
+      type,
+      bindingsNames: Object.keys(bindings)
+    }));
+    const names = getBindingNames(summarizedScopes);
+    // ... and find these names in the generated scopes (with mapped
+    // original names) -- we need index of the last scope in the searchIn.
+    let foundInMax = names.reduce((max, name) => {
+      const index = searchIn.findIndex(s => name in s.bindings);
+      return index < 0 ? Math.max(index, max) : max;
+    }, 0);
+
+    // TODO double check if names were not matched/found -- the source maps
+    // and scope parsing can be broken.
+    // Moving to the function bounary (in generated scopes).
+    while (foundInMax + 1 < searchIn.length && searchIn[foundInMax].type !== "function") {
+      foundInMax++;
+    }
+
+    // We found chunk of the function(s) that contains all/most of
+    // the scopeChunk names -- adding finding to the result.
+    result.push({
+      scopes: summarizedScopes,
+      start: searchOffset,
+      end: searchOffset + foundInMax + 1
+    });
+
+    // Consuming generated scopes mappings (searchIn).
+    return {
+      result,
+      searchIn: searchIn.slice(foundInMax + 1),
+      searchOffset: searchOffset + foundInMax + 1
+    };
+  }, { result: [], searchIn: generatedScopes, searchOffset: 0 });
+  return assigned;
+}
+
+module.exports = {
+  remapScopes
+};
+
+/***/ }),
+/* 1777 */
+/***/ (function(module, exports) {
+
+module.exports = "<svg viewBox=\"0 0 9 15\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><title>Group 2</title><desc>Created with Sketch.</desc><g id=\"Symbols\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\"><g id=\"Group-2\" transform=\"translate(-3.000000, 0.000000)\" fill-rule=\"nonzero\" fill=\"#000000\"><g transform=\"translate(2.000000, 0.000000)\" id=\"path10\"><path d=\"M8.66478978,0.152329483 L6.24859226,7.23234215 L6.24859226,7.23234215 C6.22451137,7.30290469 6.14778771,7.34058551 6.07722517,7.31650462 C6.0437665,7.30508617 6.01612208,7.2809984 6.00023206,7.24941723 L2.49196511,0.276788279 L2.49196511,0.276788279 C2.4537519,0.200840088 2.3759926,0.152917255 2.29097274,0.152917255 L1.08420686,0.152917255 L1.08420686,0.152917255 C1.02897839,0.152917255 0.984206865,0.19768878 0.984206865,0.252917255 C0.984206865,0.268916365 0.988045664,0.284681937 0.99540091,0.2988901 L5.47310495,8.94849143 L5.47310495,8.94849143 C5.53346173,9.06508289 5.54553974,9.2007357 5.50673082,9.3261565 L4.0917648,13.8989752 L4.0917648,13.8989752 C4.06260539,13.9932111 3.97546399,14.0574648 3.87681975,14.0574648 L1.45804052,14.0574648 L1.45804052,14.0574648 C1.33377645,14.0574648 1.23304051,14.1582007 1.23304051,14.2824648 L1.23304051,14.775 L1.23304051,14.775 C1.23304051,14.8992641 1.33377645,15 1.45804052,15 L4.50020953,15 L4.50020953,15 C4.71271509,15 4.90200445,14.8656767 4.97216898,14.6650887 L10.0088745,0.266035474 L10.0088745,0.266035474 C10.0453448,0.161773071 9.99038856,0.0476866038 9.88612615,0.0112162185 C9.86490135,0.00379190571 9.84257651,2.78889645e-14 9.82009068,2.5895952e-14 L8.87773108,-4.83289971e-14 L8.87773108,-4.79061235e-14 C8.78147405,-5.47279145e-14 8.69587888,0.061231278 8.66478978,0.152329483 Z\" transform=\"translate(5.502176, 7.500000) scale(1, -1) translate(-5.502176, -7.500000) \"></path></g></g></g></svg>"
+
+/***/ }),
+/* 1778 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.default = renderBreakpointsDropdown;
+
+var _react = __webpack_require__(0);
+
+var _react2 = _interopRequireDefault(_react);
+
+var _Svg = __webpack_require__(1359);
+
+var _Svg2 = _interopRequireDefault(_Svg);
+
+var _Dropdown = __webpack_require__(1615);
+
+var _Dropdown2 = _interopRequireDefault(_Dropdown);
+
+var _classnames = __webpack_require__(175);
+
+var _classnames2 = _interopRequireDefault(_classnames);
+
+__webpack_require__(1779);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function renderPause(isWaitingOnBreak) {
+  const active = isWaitingOnBreak;
+  return _react2.default.createElement(
+    "div",
+    {
+      className: (0, _classnames2.default)("pause-next", {
+        active: active,
+        inactive: !active
+      })
+    },
+    _react2.default.createElement("img", { className: "pause-next" }),
+    _react2.default.createElement(
+      "span",
+      { className: "icon-spacer" },
+      L10N.getStr("pauseButtonItem")
+    )
+  );
+}
+
+function renderPauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) {
+  const active = (shouldPauseOnExceptions || shouldIgnoreCaughtExceptions) && (!shouldPauseOnExceptions || !shouldIgnoreCaughtExceptions);
+  return _react2.default.createElement(
+    "div",
+    {
+      className: (0, _classnames2.default)("pause-on-exceptions", {
+        active: active,
+        inactive: !active
+      })
+    },
+    _react2.default.createElement("img", { className: "pause-on-exceptions" }),
+    _react2.default.createElement(
+      "span",
+      { className: "icon-spacer" },
+      L10N.getStr("pauseOnExceptionsItem")
+    )
+  );
+}
+
+function renderPauseOnUncaughtExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) {
+  const active = shouldPauseOnExceptions && shouldIgnoreCaughtExceptions;
+  return _react2.default.createElement(
+    "div",
+    {
+      className: (0, _classnames2.default)("pause-uncaught-exceptions", {
+        active: active,
+        inactive: !active
+      })
+    },
+    _react2.default.createElement("img", { className: "pause-uncaught-exceptions" }),
+    _react2.default.createElement(
+      "span",
+      { className: "icon-spacer" },
+      L10N.getStr("pauseOnUncaughtExceptionsItem")
+    )
+  );
+}
+
+function renderIgnoreExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) {
+  const active = !shouldPauseOnExceptions && !shouldIgnoreCaughtExceptions;
+  return _react2.default.createElement(
+    "div",
+    {
+      className: (0, _classnames2.default)("ignore-exceptions", {
+        active: active,
+        inactive: !active
+      })
+    },
+    _react2.default.createElement("img", { className: "ignore-exceptions" }),
+    _react2.default.createElement(
+      "span",
+      { className: "icon-spacer" },
+      L10N.getStr("ignoreExceptionsItem")
+    )
+  );
+}
+
+function handleClick(e) {
+  e.stopPropagation();
+}
+
+function renderBreakpointsDropdown(breakOnNext, pauseOnExceptions, shouldPauseOnExceptions, shouldIgnoreCaughtExceptions, isWaitingOnBreak) {
+  const Panel = _react2.default.createElement(
+    "ul",
+    null,
+    _react2.default.createElement(
+      "li",
+      { onClick: () => breakOnNext(), className: "first" },
+      renderPause(isWaitingOnBreak)
+    ),
+    _react2.default.createElement(
+      "li",
+      { onClick: () => pauseOnExceptions(false, false) },
+      renderIgnoreExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions)
+    ),
+    _react2.default.createElement(
+      "li",
+      { onClick: () => pauseOnExceptions(true, true) },
+      renderPauseOnUncaughtExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions)
+    ),
+    _react2.default.createElement(
+      "li",
+      { onClick: () => pauseOnExceptions(true, false) },
+      renderPauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions)
+    )
+  );
+
+  const active = shouldPauseOnExceptions || shouldIgnoreCaughtExceptions || isWaitingOnBreak;
+
+  return _react2.default.createElement(
+    "div",
+    {
+      className: "breakpoints-dropdown",
+      onClick: e => handleClick(e),
+      key: "breakpoints-dropdown"
+    },
+    _react2.default.createElement(_Dropdown2.default, {
+      className: "dropdown",
+      panel: Panel,
+      icon: _react2.default.createElement(_Svg2.default, {
+        name: "plus",
+        className: (0, _classnames2.default)("plus", {
+          active: active,
+          inactive: !active
+        })
+      })
+    })
+  );
+}
+
+/***/ }),
+/* 1779 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 1780 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.getScopes = getScopes;
+
+var _synthesizeScopes = __webpack_require__(1781);
+
+var _getScope = __webpack_require__(1782);
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 getScopes(pauseInfo, selectedFrame, frameScopes) {
+  if (!pauseInfo || !selectedFrame) {
+    return null;
+  }
+
+  if (!frameScopes) {
+    return null;
+  }
+
+  const scopes = [];
+
+  let scope = frameScopes;
+  let scopeIndex = 1;
+
+  while (scope) {
+    const { syntheticScopes } = scope;
+    let lastScope = scope;
+
+    if (!syntheticScopes) {
+      const scopeItem = (0, _getScope.getScope)(scope, selectedFrame, frameScopes, pauseInfo, scopeIndex);
+
+      if (scopeItem) {
+        scopes.push(scopeItem);
+      }
+      scopeIndex++;
+    } else {
+      scopes.push(...(0, _synthesizeScopes.synthesizeScopes)(scope, selectedFrame, frameScopes, pauseInfo, scopeIndex));
+
+      // skip to the next generated scope
+      const scopeDepth = syntheticScopes.groupLength;
+      for (let i = 1; lastScope.parent && i < scopeDepth; i++) {
+        const nextScope = lastScope.parent;
+        lastScope = nextScope;
+      }
+
+      scope = lastScope;
+      scopeIndex += syntheticScopes.scopes.length;
+    }
+    scope = scope.parent;
+  }
+
+  return scopes;
+}
+
+/***/ }),
+/* 1781 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.synthesizeScopes = synthesizeScopes;
+
+var _getVariables = __webpack_require__(1760);
+
+var _frame = __webpack_require__(1380);
+
+var _utils = __webpack_require__(1761);
+
+function getSynteticScopeTitle(type, generatedScopes) {
+  if (type === "function") {
+    // FIXME Use original function name here
+    const lastGeneratedScope = generatedScopes[generatedScopes.length - 1];
+    const isLastGeneratedScopeFn = lastGeneratedScope && lastGeneratedScope.type === "function";
+    return isLastGeneratedScopeFn && lastGeneratedScope.function.displayName ? (0, _frame.simplifyDisplayName)(lastGeneratedScope.function.displayName) : L10N.getStr("anonymous");
+  }
+  return L10N.getStr("scopes.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/>. */
+
+function findOriginalBindings(bindingsNames, generatedScopes, key, foundGeneratedNames) {
+  return bindingsNames.reduce((vars, name) => {
+    // Find binding name in the original source bindings
+    const generatedScope = generatedScopes.find(gs => gs.sourceBindings && name in gs.sourceBindings);
+    if (!generatedScope || !generatedScope.sourceBindings) {
+      return vars;
+    }
+    // .. and map it to the generated name
+    const generatedName = generatedScope.sourceBindings[name];
+    // Skip if we already use the generated name
+    if (generatedName && !foundGeneratedNames[generatedName]) {
+      if (generatedScope.bindings.variables[generatedName]) {
+        vars.push({
+          name,
+          generatedName,
+          path: `${key}/${generatedName}`,
+          contents: generatedScope.bindings.variables[generatedName]
+        });
+        foundGeneratedNames[generatedName] = true;
+        return vars;
+      }
+
+      const arg = generatedScope.bindings.arguments.find(arg_ => arg_[generatedName]);
+      if (arg) {
+        vars.push({
+          name,
+          generatedName,
+          path: `${key}/${generatedName}`,
+          contents: arg[generatedName]
+        });
+        foundGeneratedNames[generatedName] = true;
+        return vars;
+      }
+    }
+
+    vars.push({
+      name,
+      generatedName,
+      path: `${key}/${generatedName}`,
+      contents: { value: { type: "undefined" } }
+    });
+    return vars;
+  }, []);
+}
+
+function findUnusedBindings(generatedScopes, foundGeneratedNames, key) {
+  const allGeneratedVars = generatedScopes.reduce((acc, { bindings }) => {
+    return acc.concat((0, _getVariables.getBindingVariables)(bindings, key));
+  }, []);
+  return allGeneratedVars.filter(v => !foundGeneratedNames[v.name]);
+}
+
+// Create a synthesized scope based on its binding names and
+// generated/original scopes information.
+function synthesizeScope(syntheticScope, index, actor, key, scopeIndex, lastScopeIndex, generatedScopes, foundGeneratedNames, scope, frameScopes, selectedFrame, pauseInfo) {
+  const { bindingsNames } = syntheticScope;
+  const isLast = index === lastScopeIndex;
+
+  let vars = findOriginalBindings(bindingsNames, generatedScopes, key, foundGeneratedNames);
+
+  if (isLast) {
+    // For the last synthesized scope, apply all generated names we did not use
+    vars = [...vars, ...findUnusedBindings(generatedScopes, foundGeneratedNames, key)];
+  }
+
+  if (index === 0) {
+    const isLocalScope = scope.actor === frameScopes.actor;
+
+    // For the first synthesized scope, add this and other vars.
+    if (isLocalScope) {
+      vars = [...vars, ...(0, _utils.getFramePopVariables)(pauseInfo, key)];
+
+      const this_ = (0, _utils.getThisVariable)(selectedFrame, key);
+
+      if (this_) {
+        vars.push(this_);
+      }
+    }
+  }
+
+  return vars;
+}
+
+function synthesizeScopes(scope, selectedFrame, frameScopes, pauseInfo, scopeIndex) {
+  const { actor, syntheticScopes } = scope;
+  if (!syntheticScopes) {
+    return [];
+  }
+
+  // Collect all connected generated scopes.
+  const generatedScopes = [];
+  for (let count = syntheticScopes.groupLength, s = scope; count > 0 && s; count--) {
+    generatedScopes.push(s);
+    s = s.parent;
+  }
+
+  const foundGeneratedNames = Object.create(null);
+  const lastScopeIndex = syntheticScopes.scopes.length - 1;
+  return syntheticScopes.scopes.reduce((result, syntheticScope, index) => {
+    const key = `${actor}-${scopeIndex + index}`;
+    const bindings = synthesizeScope(syntheticScope, index, actor, key, scopeIndex, lastScopeIndex, generatedScopes, foundGeneratedNames, scope, frameScopes, selectedFrame, pauseInfo);
+
+    if (bindings && bindings.length) {
+      const title = getSynteticScopeTitle(syntheticScope.type, generatedScopes);
+      bindings.sort((a, b) => a.name.localeCompare(b.name));
+      result.push({
+        name: title,
+        path: key,
+        contents: bindings
+      });
+    }
+    return result;
+  }, []);
+}
+
+/***/ }),
+/* 1782 */
+/***/ (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.getScope = getScope;
+
+var _getVariables = __webpack_require__(1760);
+
+var _utils = __webpack_require__(1761);
+
+var _frame = __webpack_require__(1380);
+
+function getScopeTitle(type, scope) {
+  if (type === "function") {
+    return scope.function.displayName ? (0, _frame.simplifyDisplayName)(scope.function.displayName) : L10N.getStr("anonymous");
+  }
+  return L10N.getStr("scopes.block");
+}
+
+function getScope(scope, selectedFrame, frameScopes, pauseInfo, scopeIndex) {
+  const { type, actor } = scope;
+
+  const isLocalScope = scope.actor === frameScopes.actor;
+
+  const key = `${actor}-${scopeIndex}`;
+  if (type === "function" || type === "block") {
+    const bindings = scope.bindings;
+    const sourceBindings = scope.sourceBindings;
+
+    let vars = sourceBindings ? (0, _getVariables.getSourceBindingVariables)(bindings, sourceBindings, key) : (0, _getVariables.getBindingVariables)(bindings, key);
+
+    // show exception, return, and this variables in innermost scope
+    if (isLocalScope) {
+      vars = vars.concat((0, _utils.getFramePopVariables)(pauseInfo, key));
+
+      const this_ = (0, _utils.getThisVariable)(selectedFrame, key);
+
+      if (this_) {
+        vars.push(this_);
+      }
+    }
+
+    if (vars && vars.length) {
+      const title = getScopeTitle(type, scope);
+      vars.sort((a, b) => a.name.localeCompare(b.name));
+      return {
+        name: title,
+        path: key,
+        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 = _extends({}, scope.object, { displayClass: "Global" });
+    }
+    return {
+      name: scope.object.class,
+      path: key,
+      contents: { value }
+    };
+  }
+
+  return null;
+}
+
 /***/ })
 /******/ ]);
 });
\ No newline at end of file
--- a/devtools/client/debugger/new/panel.js
+++ b/devtools/client/debugger/new/panel.js
@@ -93,18 +93,18 @@ DebuggerPanel.prototype = {
 
     frames.forEach(frame => {
       frame.actor = frame.id;
     });
 
     return { frames, selected };
   },
 
-  selectSource(sourceURL, sourceLine) {
-    this._actions.selectSourceURL(sourceURL, { line: sourceLine });
+  selectSource(url, line) {
+    this._actions.selectSourceURL(url, { location: { line } });
   },
 
   getSource(sourceURL) {
     return this._selectors.getSourceByURL(this._getState(), sourceURL);
   },
 
   destroy: function() {
     this.panelWin.Debugger.destroy();
--- a/devtools/client/debugger/new/parser-worker.js
+++ b/devtools/client/debugger/new/parser-worker.js
@@ -36038,20 +36038,22 @@ function extractSymbols(source) {
           expressionLocation: path.node.loc,
           expression: getSnippet(path),
           computed: path.node.computed
         });
       }
 
       if (t.isCallExpression(path)) {
         const callee = path.node.callee;
+        const args = path.node.arguments;
         if (!t.isMemberExpression(callee)) {
           const { start, end, identifierName } = callee.loc;
           callExpressions.push({
             name: identifierName,
+            values: args.filter(arg => arg.value).map(arg => arg.value),
             location: { start, end }
           });
         }
       }
 
       if (t.isIdentifier(path)) {
         let { start, end } = path.node.loc;
 
@@ -41733,35 +41735,34 @@ exports.isReactComponent = isReactCompon
 
 var _getSymbols = __webpack_require__(1457);
 
 var _getSymbols2 = _interopRequireDefault(_getSymbols);
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function isReactComponent(source) {
-  const { imports, classes } = (0, _getSymbols2.default)(source);
-
-  if (!imports || !classes) {
-    return false;
-  }
-
-  return importsReact(imports) && extendsComponent(classes);
+  const { imports, classes, callExpressions } = (0, _getSymbols2.default)(source);
+  return (importsReact(imports) || requiresReact(callExpressions)) && extendsComponent(classes);
 } /* This Source Code Form is subject to the terms of the Mozilla Public
    * License, v. 2.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 importsReact(imports) {
   return imports.some(importObj => importObj.source === "react" && importObj.specifiers.some(specifier => specifier === "React"));
 }
 
+function requiresReact(callExpressions) {
+  return callExpressions.some(callExpression => callExpression.name === "require" && callExpression.values.some(value => value === "react"));
+}
+
 function extendsComponent(classes) {
   let result = false;
   classes.some(classObj => {
-    if (classObj.parent.name === "Component" || classObj.parent.name === "PureComponent") {
+    if (classObj.parent.name === "Component" || classObj.parent.name === "PureComponent" || classObj.parent.property.name === "Component") {
       result = true;
     }
   });
 
   return result;
 }
 
 /***/ }),
--- a/devtools/client/debugger/new/pretty-print-worker.js
+++ b/devtools/client/debugger/new/pretty-print-worker.js
@@ -315,1319 +315,337 @@ function invertMappings(mappings) {
 
 self.onmessage = workerHandler({ prettyPrint });
 
 /***/ }),
 
 /***/ 381:
 /***/ (function(module, exports, __webpack_require__) {
 
-var require;var require;(function(f){if(true){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.acorn = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return require(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
-// A recursive descent parser operates by defining functions for all
-// syntactic elements, and recursively calling those, each function
-// advancing the input stream and returning an AST node. Precedence
-// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
-// instead of `(!x)[1]` is handled by the fact that the parser
-// function that parses unary prefix operators is called first, and
-// in turn calls the function that parses `[]` subscripts — that
-// way, it'll receive the node for `x[1]` already parsed, and wraps
-// *that* in the unary operator node.
-//
-// Acorn uses an [operator precedence parser][opp] to handle binary
-// operator precedence, because it is much more compact than using
-// the technique outlined above, which uses different, nesting
-// functions to specify precedence, for all of the ten binary
-// precedence levels that JavaScript defines.
-//
-// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
-
-"use strict";
-
-var _tokentype = _dereq_("./tokentype");
-
-var _state = _dereq_("./state");
-
-var pp = _state.Parser.prototype;
-
-// Check if property name clashes with already added.
-// Object/class getters and setters are not allowed to clash —
-// either with each other or with an init property — and in
-// strict mode, init properties are also not allowed to be repeated.
-
-pp.checkPropClash = function (prop, propHash) {
-  if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) return;
-  var key = prop.key;var name = undefined;
-  switch (key.type) {
-    case "Identifier":
-      name = key.name;break;
-    case "Literal":
-      name = String(key.value);break;
-    default:
-      return;
-  }
-  var kind = prop.kind;
-
-  if (this.options.ecmaVersion >= 6) {
-    if (name === "__proto__" && kind === "init") {
-      if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
-      propHash.proto = true;
-    }
-    return;
-  }
-  name = "$" + name;
-  var other = propHash[name];
-  if (other) {
-    var isGetSet = kind !== "init";
-    if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(key.start, "Redefinition of property");
-  } else {
-    other = propHash[name] = {
-      init: false,
-      get: false,
-      set: false
-    };
-  }
-  other[kind] = true;
-};
-
-// ### Expression parsing
-
-// These nest, from the most general expression type at the top to
-// 'atomic', nondivisible expression types at the bottom. Most of
-// the functions will simply let the function(s) below them parse,
-// and, *if* the syntactic construct they handle is present, wrap
-// the AST node that the inner parser gave them in another node.
-
-// Parse a full expression. The optional arguments are used to
-// forbid the `in` operator (in for loops initalization expressions)
-// and provide reference for storing '=' operator inside shorthand
-// property assignment in contexts where both object expression
-// and object pattern might appear (so it's possible to raise
-// delayed syntax error at correct position).
-
-pp.parseExpression = function (noIn, refDestructuringErrors) {
-  var startPos = this.start,
-      startLoc = this.startLoc;
-  var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
-  if (this.type === _tokentype.types.comma) {
-    var node = this.startNodeAt(startPos, startLoc);
-    node.expressions = [expr];
-    while (this.eat(_tokentype.types.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors));
-    return this.finishNode(node, "SequenceExpression");
-  }
-  return expr;
-};
-
-// Parse an assignment expression. This includes applications of
-// operators like `+=`.
-
-pp.parseMaybeAssign = function (noIn, refDestructuringErrors, afterLeftParse) {
-  if (this.type == _tokentype.types._yield && this.inGenerator) return this.parseYield();
-
-  var validateDestructuring = false;
-  if (!refDestructuringErrors) {
-    refDestructuringErrors = { shorthandAssign: 0, trailingComma: 0 };
-    validateDestructuring = true;
-  }
-  var startPos = this.start,
-      startLoc = this.startLoc;
-  if (this.type == _tokentype.types.parenL || this.type == _tokentype.types.name) this.potentialArrowAt = this.start;
-  var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
-  if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
-  if (this.type.isAssign) {
-    if (validateDestructuring) this.checkPatternErrors(refDestructuringErrors, true);
-    var node = this.startNodeAt(startPos, startLoc);
-    node.operator = this.value;
-    node.left = this.type === _tokentype.types.eq ? this.toAssignable(left) : left;
-    refDestructuringErrors.shorthandAssign = 0; // reset because shorthand default was used correctly
-    this.checkLVal(left);
-    this.next();
-    node.right = this.parseMaybeAssign(noIn);
-    return this.finishNode(node, "AssignmentExpression");
-  } else {
-    if (validateDestructuring) this.checkExpressionErrors(refDestructuringErrors, true);
-  }
-  return left;
-};
-
-// Parse a ternary conditional (`?:`) operator.
-
-pp.parseMaybeConditional = function (noIn, refDestructuringErrors) {
-  var startPos = this.start,
-      startLoc = this.startLoc;
-  var expr = this.parseExprOps(noIn, refDestructuringErrors);
-  if (this.checkExpressionErrors(refDestructuringErrors)) return expr;
-  if (this.eat(_tokentype.types.question)) {
-    var node = this.startNodeAt(startPos, startLoc);
-    node.test = expr;
-    node.consequent = this.parseMaybeAssign();
-    this.expect(_tokentype.types.colon);
-    node.alternate = this.parseMaybeAssign(noIn);
-    return this.finishNode(node, "ConditionalExpression");
-  }
-  return expr;
-};
-
-// Start the precedence parser.
-
-pp.parseExprOps = function (noIn, refDestructuringErrors) {
-  var startPos = this.start,
-      startLoc = this.startLoc;
-  var expr = this.parseMaybeUnary(refDestructuringErrors);
-  if (this.checkExpressionErrors(refDestructuringErrors)) return expr;
-  return this.parseExprOp(expr, startPos, startLoc, -1, noIn);
-};
-
-// Parse binary operators with the operator precedence parsing
-// algorithm. `left` is the left-hand side of the operator.
-// `minPrec` provides context that allows the function to stop and
-// defer further parser to one of its callers when it encounters an
-// operator that has a lower precedence than the set it is parsing.
-
-pp.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) {
-  var prec = this.type.binop;
-  if (prec != null && (!noIn || this.type !== _tokentype.types._in)) {
-    if (prec > minPrec) {
-      var node = this.startNodeAt(leftStartPos, leftStartLoc);
-      node.left = left;
-      node.operator = this.value;
-      var op = this.type;
-      this.next();
-      var startPos = this.start,
-          startLoc = this.startLoc;
-      node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn);
-      this.finishNode(node, op === _tokentype.types.logicalOR || op === _tokentype.types.logicalAND ? "LogicalExpression" : "BinaryExpression");
-      return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn);
-    }
-  }
-  return left;
-};
-
-// Parse unary operators, both prefix and postfix.
-
-pp.parseMaybeUnary = function (refDestructuringErrors) {
-  if (this.type.prefix) {
-    var node = this.startNode(),
-        update = this.type === _tokentype.types.incDec;
-    node.operator = this.value;
-    node.prefix = true;
-    this.next();
-    node.argument = this.parseMaybeUnary();
-    this.checkExpressionErrors(refDestructuringErrors, true);
-    if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
-    return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
-  }
-  var startPos = this.start,
-      startLoc = this.startLoc;
-  var expr = this.parseExprSubscripts(refDestructuringErrors);
-  if (this.checkExpressionErrors(refDestructuringErrors)) return expr;
-  while (this.type.postfix && !this.canInsertSemicolon()) {
-    var node = this.startNodeAt(startPos, startLoc);
-    node.operator = this.value;
-    node.prefix = false;
-    node.argument = expr;
-    this.checkLVal(expr);
-    this.next();
-    expr = this.finishNode(node, "UpdateExpression");
-  }
-  return expr;
-};
-
-// Parse call, dot, and `[]`-subscript expressions.
-
-pp.parseExprSubscripts = function (refDestructuringErrors) {
-  var startPos = this.start,
-      startLoc = this.startLoc;
-  var expr = this.parseExprAtom(refDestructuringErrors);
-  var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")";
-  if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr;
-  return this.parseSubscripts(expr, startPos, startLoc);
-};
-
-pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
-  for (;;) {
-    if (this.eat(_tokentype.types.dot)) {
-      var node = this.startNodeAt(startPos, startLoc);
-      node.object = base;
-      node.property = this.parseIdent(true);
-      node.computed = false;
-      base = this.finishNode(node, "MemberExpression");
-    } else if (this.eat(_tokentype.types.bracketL)) {
-      var node = this.startNodeAt(startPos, startLoc);
-      node.object = base;
-      node.property = this.parseExpression();
-      node.computed = true;
-      this.expect(_tokentype.types.bracketR);
-      base = this.finishNode(node, "MemberExpression");
-    } else if (!noCalls && this.eat(_tokentype.types.parenL)) {
-      var node = this.startNodeAt(startPos, startLoc);
-      node.callee = base;
-      node.arguments = this.parseExprList(_tokentype.types.parenR, false);
-      base = this.finishNode(node, "CallExpression");
-    } else if (this.type === _tokentype.types.backQuote) {
-      var node = this.startNodeAt(startPos, startLoc);
-      node.tag = base;
-      node.quasi = this.parseTemplate();
-      base = this.finishNode(node, "TaggedTemplateExpression");
-    } else {
-      return base;
-    }
-  }
-};
-
-// Parse an atomic expression — either a single token that is an
-// expression, an expression started by a keyword like `function` or
-// `new`, or an expression wrapped in punctuation like `()`, `[]`,
-// or `{}`.
-
-pp.parseExprAtom = function (refDestructuringErrors) {
-  var node = undefined,
-      canBeArrow = this.potentialArrowAt == this.start;
-  switch (this.type) {
-    case _tokentype.types._super:
-      if (!this.inFunction) this.raise(this.start, "'super' outside of function or class");
-    case _tokentype.types._this:
-      var type = this.type === _tokentype.types._this ? "ThisExpression" : "Super";
-      node = this.startNode();
-      this.next();
-      return this.finishNode(node, type);
-
-    case _tokentype.types._yield:
-      if (this.inGenerator) this.unexpected();
-
-    case _tokentype.types.name:
-      var startPos = this.start,
-          startLoc = this.startLoc;
-      var id = this.parseIdent(this.type !== _tokentype.types.name);
-      if (canBeArrow && !this.canInsertSemicolon() && this.eat(_tokentype.types.arrow)) return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]);
-      return id;
-
-    case _tokentype.types.regexp:
-      var value = this.value;
-      node = this.parseLiteral(value.value);
-      node.regex = { pattern: value.pattern, flags: value.flags };
-      return node;
-
-    case _tokentype.types.num:case _tokentype.types.string:
-      return this.parseLiteral(this.value);
-
-    case _tokentype.types._null:case _tokentype.types._true:case _tokentype.types._false:
-      node = this.startNode();
-      node.value = this.type === _tokentype.types._null ? null : this.type === _tokentype.types._true;
-      node.raw = this.type.keyword;
-      this.next();
-      return this.finishNode(node, "Literal");
-
-    case _tokentype.types.parenL:
-      return this.parseParenAndDistinguishExpression(canBeArrow);
-
-    case _tokentype.types.bracketL:
-      node = this.startNode();
-      this.next();
-      // check whether this is array comprehension or regular array
-      if (this.options.ecmaVersion >= 7 && this.type === _tokentype.types._for) {
-        return this.parseComprehension(node, false);
-      }
-      node.elements = this.parseExprList(_tokentype.types.bracketR, true, true, refDestructuringErrors);
-      return this.finishNode(node, "ArrayExpression");
-
-    case _tokentype.types.braceL:
-      return this.parseObj(false, refDestructuringErrors);
-
-    case _tokentype.types._function:
-      node = this.startNode();
-      this.next();
-      return this.parseFunction(node, false);
-
-    case _tokentype.types._class:
-      return this.parseClass(this.startNode(), false);
-
-    case _tokentype.types._new:
-      return this.parseNew();
-
-    case _tokentype.types.backQuote:
-      return this.parseTemplate();
-
-    default:
-      this.unexpected();
-  }
-};
-
-pp.parseLiteral = function (value) {
-  var node = this.startNode();
-  node.value = value;
-  node.raw = this.input.slice(this.start, this.end);
-  this.next();
-  return this.finishNode(node, "Literal");
-};
-
-pp.parseParenExpression = function () {
-  this.expect(_tokentype.types.parenL);
-  var val = this.parseExpression();
-  this.expect(_tokentype.types.parenR);
-  return val;
-};
-
-pp.parseParenAndDistinguishExpression = function (canBeArrow) {
-  var startPos = this.start,
-      startLoc = this.startLoc,
-      val = undefined;
-  if (this.options.ecmaVersion >= 6) {
-    this.next();
-
-    if (this.options.ecmaVersion >= 7 && this.type === _tokentype.types._for) {
-      return this.parseComprehension(this.startNodeAt(startPos, startLoc), true);
-    }
-
-    var innerStartPos = this.start,
-        innerStartLoc = this.startLoc;
-    var exprList = [],
-        first = true;
-    var refDestructuringErrors = { shorthandAssign: 0, trailingComma: 0 },
-        spreadStart = undefined,
-        innerParenStart = undefined;
-    while (this.type !== _tokentype.types.parenR) {
-      first ? first = false : this.expect(_tokentype.types.comma);
-      if (this.type === _tokentype.types.ellipsis) {
-        spreadStart = this.start;
-        exprList.push(this.parseParenItem(this.parseRest()));
-        break;
-      } else {
-        if (this.type === _tokentype.types.parenL && !innerParenStart) {
-          innerParenStart = this.start;
-        }
-        exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
-      }
-    }
-    var innerEndPos = this.start,
-        innerEndLoc = this.startLoc;
-    this.expect(_tokentype.types.parenR);
-
-    if (canBeArrow && !this.canInsertSemicolon() && this.eat(_tokentype.types.arrow)) {
-      this.checkPatternErrors(refDestructuringErrors, true);
-      if (innerParenStart) this.unexpected(innerParenStart);
-      return this.parseParenArrowList(startPos, startLoc, exprList);
-    }
-
-    if (!exprList.length) this.unexpected(this.lastTokStart);
-    if (spreadStart) this.unexpected(spreadStart);
-    this.checkExpressionErrors(refDestructuringErrors, true);
-
-    if (exprList.length > 1) {
-      val = this.startNodeAt(innerStartPos, innerStartLoc);
-      val.expressions = exprList;
-      this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
-    } else {
-      val = exprList[0];
-    }
-  } else {
-    val = this.parseParenExpression();
-  }
-
-  if (this.options.preserveParens) {
-    var par = this.startNodeAt(startPos, startLoc);
-    par.expression = val;
-    return this.finishNode(par, "ParenthesizedExpression");
-  } else {
-    return val;
-  }
-};
-
-pp.parseParenItem = function (item) {
-  return item;
-};
-
-pp.parseParenArrowList = function (startPos, startLoc, exprList) {
-  return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList);
-};
-
-// New's precedence is slightly tricky. It must allow its argument
-// to be a `[]` or dot subscript expression, but not a call — at
-// least, not without wrapping it in parentheses. Thus, it uses the
-
-var empty = [];
-
-pp.parseNew = function () {
-  var node = this.startNode();
-  var meta = this.parseIdent(true);
-  if (this.options.ecmaVersion >= 6 && this.eat(_tokentype.types.dot)) {
-    node.meta = meta;
-    node.property = this.parseIdent(true);
-    if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
-    if (!this.inFunction) this.raise(node.start, "new.target can only be used in functions");
-    return this.finishNode(node, "MetaProperty");
-  }
-  var startPos = this.start,
-      startLoc = this.startLoc;
-  node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
-  if (this.eat(_tokentype.types.parenL)) node.arguments = this.parseExprList(_tokentype.types.parenR, false);else node.arguments = empty;
-  return this.finishNode(node, "NewExpression");
-};
-
-// Parse template expression.
-
-pp.parseTemplateElement = function () {
-  var elem = this.startNode();
-  elem.value = {
-    raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'),
-    cooked: this.value
-  };
-  this.next();
-  elem.tail = this.type === _tokentype.types.backQuote;
-  return this.finishNode(elem, "TemplateElement");
-};
-
-pp.parseTemplate = function () {
-  var node = this.startNode();
-  this.next();
-  node.expressions = [];
-  var curElt = this.parseTemplateElement();
-  node.quasis = [curElt];
-  while (!curElt.tail) {
-    this.expect(_tokentype.types.dollarBraceL);
-    node.expressions.push(this.parseExpression());
-    this.expect(_tokentype.types.braceR);
-    node.quasis.push(curElt = this.parseTemplateElement());
-  }
-  this.next();
-  return this.finishNode(node, "TemplateLiteral");
-};
-
-// Parse an object literal or binding pattern.
-
-pp.parseObj = function (isPattern, refDestructuringErrors) {
-  var node = this.startNode(),
-      first = true,
-      propHash = {};
-  node.properties = [];
-  this.next();
-  while (!this.eat(_tokentype.types.braceR)) {
-    if (!first) {
-      this.expect(_tokentype.types.comma);
-      if (this.afterTrailingComma(_tokentype.types.braceR)) break;
-    } else first = false;
-
-    var prop = this.startNode(),
-        isGenerator = undefined,
-        startPos = undefined,
-        startLoc = undefined;
-    if (this.options.ecmaVersion >= 6) {
-      prop.method = false;
-      prop.shorthand = false;
-      if (isPattern || refDestructuringErrors) {
-        startPos = this.start;
-        startLoc = this.startLoc;
-      }
-      if (!isPattern) isGenerator = this.eat(_tokentype.types.star);
-    }
-    this.parsePropertyName(prop);
-    this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors);
-    this.checkPropClash(prop, propHash);
-    node.properties.push(this.finishNode(prop, "Property"));
-  }
-  return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
-};
-
-pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) {
-  if (this.eat(_tokentype.types.colon)) {
-    prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
-    prop.kind = "init";
-  } else if (this.options.ecmaVersion >= 6 && this.type === _tokentype.types.parenL) {
-    if (isPattern) this.unexpected();
-    prop.kind = "init";
-    prop.method = true;
-    prop.value = this.parseMethod(isGenerator);
-  } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.type != _tokentype.types.comma && this.type != _tokentype.types.braceR)) {
-    if (isGenerator || isPattern) this.unexpected();
-    prop.kind = prop.key.name;
-    this.parsePropertyName(prop);
-    prop.value = this.parseMethod(false);
-    var paramCount = prop.kind === "get" ? 0 : 1;
-    if (prop.value.params.length !== paramCount) {
-      var start = prop.value.start;
-      if (prop.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param");
-    }
-  } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
-    prop.kind = "init";
-    if (isPattern) {
-      if (this.keywords.test(prop.key.name) || (this.strict ? this.reservedWordsStrictBind : this.reservedWords).test(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
-      prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
-    } else if (this.type === _tokentype.types.eq && refDestructuringErrors) {
-      if (!refDestructuringErrors.shorthandAssign) refDestructuringErrors.shorthandAssign = this.start;
-      prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
-    } else {
-      prop.value = prop.key;
-    }
-    prop.shorthand = true;
-  } else this.unexpected();
-};
-
-pp.parsePropertyName = function (prop) {
-  if (this.options.ecmaVersion >= 6) {
-    if (this.eat(_tokentype.types.bracketL)) {
-      prop.computed = true;
-      prop.key = this.parseMaybeAssign();
-      this.expect(_tokentype.types.bracketR);
-      return prop.key;
-    } else {
-      prop.computed = false;
-    }
-  }
-  return prop.key = this.type === _tokentype.types.num || this.type === _tokentype.types.string ? this.parseExprAtom() : this.parseIdent(true);
-};
-
-// Initialize empty function node.
-
-pp.initFunction = function (node) {
-  node.id = null;
-  if (this.options.ecmaVersion >= 6) {
-    node.generator = false;
-    node.expression = false;
-  }
-};
-
-// Parse object or class method.
-
-pp.parseMethod = function (isGenerator) {
-  var node = this.startNode();
-  this.initFunction(node);
-  this.expect(_tokentype.types.parenL);
-  node.params = this.parseBindingList(_tokentype.types.parenR, false, false);
-  if (this.options.ecmaVersion >= 6) node.generator = isGenerator;
-  this.parseFunctionBody(node, false);
-  return this.finishNode(node, "FunctionExpression");
-};
-
-// Parse arrow function expression with given parameters.
-
-pp.parseArrowExpression = function (node, params) {
-  this.initFunction(node);
-  node.params = this.toAssignableList(params, true);
-  this.parseFunctionBody(node, true);
-  return this.finishNode(node, "ArrowFunctionExpression");
-};
-
-// Parse function body and check parameters.
-
-pp.parseFunctionBody = function (node, isArrowFunction) {
-  var isExpression = isArrowFunction && this.type !== _tokentype.types.braceL;
-
-  if (isExpression) {
-    node.body = this.parseMaybeAssign();
-    node.expression = true;
-  } else {
-    // Start a new scope with regard to labels and the `inFunction`
-    // flag (restore them to their old value afterwards).
-    var oldInFunc = this.inFunction,
-        oldInGen = this.inGenerator,
-        oldLabels = this.labels;
-    this.inFunction = true;this.inGenerator = node.generator;this.labels = [];
-    node.body = this.parseBlock(true);
-    node.expression = false;
-    this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels;
-  }
-
-  // If this is a strict mode function, verify that argument names
-  // are not repeated, and it does not try to bind the words `eval`
-  // or `arguments`.
-  if (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) {
-    var oldStrict = this.strict;
-    this.strict = true;
-    if (node.id) this.checkLVal(node.id, true);
-    this.checkParams(node);
-    this.strict = oldStrict;
-  } else if (isArrowFunction) {
-    this.checkParams(node);
-  }
-};
-
-// Checks function params for various disallowed patterns such as using "eval"
-// or "arguments" and duplicate parameters.
-
-pp.checkParams = function (node) {
-  var nameHash = {};
-  for (var i = 0; i < node.params.length; i++) {
-    this.checkLVal(node.params[i], true, nameHash);
-  }
-};
-
-// Parses a comma-separated list of expressions, and returns them as
-// an array. `close` is the token type that ends the list, and
-// `allowEmpty` can be turned on to allow subsequent commas with
-// nothing in between them to be parsed as `null` (which is needed
-// for array literals).
-
-pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
-  var elts = [],
-      first = true;
-  while (!this.eat(close)) {
-    if (!first) {
-      this.expect(_tokentype.types.comma);
-      if (this.type === close && refDestructuringErrors && !refDestructuringErrors.trailingComma) {
-        refDestructuringErrors.trailingComma = this.lastTokStart;
-      }
-      if (allowTrailingComma && this.afterTrailingComma(close)) break;
-    } else first = false;
-
-    var elt = undefined;
-    if (allowEmpty && this.type === _tokentype.types.comma) elt = null;else if (this.type === _tokentype.types.ellipsis) elt = this.parseSpread(refDestructuringErrors);else elt = this.parseMaybeAssign(false, refDestructuringErrors);
-    elts.push(elt);
-  }
-  return elts;
-};
-
-// Parse the next token as an identifier. If `liberal` is true (used
-// when parsing properties), it will also convert keywords into
-// identifiers.
-
-pp.parseIdent = function (liberal) {
-  var node = this.startNode();
-  if (liberal && this.options.allowReserved == "never") liberal = false;
-  if (this.type === _tokentype.types.name) {
-    if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1)) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
-    node.name = this.value;
-  } else if (liberal && this.type.keyword) {
-    node.name = this.type.keyword;
-  } else {
-    this.unexpected();
-  }
-  this.next();
-  return this.finishNode(node, "Identifier");
-};
-
-// Parses yield expression inside generator.
-
-pp.parseYield = function () {
-  var node = this.startNode();
-  this.next();
-  if (this.type == _tokentype.types.semi || this.canInsertSemicolon() || this.type != _tokentype.types.star && !this.type.startsExpr) {
-    node.delegate = false;
-    node.argument = null;
-  } else {
-    node.delegate = this.eat(_tokentype.types.star);
-    node.argument = this.parseMaybeAssign();
-  }
-  return this.finishNode(node, "YieldExpression");
-};
-
-// Parses array and generator comprehensions.
-
-pp.parseComprehension = function (node, isGenerator) {
-  node.blocks = [];
-  while (this.type === _tokentype.types._for) {
-    var block = this.startNode();
-    this.next();
-    this.expect(_tokentype.types.parenL);
-    block.left = this.parseBindingAtom();
-    this.checkLVal(block.left, true);
-    this.expectContextual("of");
-    block.right = this.parseExpression();
-    this.expect(_tokentype.types.parenR);
-    node.blocks.push(this.finishNode(block, "ComprehensionBlock"));
-  }
-  node.filter = this.eat(_tokentype.types._if) ? this.parseParenExpression() : null;
-  node.body = this.parseExpression();
-  this.expect(isGenerator ? _tokentype.types.parenR : _tokentype.types.bracketR);
-  node.generator = isGenerator;
-  return this.finishNode(node, "ComprehensionExpression");
-};
-
-},{"./state":10,"./tokentype":14}],2:[function(_dereq_,module,exports){
-// This is a trick taken from Esprima. It turns out that, on
-// non-Chrome browsers, to check whether a string is in a set, a
-// predicate containing a big ugly `switch` statement is faster than
-// a regular expression, and on Chrome the two are about on par.
-// This function uses `eval` (non-lexical) to produce such a
-// predicate from a space-separated string of words.
-//
-// It starts by sorting the words by length.
+(function (global, factory) {
+	 true ? factory(exports) :
+	typeof define === 'function' && define.amd ? define(['exports'], factory) :
+	(factory((global.acorn = global.acorn || {})));
+}(this, (function (exports) { 'use strict';
 
 // Reserved word lists for various dialects of the language
 
-"use strict";
-
-exports.__esModule = true;
-exports.isIdentifierStart = isIdentifierStart;
-exports.isIdentifierChar = isIdentifierChar;
 var reservedWords = {
   3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
   5: "class enum extends super const export import",
   6: "enum",
   strict: "implements interface let package private protected public static yield",
   strictBind: "eval arguments"
 };
 
-exports.reservedWords = reservedWords;
 // And the keywords
 
 var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
 
 var keywords = {
   5: ecma5AndLessKeywords,
-  6: ecma5AndLessKeywords + " let const class extends export import yield super"
-};
-
-exports.keywords = keywords;
+  6: ecma5AndLessKeywords + " const class extends export import super"
+};
+
 // ## Character categories
 
 // Big ugly regular expressions that match characters in the
 // whitespace, identifier, and identifier-start categories. These
 // are only applied when a character is found to actually have a
 // code point above 128.
 // Generated by `bin/generate-identifier-regex.js`.
 
-var nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";
-var nonASCIIidentifierChars = "‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";
+var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
+var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
 
 var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
 var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
 
 nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
 
 // These are a run-length and offset encoded representation of the
 // >0xffff code points that are a valid part of identifiers. The
 // offset starts at 0x10000, and each pair of numbers represents an
 // offset to the next range, and then a size of the range. They were
-// generated by tools/generate-identifier-regex.js
-var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 99, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 98, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 955, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 38, 17, 2, 24, 133, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 32, 4, 287, 47, 21, 1, 2, 0, 185, 46, 82, 47, 21, 0, 60, 42, 502, 63, 32, 0, 449, 56, 1288, 920, 104, 110, 2962, 1070, 13266, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 16481, 1, 3071, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 1340, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 16355, 541];
-var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 16, 9, 83, 11, 168, 11, 6, 9, 8, 2, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 316, 19, 13, 9, 214, 6, 3, 8, 112, 16, 16, 9, 82, 12, 9, 9, 535, 9, 20855, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 4305, 6, 792618, 239];
+// generated by bin/generate-identifier-regex.js
+
+// eslint-disable-next-line comma-spacing
+var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541];
+
+// eslint-disable-next-line comma-spacing
+var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239];
 
 // This has a complexity linear to the value of the code. The
 // assumption is that looking up astral identifier characters is
 // rare.
 function isInAstralSet(code, set) {
   var pos = 0x10000;
   for (var i = 0; i < set.length; i += 2) {
     pos += set[i];
-    if (pos > code) return false;
+    if (pos > code) { return false }
     pos += set[i + 1];
-    if (pos >= code) return true;
+    if (pos >= code) { return true }
   }
 }
 
 // Test whether a given character code starts an identifier.
 
 function isIdentifierStart(code, astral) {
-  if (code < 65) return code === 36;
-  if (code < 91) return true;
-  if (code < 97) return code === 95;
-  if (code < 123) return true;
-  if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
-  if (astral === false) return false;
-  return isInAstralSet(code, astralIdentifierStartCodes);
+  if (code < 65) { return code === 36 }
+  if (code < 91) { return true }
+  if (code < 97) { return code === 95 }
+  if (code < 123) { return true }
+  if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
+  if (astral === false) { return false }
+  return isInAstralSet(code, astralIdentifierStartCodes)
 }
 
 // Test whether a given character is part of an identifier.
 
 function isIdentifierChar(code, astral) {
-  if (code < 48) return code === 36;
-  if (code < 58) return true;
-  if (code < 65) return false;
-  if (code < 91) return true;
-  if (code < 97) return code === 95;
-  if (code < 123) return true;
-  if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
-  if (astral === false) return false;
-  return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
+  if (code < 48) { return code === 36 }
+  if (code < 58) { return true }
+  if (code < 65) { return false }
+  if (code < 91) { return true }
+  if (code < 97) { return code === 95 }
+  if (code < 123) { return true }
+  if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
+  if (astral === false) { return false }
+  return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
 }
 
-},{}],3:[function(_dereq_,module,exports){
-// Acorn is a tiny, fast JavaScript parser written in JavaScript.
+// ## Token types
+
+// The assignment of fine-grained, information-carrying type objects
+// allows the tokenizer to store the information it has about a
+// token in a way that is very cheap for the parser to look up.
+
+// All token type variables start with an underscore, to make them
+// easy to recognize.
+
+// The `beforeExpr` property is used to disambiguate between regular
+// expressions and divisions. It is set on all token types that can
+// be followed by an expression (thus, a slash after them would be a
+// regular expression).
 //
-// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
-// various contributors and released under an MIT license.
-//
-// Git repositories for Acorn are available at
-//
-//     http://marijnhaverbeke.nl/git/acorn
-//     https://github.com/ternjs/acorn.git
-//
-// Please use the [github bug tracker][ghbt] to report issues.
-//
-// [ghbt]: https://github.com/ternjs/acorn/issues
-//
-// This file defines the main parser interface. The library also comes
-// with a [error-tolerant parser][dammit] and an
-// [abstract syntax tree walker][walk], defined in other files.
+// The `startsExpr` property is used to check if the token ends a
+// `yield` expression. It is set on all token types that either can
+// directly start an expression (like a quotation mark) or can
+// continue an expression (like the body of a string).
 //
-// [dammit]: acorn_loose.js
-// [walk]: util/walk.js
-
-"use strict";
-
-exports.__esModule = true;
-exports.parse = parse;
-exports.parseExpressionAt = parseExpressionAt;
-exports.tokenizer = tokenizer;
-
-var _state = _dereq_("./state");
-
-_dereq_("./parseutil");
-
-_dereq_("./statement");
-
-_dereq_("./lval");
-
-_dereq_("./expression");
-
-_dereq_("./location");
-
-exports.Parser = _state.Parser;
-exports.plugins = _state.plugins;
-
-var _options = _dereq_("./options");
-
-exports.defaultOptions = _options.defaultOptions;
-
-var _locutil = _dereq_("./locutil");
-
-exports.Position = _locutil.Position;
-exports.SourceLocation = _locutil.SourceLocation;
-exports.getLineInfo = _locutil.getLineInfo;
-
-var _node = _dereq_("./node");
-
-exports.Node = _node.Node;
-
-var _tokentype = _dereq_("./tokentype");
-
-exports.TokenType = _tokentype.TokenType;
-exports.tokTypes = _tokentype.types;
-
-var _tokencontext = _dereq_("./tokencontext");
-
-exports.TokContext = _tokencontext.TokContext;
-exports.tokContexts = _tokencontext.types;
-
-var _identifier = _dereq_("./identifier");
-
-exports.isIdentifierChar = _identifier.isIdentifierChar;
-exports.isIdentifierStart = _identifier.isIdentifierStart;
-
-var _tokenize = _dereq_("./tokenize");
-
-exports.Token = _tokenize.Token;
-
-var _whitespace = _dereq_("./whitespace");
-
-exports.isNewLine = _whitespace.isNewLine;
-exports.lineBreak = _whitespace.lineBreak;
-exports.lineBreakG = _whitespace.lineBreakG;
-var version = "2.6.4";
-
-exports.version = version;
-// The main exported interface (under `self.acorn` when in the
-// browser) is a `parse` function that takes a code string and
-// returns an abstract syntax tree as specified by [Mozilla parser
-// API][api].
-//
-// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
-
-function parse(input, options) {
-  return new _state.Parser(options, input).parse();
+// `isLoop` marks a keyword as starting a loop, which is important
+// to know when parsing a label, in order to allow or disallow
+// continue jumps to that label.
+
+var TokenType = function TokenType(label, conf) {
+  if ( conf === void 0 ) conf = {};
+
+  this.label = label;
+  this.keyword = conf.keyword;
+  this.beforeExpr = !!conf.beforeExpr;
+  this.startsExpr = !!conf.startsExpr;
+  this.isLoop = !!conf.isLoop;
+  this.isAssign = !!conf.isAssign;
+  this.prefix = !!conf.prefix;
+  this.postfix = !!conf.postfix;
+  this.binop = conf.binop || null;
+  this.updateContext = null;
+};
+
+function binop(name, prec) {
+  return new TokenType(name, {beforeExpr: true, binop: prec})
+}
+var beforeExpr = {beforeExpr: true};
+var startsExpr = {startsExpr: true};
+
+// Map keyword names to token types.
+
+var keywords$1 = {};
+
+// Succinct definitions of keyword token types
+function kw(name, options) {
+  if ( options === void 0 ) options = {};
+
+  options.keyword = name;
+  return keywords$1[name] = new TokenType(name, options)
 }
 
-// This function tries to parse a single expression at a given
-// offset in a string. Useful for parsing mixed-language formats
-// that embed JavaScript expressions.
-
-function parseExpressionAt(input, pos, options) {
-  var p = new _state.Parser(options, input, pos);
-  p.nextToken();
-  return p.parseExpression();
-}
-
-// Acorn is organized as a tokenizer and a recursive-descent parser.
-// The `tokenizer` export provides an interface to the tokenizer.
-
-function tokenizer(input, options) {
-  return new _state.Parser(options, input);
+var types = {
+  num: new TokenType("num", startsExpr),
+  regexp: new TokenType("regexp", startsExpr),
+  string: new TokenType("string", startsExpr),
+  name: new TokenType("name", startsExpr),
+  eof: new TokenType("eof"),
+
+  // Punctuation token types.
+  bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
+  bracketR: new TokenType("]"),
+  braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
+  braceR: new TokenType("}"),
+  parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
+  parenR: new TokenType(")"),
+  comma: new TokenType(",", beforeExpr),
+  semi: new TokenType(";", beforeExpr),
+  colon: new TokenType(":", beforeExpr),
+  dot: new TokenType("."),
+  question: new TokenType("?", beforeExpr),
+  arrow: new TokenType("=>", beforeExpr),
+  template: new TokenType("template"),
+  invalidTemplate: new TokenType("invalidTemplate"),
+  ellipsis: new TokenType("...", beforeExpr),
+  backQuote: new TokenType("`", startsExpr),
+  dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
+
+  // Operators. These carry several kinds of properties to help the
+  // parser use them properly (the presence of these properties is
+  // what categorizes them as operators).
+  //
+  // `binop`, when present, specifies that this operator is a binary
+  // operator, and will refer to its precedence.
+  //
+  // `prefix` and `postfix` mark the operator as a prefix or postfix
+  // unary operator.
+  //
+  // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
+  // binary operators with a very low precedence, that should result
+  // in AssignmentExpression nodes.
+
+  eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
+  assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
+  incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
+  prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
+  logicalOR: binop("||", 1),
+  logicalAND: binop("&&", 2),
+  bitwiseOR: binop("|", 3),
+  bitwiseXOR: binop("^", 4),
+  bitwiseAND: binop("&", 5),
+  equality: binop("==/!=/===/!==", 6),
+  relational: binop("</>/<=/>=", 7),
+  bitShift: binop("<</>>/>>>", 8),
+  plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
+  modulo: binop("%", 10),
+  star: binop("*", 10),
+  slash: binop("/", 10),
+  starstar: new TokenType("**", {beforeExpr: true}),
+
+  // Keyword token types.
+  _break: kw("break"),
+  _case: kw("case", beforeExpr),
+  _catch: kw("catch"),
+  _continue: kw("continue"),
+  _debugger: kw("debugger"),
+  _default: kw("default", beforeExpr),
+  _do: kw("do", {isLoop: true, beforeExpr: true}),
+  _else: kw("else", beforeExpr),
+  _finally: kw("finally"),
+  _for: kw("for", {isLoop: true}),
+  _function: kw("function", startsExpr),
+  _if: kw("if"),
+  _return: kw("return", beforeExpr),
+  _switch: kw("switch"),
+  _throw: kw("throw", beforeExpr),
+  _try: kw("try"),
+  _var: kw("var"),
+  _const: kw("const"),
+  _while: kw("while", {isLoop: true}),
+  _with: kw("with"),
+  _new: kw("new", {beforeExpr: true, startsExpr: true}),
+  _this: kw("this", startsExpr),
+  _super: kw("super", startsExpr),
+  _class: kw("class", startsExpr),
+  _extends: kw("extends", beforeExpr),
+  _export: kw("export"),
+  _import: kw("import"),
+  _null: kw("null", startsExpr),
+  _true: kw("true", startsExpr),
+  _false: kw("false", startsExpr),
+  _in: kw("in", {beforeExpr: true, binop: 7}),
+  _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
+  _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
+  _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
+  _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
+};
+
+// Matches a whole line break (where CRLF is considered a single
+// line break). Used to count lines.
+
+var lineBreak = /\r\n?|\n|\u2028|\u2029/;
+var lineBreakG = new RegExp(lineBreak.source, "g");
+
+function isNewLine(code) {
+  return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
 }
 
-},{"./expression":1,"./identifier":2,"./location":4,"./locutil":5,"./lval":6,"./node":7,"./options":8,"./parseutil":9,"./state":10,"./statement":11,"./tokencontext":12,"./tokenize":13,"./tokentype":14,"./whitespace":16}],4:[function(_dereq_,module,exports){
-"use strict";
-
-var _state = _dereq_("./state");
-
-var _locutil = _dereq_("./locutil");
-
-var pp = _state.Parser.prototype;
-
-// This function is used to raise exceptions on parse errors. It
-// takes an offset integer (into the current `input`) to indicate
-// the location of the error, attaches the position to the end
-// of the error message, and then raises a `SyntaxError` with that
-// message.
-
-pp.raise = function (pos, message) {
-  var loc = _locutil.getLineInfo(this.input, pos);
-  message += " (" + loc.line + ":" + loc.column + ")";
-  var err = new SyntaxError(message);
-  err.pos = pos;err.loc = loc;err.raisedAt = this.pos;
-  throw err;
-};
-
-pp.curPosition = function () {
-  if (this.options.locations) {
-    return new _locutil.Position(this.curLine, this.pos - this.lineStart);
-  }
-};
-
-},{"./locutil":5,"./state":10}],5:[function(_dereq_,module,exports){
-"use strict";
-
-exports.__esModule = true;
-exports.getLineInfo = getLineInfo;
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var _whitespace = _dereq_("./whitespace");
+var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
+
+var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
+
+var ref = Object.prototype;
+var hasOwnProperty = ref.hasOwnProperty;
+var toString = ref.toString;
+
+// Checks if an object has a property.
+
+function has(obj, propName) {
+  return hasOwnProperty.call(obj, propName)
+}
+
+var isArray = Array.isArray || (function (obj) { return (
+  toString.call(obj) === "[object Array]"
+); });
 
 // These are used when `options.locations` is on, for the
 // `startLoc` and `endLoc` properties.
 
-var Position = (function () {
-  function Position(line, col) {
-    _classCallCheck(this, Position);
-
-    this.line = line;
-    this.column = col;
-  }
-
-  Position.prototype.offset = function offset(n) {
-    return new Position(this.line, this.column + n);
-  };
-
-  return Position;
-})();
-
-exports.Position = Position;
+var Position = function Position(line, col) {
+  this.line = line;
+  this.column = col;
+};
+
+Position.prototype.offset = function offset (n) {
+  return new Position(this.line, this.column + n)
+};
 
 var SourceLocation = function SourceLocation(p, start, end) {
-  _classCallCheck(this, SourceLocation);
-
   this.start = start;
   this.end = end;
-  if (p.sourceFile !== null) this.source = p.sourceFile;
-}
+  if (p.sourceFile !== null) { this.source = p.sourceFile; }
+};
 
 // The `getLineInfo` function is mostly useful when the
 // `locations` option is off (for performance reasons) and you
 // want to find the line/column position for a given character
 // offset. `input` should be the code string that the offset refers
 // into.
 
-;
-
-exports.SourceLocation = SourceLocation;
-
 function getLineInfo(input, offset) {
   for (var line = 1, cur = 0;;) {
-    _whitespace.lineBreakG.lastIndex = cur;
-    var match = _whitespace.lineBreakG.exec(input);
+    lineBreakG.lastIndex = cur;
+    var match = lineBreakG.exec(input);
     if (match && match.index < offset) {
       ++line;
       cur = match.index + match[0].length;
     } else {
-      return new Position(line, offset - cur);
+      return new Position(line, offset - cur)
     }
   }
 }
 
-},{"./whitespace":16}],6:[function(_dereq_,module,exports){
-"use strict";
-
-var _tokentype = _dereq_("./tokentype");
-
-var _state = _dereq_("./state");
-
-var _util = _dereq_("./util");
-
-var pp = _state.Parser.prototype;
-
-// Convert existing expression atom to assignable pattern
-// if possible.
-
-pp.toAssignable = function (node, isBinding) {
-  if (this.options.ecmaVersion >= 6 && node) {
-    switch (node.type) {
-      case "Identifier":
-      case "ObjectPattern":
-      case "ArrayPattern":
-        break;
-
-      case "ObjectExpression":
-        node.type = "ObjectPattern";
-        for (var i = 0; i < node.properties.length; i++) {
-          var prop = node.properties[i];
-          if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter");
-          this.toAssignable(prop.value, isBinding);
-        }
-        break;
-
-      case "ArrayExpression":
-        node.type = "ArrayPattern";
-        this.toAssignableList(node.elements, isBinding);
-        break;
-
-      case "AssignmentExpression":
-        if (node.operator === "=") {
-          node.type = "AssignmentPattern";
-          delete node.operator;
-          // falls through to AssignmentPattern
-        } else {
-            this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
-            break;
-          }
-
-      case "AssignmentPattern":
-        if (node.right.type === "YieldExpression") this.raise(node.right.start, "Yield expression cannot be a default value");
-        break;
-
-      case "ParenthesizedExpression":
-        node.expression = this.toAssignable(node.expression, isBinding);
-        break;
-
-      case "MemberExpression":
-        if (!isBinding) break;
-
-      default:
-        this.raise(node.start, "Assigning to rvalue");
-    }
-  }
-  return node;
-};
-
-// Convert list of expression atoms to binding list.
-
-pp.toAssignableList = function (exprList, isBinding) {
-  var end = exprList.length;
-  if (end) {
-    var last = exprList[end - 1];
-    if (last && last.type == "RestElement") {
-      --end;
-    } else if (last && last.type == "SpreadElement") {
-      last.type = "RestElement";
-      var arg = last.argument;
-      this.toAssignable(arg, isBinding);
-      if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
-      --end;
-    }
-
-    if (isBinding && last.type === "RestElement" && last.argument.type !== "Identifier") this.unexpected(last.argument.start);
-  }
-  for (var i = 0; i < end; i++) {
-    var elt = exprList[i];
-    if (elt) this.toAssignable(elt, isBinding);
-  }
-  return exprList;
-};
-
-// Parses spread element.
-
-pp.parseSpread = function (refDestructuringErrors) {
-  var node = this.startNode();
-  this.next();
-  node.argument = this.parseMaybeAssign(refDestructuringErrors);
-  return this.finishNode(node, "SpreadElement");
-};
-
-pp.parseRest = function (allowNonIdent) {
-  var node = this.startNode();
-  this.next();
-
-  // RestElement inside of a function parameter must be an identifier
-  if (allowNonIdent) node.argument = this.type === _tokentype.types.name ? this.parseIdent() : this.unexpected();else node.argument = this.type === _tokentype.types.name || this.type === _tokentype.types.bracketL ? this.parseBindingAtom() : this.unexpected();
-
-  return this.finishNode(node, "RestElement");
-};
-
-// Parses lvalue (assignable) atom.
-
-pp.parseBindingAtom = function () {
-  if (this.options.ecmaVersion < 6) return this.parseIdent();
-  switch (this.type) {
-    case _tokentype.types.name:
-      return this.parseIdent();
-
-    case _tokentype.types.bracketL:
-      var node = this.startNode();
-      this.next();
-      node.elements = this.parseBindingList(_tokentype.types.bracketR, true, true);
-      return this.finishNode(node, "ArrayPattern");
-
-    case _tokentype.types.braceL:
-      return this.parseObj(true);
-
-    default:
-      this.unexpected();
-  }
-};
-
-pp.parseBindingList = function (close, allowEmpty, allowTrailingComma, allowNonIdent) {
-  var elts = [],
-      first = true;
-  while (!this.eat(close)) {
-    if (first) first = false;else this.expect(_tokentype.types.comma);
-    if (allowEmpty && this.type === _tokentype.types.comma) {
-      elts.push(null);
-    } else if (allowTrailingComma && this.afterTrailingComma(close)) {
-      break;
-    } else if (this.type === _tokentype.types.ellipsis) {
-      var rest = this.parseRest(allowNonIdent);
-      this.parseBindingListItem(rest);
-      elts.push(rest);
-      this.expect(close);
-      break;
-    } else {
-      var elem = this.parseMaybeDefault(this.start, this.startLoc);
-      this.parseBindingListItem(elem);
-      elts.push(elem);
-    }
-  }
-  return elts;
-};
-
-pp.parseBindingListItem = function (param) {
-  return param;
-};
-
-// Parses assignment pattern around given atom if possible.
-
-pp.parseMaybeDefault = function (startPos, startLoc, left) {
-  left = left || this.parseBindingAtom();
-  if (this.options.ecmaVersion < 6 || !this.eat(_tokentype.types.eq)) return left;
-  var node = this.startNodeAt(startPos, startLoc);
-  node.left = left;
-  node.right = this.parseMaybeAssign();
-  return this.finishNode(node, "AssignmentPattern");
-};
-
-// Verify that a node is an lval — something that can be assigned
-// to.
-
-pp.checkLVal = function (expr, isBinding, checkClashes) {
-  switch (expr.type) {
-    case "Identifier":
-      if (this.strict && this.reservedWordsStrictBind.test(expr.name)) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
-      if (checkClashes) {
-        if (_util.has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash");
-        checkClashes[expr.name] = true;
-      }
-      break;
-
-    case "MemberExpression":
-      if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
-      break;
-
-    case "ObjectPattern":
-      for (var i = 0; i < expr.properties.length; i++) {
-        this.checkLVal(expr.properties[i].value, isBinding, checkClashes);
-      }break;
-
-    case "ArrayPattern":
-      for (var i = 0; i < expr.elements.length; i++) {
-        var elem = expr.elements[i];
-        if (elem) this.checkLVal(elem, isBinding, checkClashes);
-      }
-      break;
-
-    case "AssignmentPattern":
-      this.checkLVal(expr.left, isBinding, checkClashes);
-      break;
-
-    case "RestElement":
-      this.checkLVal(expr.argument, isBinding, checkClashes);
-      break;
-
-    case "ParenthesizedExpression":
-      this.checkLVal(expr.expression, isBinding, checkClashes);
-      break;
-
-    default:
-      this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
-  }
-};
-
-},{"./state":10,"./tokentype":14,"./util":15}],7:[function(_dereq_,module,exports){
-"use strict";
-
-exports.__esModule = true;
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var _state = _dereq_("./state");
-
-var _locutil = _dereq_("./locutil");
-
-var Node = function Node(parser, pos, loc) {
-  _classCallCheck(this, Node);
-
-  this.type = "";
-  this.start = pos;
-  this.end = 0;
-  if (parser.options.locations) this.loc = new _locutil.SourceLocation(parser, loc);
-  if (parser.options.directSourceFile) this.sourceFile = parser.options.directSourceFile;
-  if (parser.options.ranges) this.range = [pos, 0];
-}
-
-// Start an AST node, attaching a start offset.
-
-;
-
-exports.Node = Node;
-var pp = _state.Parser.prototype;
-
-pp.startNode = function () {
-  return new Node(this, this.start, this.startLoc);
-};
-
-pp.startNodeAt = function (pos, loc) {
-  return new Node(this, pos, loc);
-};
-
-// Finish an AST node, adding `type` and `end` properties.
-
-function finishNodeAt(node, type, pos, loc) {
-  node.type = type;
-  node.end = pos;
-  if (this.options.locations) node.loc.end = loc;
-  if (this.options.ranges) node.range[1] = pos;
-  return node;
-}
-
-pp.finishNode = function (node, type) {
-  return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc);
-};
-
-// Finish node at given position
-
-pp.finishNodeAt = function (node, type, pos, loc) {
-  return finishNodeAt.call(this, node, type, pos, loc);
-};
-
-},{"./locutil":5,"./state":10}],8:[function(_dereq_,module,exports){
-"use strict";
-
-exports.__esModule = true;
-exports.getOptions = getOptions;
-
-var _util = _dereq_("./util");
-
-var _locutil = _dereq_("./locutil");
-
 // A second optional argument can be given to further configure
 // the parser process. These options are recognized:
 
 var defaultOptions = {
   // `ecmaVersion` indicates the ECMAScript version to parse. Must
-  // be either 3, or 5, or 6. This influences support for strict
-  // mode, the set of reserved words, support for getters and
-  // setters and other features.
-  ecmaVersion: 5,
-  // Source type ("script" or "module") for different semantics
+  // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support
+  // for strict mode, the set of reserved words, and support for
+  // new syntax features. The default is 7.
+  ecmaVersion: 7,
+  // `sourceType` indicates the mode the code should be parsed in.
+  // Can be either `"script"` or `"module"`. This influences global
+  // strict mode and parsing of `import` and `export` declarations.
   sourceType: "script",
   // `onInsertedSemicolon` can be a callback that will be called
   // when a semicolon is automatically inserted. It will be passed
   // th position of the comma as an offset, and if `locations` is
   // enabled, it is given the location as a `{line, column}` object
   // as second argument.
   onInsertedSemicolon: null,
   // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
@@ -1691,1970 +709,3388 @@ var defaultOptions = {
   // `locations` is on or off.
   directSourceFile: null,
   // When enabled, parenthesized expressions are represented by
   // (non-standard) ParenthesizedExpression nodes
   preserveParens: false,
   plugins: {}
 };
 
-exports.defaultOptions = defaultOptions;
 // Interpret and default an options object
 
 function getOptions(opts) {
   var options = {};
-  for (var opt in defaultOptions) {
-    options[opt] = opts && _util.has(opts, opt) ? opts[opt] : defaultOptions[opt];
-  }if (options.allowReserved == null) options.allowReserved = options.ecmaVersion < 5;
-
-  if (_util.isArray(options.onToken)) {
-    (function () {
-      var tokens = options.onToken;
-      options.onToken = function (token) {
-        return tokens.push(token);
-      };
-    })();
-  }
-  if (_util.isArray(options.onComment)) options.onComment = pushComment(options, options.onComment);
-
-  return options;
+
+  for (var opt in defaultOptions)
+    { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }
+
+  if (options.ecmaVersion >= 2015)
+    { options.ecmaVersion -= 2009; }
+
+  if (options.allowReserved == null)
+    { options.allowReserved = options.ecmaVersion < 5; }
+
+  if (isArray(options.onToken)) {
+    var tokens = options.onToken;
+    options.onToken = function (token) { return tokens.push(token); };
+  }
+  if (isArray(options.onComment))
+    { options.onComment = pushComment(options, options.onComment); }
+
+  return options
 }
 
 function pushComment(options, array) {
-  return function (block, text, start, end, startLoc, endLoc) {
+  return function(block, text, start, end, startLoc, endLoc) {
     var comment = {
-      type: block ? 'Block' : 'Line',
+      type: block ? "Block" : "Line",
       value: text,
       start: start,
       end: end
     };
-    if (options.locations) comment.loc = new _locutil.SourceLocation(this, startLoc, endLoc);
-    if (options.ranges) comment.range = [start, end];
+    if (options.locations)
+      { comment.loc = new SourceLocation(this, startLoc, endLoc); }
+    if (options.ranges)
+      { comment.range = [start, end]; }
     array.push(comment);
-  };
+  }
+}
+
+// Registered plugins
+var plugins = {};
+
+function keywordRegexp(words) {
+  return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
 }
 
-},{"./locutil":5,"./util":15}],9:[function(_dereq_,module,exports){
-"use strict";
-
-var _tokentype = _dereq_("./tokentype");
-
-var _state = _dereq_("./state");
-
-var _whitespace = _dereq_("./whitespace");
-
-var pp = _state.Parser.prototype;
+var Parser = function Parser(options, input, startPos) {
+  this.options = options = getOptions(options);
+  this.sourceFile = options.sourceFile;
+  this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]);
+  var reserved = "";
+  if (!options.allowReserved) {
+    for (var v = options.ecmaVersion;; v--)
+      { if (reserved = reservedWords[v]) { break } }
+    if (options.sourceType == "module") { reserved += " await"; }
+  }
+  this.reservedWords = keywordRegexp(reserved);
+  var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
+  this.reservedWordsStrict = keywordRegexp(reservedStrict);
+  this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind);
+  this.input = String(input);
+
+  // Used to signal to callers of `readWord1` whether the word
+  // contained any escape sequences. This is needed because words with
+  // escape sequences must not be interpreted as keywords.
+  this.containsEsc = false;
+
+  // Load plugins
+  this.loadPlugins(options.plugins);
+
+  // Set up token state
+
+  // The current position of the tokenizer in the input.
+  if (startPos) {
+    this.pos = startPos;
+    this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
+    this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
+  } else {
+    this.pos = this.lineStart = 0;
+    this.curLine = 1;
+  }
+
+  // Properties of the current token:
+  // Its type
+  this.type = types.eof;
+  // For tokens that include more information than their type, the value
+  this.value = null;
+  // Its start and end offset
+  this.start = this.end = this.pos;
+  // And, if locations are used, the {line, column} object
+  // corresponding to those offsets
+  this.startLoc = this.endLoc = this.curPosition();
+
+  // Position information for the previous token
+  this.lastTokEndLoc = this.lastTokStartLoc = null;
+  this.lastTokStart = this.lastTokEnd = this.pos;
+
+  // The context stack is used to superficially track syntactic
+  // context to predict whether a regular expression is allowed in a
+  // given position.
+  this.context = this.initialContext();
+  this.exprAllowed = true;
+
+  // Figure out if it's a module code.
+  this.inModule = options.sourceType === "module";
+  this.strict = this.inModule || this.strictDirective(this.pos);
+
+  // Used to signify the start of a potential arrow function
+  this.potentialArrowAt = -1;
+
+  // Flags to track whether we are in a function, a generator, an async function.
+  this.inFunction = this.inGenerator = this.inAsync = false;
+  // Positions to delayed-check that yield/await does not exist in default parameters.
+  this.yieldPos = this.awaitPos = 0;
+  // Labels in scope.
+  this.labels = [];
+
+  // If enabled, skip leading hashbang line.
+  if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
+    { this.skipLineComment(2); }
+
+  // Scope tracking for duplicate variable names (see scope.js)
+  this.scopeStack = [];
+  this.enterFunctionScope();
+};
+
+// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
+Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) };
+Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) };
+
+Parser.prototype.extend = function extend (name, f) {
+  this[name] = f(this[name]);
+};
+
+Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {
+    var this$1 = this;
+
+  for (var name in pluginConfigs) {
+    var plugin = plugins[name];
+    if (!plugin) { throw new Error("Plugin '" + name + "' not found") }
+    plugin(this$1, pluginConfigs[name]);
+  }
+};
+
+Parser.prototype.parse = function parse () {
+  var node = this.options.program || this.startNode();
+  this.nextToken();
+  return this.parseTopLevel(node)
+};
+
+var pp = Parser.prototype;
 
 // ## Parser utilities
 
-// Test whether a statement node is the string literal `"use strict"`.
-
-pp.isUseStrict = function (stmt) {
-  return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.raw.slice(1, -1) === "use strict";
+var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/;
+pp.strictDirective = function(start) {
+  var this$1 = this;
+
+  for (;;) {
+    skipWhiteSpace.lastIndex = start;
+    start += skipWhiteSpace.exec(this$1.input)[0].length;
+    var match = literal.exec(this$1.input.slice(start));
+    if (!match) { return false }
+    if ((match[1] || match[2]) == "use strict") { return true }
+    start += match[0].length;
+  }
 };
 
 // Predicate that tests whether the next token is of the given
 // type, and if yes, consumes it as a side effect.
 
-pp.eat = function (type) {
+pp.eat = function(type) {
   if (this.type === type) {
     this.next();
-    return true;
+    return true
   } else {
-    return false;
+    return false
   }
 };
 
 // Tests whether parsed token is a contextual keyword.
 
-pp.isContextual = function (name) {
-  return this.type === _tokentype.types.name && this.value === name;
+pp.isContextual = function(name) {
+  return this.type === types.name && this.value === name
 };
 
 // Consumes contextual keyword if possible.
 
-pp.eatContextual = function (name) {
-  return this.value === name && this.eat(_tokentype.types.name);
+pp.eatContextual = function(name) {
+  return this.value === name && this.eat(types.name)
 };
 
 // Asserts that following token is given contextual keyword.
 
-pp.expectContextual = function (name) {
-  if (!this.eatContextual(name)) this.unexpected();
+pp.expectContextual = function(name) {
+  if (!this.eatContextual(name)) { this.unexpected(); }
 };
 
 // Test whether a semicolon can be inserted at the current position.
 
-pp.canInsertSemicolon = function () {
-  return this.type === _tokentype.types.eof || this.type === _tokentype.types.braceR || _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
-};
-
-pp.insertSemicolon = function () {
+pp.canInsertSemicolon = function() {
+  return this.type === types.eof ||
+    this.type === types.braceR ||
+    lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
+};
+
+pp.insertSemicolon = function() {
   if (this.canInsertSemicolon()) {
-    if (this.options.onInsertedSemicolon) this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc);
-    return true;
+    if (this.options.onInsertedSemicolon)
+      { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
+    return true
   }
 };
 
 // Consume a semicolon, or, failing that, see if we are allowed to
 // pretend that there is a semicolon at this position.
 
-pp.semicolon = function () {
-  if (!this.eat(_tokentype.types.semi) && !this.insertSemicolon()) this.unexpected();
-};
-
-pp.afterTrailingComma = function (tokType) {
+pp.semicolon = function() {
+  if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }
+};
+
+pp.afterTrailingComma = function(tokType, notNext) {
   if (this.type == tokType) {
-    if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc);
-    this.next();
-    return true;
+    if (this.options.onTrailingComma)
+      { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
+    if (!notNext)
+      { this.next(); }
+    return true
   }
 };
 
 // Expect a token of a given type. If found, consume it, otherwise,
 // raise an unexpected token error.
 
-pp.expect = function (type) {
+pp.expect = function(type) {
   this.eat(type) || this.unexpected();
 };
 
 // Raise an unexpected token error.
 
-pp.unexpected = function (pos) {
+pp.unexpected = function(pos) {
   this.raise(pos != null ? pos : this.start, "Unexpected token");
 };
 
-pp.checkPatternErrors = function (refDestructuringErrors, andThrow) {
-  var pos = refDestructuringErrors && refDestructuringErrors.trailingComma;
-  if (!andThrow) return !!pos;
-  if (pos) this.raise(pos, "Trailing comma is not permitted in destructuring patterns");
-};
-
-pp.checkExpressionErrors = function (refDestructuringErrors, andThrow) {
-  var pos = refDestructuringErrors && refDestructuringErrors.shorthandAssign;
-  if (!andThrow) return !!pos;
-  if (pos) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns");
-};
-
-},{"./state":10,"./tokentype":14,"./whitespace":16}],10:[function(_dereq_,module,exports){
-"use strict";
-
-exports.__esModule = true;
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var _identifier = _dereq_("./identifier");
-
-var _tokentype = _dereq_("./tokentype");
-
-var _whitespace = _dereq_("./whitespace");
-
-var _options = _dereq_("./options");
-
-// Registered plugins
-var plugins = {};
-
-exports.plugins = plugins;
-function keywordRegexp(words) {
-  return new RegExp("^(" + words.replace(/ /g, "|") + ")$");
+function DestructuringErrors() {
+  this.shorthandAssign =
+  this.trailingComma =
+  this.parenthesizedAssign =
+  this.parenthesizedBind =
+    -1;
 }
 
-var Parser = (function () {
-  function Parser(options, input, startPos) {
-    _classCallCheck(this, Parser);
-
-    this.options = options = _options.getOptions(options);
-    this.sourceFile = options.sourceFile;
-    this.keywords = keywordRegexp(_identifier.keywords[options.ecmaVersion >= 6 ? 6 : 5]);
-    var reserved = options.allowReserved ? "" : _identifier.reservedWords[options.ecmaVersion] + (options.sourceType == "module" ? " await" : "");
-    this.reservedWords = keywordRegexp(reserved);
-    var reservedStrict = (reserved ? reserved + " " : "") + _identifier.reservedWords.strict;
-    this.reservedWordsStrict = keywordRegexp(reservedStrict);
-    this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + _identifier.reservedWords.strictBind);
-    this.input = String(input);
-
-    // Used to signal to callers of `readWord1` whether the word
-    // contained any escape sequences. This is needed because words with
-    // escape sequences must not be interpreted as keywords.
-    this.containsEsc = false;
-
-    // Load plugins
-    this.loadPlugins(options.plugins);
-
-    // Set up token state
-
-    // The current position of the tokenizer in the input.
-    if (startPos) {
-      this.pos = startPos;
-      this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos));
-      this.curLine = this.input.slice(0, this.lineStart).split(_whitespace.lineBreak).length;
-    } else {
-      this.pos = this.lineStart = 0;
-      this.curLine = 1;
-    }
-
-    // Properties of the current token:
-    // Its type
-    this.type = _tokentype.types.eof;
-    // For tokens that include more information than their type, the value
-    this.value = null;
-    // Its start and end offset
-    this.start = this.end = this.pos;
-    // And, if locations are used, the {line, column} object
-    // corresponding to those offsets
-    this.startLoc = this.endLoc = this.curPosition();
-
-    // Position information for the previous token
-    this.lastTokEndLoc = this.lastTokStartLoc = null;
-    this.lastTokStart = this.lastTokEnd = this.pos;
-
-    // The context stack is used to superficially track syntactic
-    // context to predict whether a regular expression is allowed in a
-    // given position.
-    this.context = this.initialContext();
-    this.exprAllowed = true;
-
-    // Figure out if it's a module code.
-    this.strict = this.inModule = options.sourceType === "module";
-
-    // Used to signify the start of a potential arrow function
-    this.potentialArrowAt = -1;
-
-    // Flags to track whether we are in a function, a generator.
-    this.inFunction = this.inGenerator = false;
-    // Labels in scope.
-    this.labels = [];
-
-    // If enabled, skip leading hashbang line.
-    if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') this.skipLineComment(2);
-  }
-
-  // DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
-
-  Parser.prototype.isKeyword = function isKeyword(word) {
-    return this.keywords.test(word);
-  };
-
-  Parser.prototype.isReservedWord = function isReservedWord(word) {
-    return this.reservedWords.test(word);
-  };
-
-  Parser.prototype.extend = function extend(name, f) {
-    this[name] = f(this[name]);
-  };
-
-  Parser.prototype.loadPlugins = function loadPlugins(pluginConfigs) {
-    for (var _name in pluginConfigs) {
-      var plugin = plugins[_name];
-      if (!plugin) throw new Error("Plugin '" + _name + "' not found");
-      plugin(this, pluginConfigs[_name]);
-    }
-  };
-
-  Parser.prototype.parse = function parse() {
-    var node = this.options.program || this.startNode();
-    this.nextToken();
-    return this.parseTopLevel(node);
-  };
-
-  return Parser;
-})();
-
-exports.Parser = Parser;
-
-},{"./identifier":2,"./options":8,"./tokentype":14,"./whitespace":16}],11:[function(_dereq_,module,exports){
-"use strict";
-
-var _tokentype = _dereq_("./tokentype");
-
-var _state = _dereq_("./state");
-
-var _whitespace = _dereq_("./whitespace");
-
-var pp = _state.Parser.prototype;
+pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
+  if (!refDestructuringErrors) { return }
+  if (refDestructuringErrors.trailingComma > -1)
+    { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
+  var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
+  if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); }
+};
+
+pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
+  var pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1;
+  if (!andThrow) { return pos >= 0 }
+  if (pos > -1) { this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns"); }
+};
+
+pp.checkYieldAwaitInDefaultParams = function() {
+  if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
+    { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
+  if (this.awaitPos)
+    { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
+};
+
+pp.isSimpleAssignTarget = function(expr) {
+  if (expr.type === "ParenthesizedExpression")
+    { return this.isSimpleAssignTarget(expr.expression) }
+  return expr.type === "Identifier" || expr.type === "MemberExpression"
+};
+
+var pp$1 = Parser.prototype;
 
 // ### Statement parsing
 
 // Parse a program. Initializes the parser, reads any number of
 // statements, and wraps them in a Program node.  Optionally takes a
 // `program` argument.  If present, the statements will be appended
 // to its body instead of creating a new node.
 
-pp.parseTopLevel = function (node) {
-  var first = true;
-  if (!node.body) node.body = [];
-  while (this.type !== _tokentype.types.eof) {
-    var stmt = this.parseStatement(true, true);
+pp$1.parseTopLevel = function(node) {
+  var this$1 = this;
+
+  var exports = {};
+  if (!node.body) { node.body = []; }
+  while (this.type !== types.eof) {
+    var stmt = this$1.parseStatement(true, true, exports);
     node.body.push(stmt);
-    if (first) {
-      if (this.isUseStrict(stmt)) this.setStrict(true);
-      first = false;
-    }
-  }
+  }
+  this.adaptDirectivePrologue(node.body);
   this.next();
   if (this.options.ecmaVersion >= 6) {
     node.sourceType = this.options.sourceType;
   }
-  return this.finishNode(node, "Program");
-};
-
-var loopLabel = { kind: "loop" },
-    switchLabel = { kind: "switch" };
+  return this.finishNode(node, "Program")
+};
+
+var loopLabel = {kind: "loop"};
+var switchLabel = {kind: "switch"};
+
+pp$1.isLet = function() {
+  if (this.type !== types.name || this.options.ecmaVersion < 6 || this.value != "let") { return false }
+  skipWhiteSpace.lastIndex = this.pos;
+  var skip = skipWhiteSpace.exec(this.input);
+  var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
+  if (nextCh === 91 || nextCh == 123) { return true } // '{' and '['
+  if (isIdentifierStart(nextCh, true)) {
+    var pos = next + 1;
+    while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
+    var ident = this.input.slice(next, pos);
+    if (!this.isKeyword(ident)) { return true }
+  }
+  return false
+};
+
+// check 'async [no LineTerminator here] function'
+// - 'async /*foo*/ function' is OK.
+// - 'async /*\n*/ function' is invalid.
+pp$1.isAsyncFunction = function() {
+  if (this.type !== types.name || this.options.ecmaVersion < 8 || this.value != "async")
+    { return false }
+
+  skipWhiteSpace.lastIndex = this.pos;
+  var skip = skipWhiteSpace.exec(this.input);
+  var next = this.pos + skip[0].length;
+  return !lineBreak.test(this.input.slice(this.pos, next)) &&
+    this.input.slice(next, next + 8) === "function" &&
+    (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
+};
 
 // Parse a single statement.
 //
 // If expecting a statement and finding a slash operator, parse a
 // regular expression literal. This is to handle cases like
 // `if (foo) /blah/.exec(foo)`, where looking at the previous token
 // does not help.
 
-pp.parseStatement = function (declaration, topLevel) {
-  var starttype = this.type,
-      node = this.startNode();
+pp$1.parseStatement = function(declaration, topLevel, exports) {
+  var starttype = this.type, node = this.startNode(), kind;
+
+  if (this.isLet()) {
+    starttype = types._var;
+    kind = "let";
+  }
 
   // Most types of statements are recognized by the keyword they
   // start with. Many are trivial to parse, some require a bit of
   // complexity.
 
   switch (starttype) {
-    case _tokentype.types._break:case _tokentype.types._continue:
-      return this.parseBreakContinueStatement(node, starttype.keyword);
-    case _tokentype.types._debugger:
-      return this.parseDebuggerStatement(node);
-    case _tokentype.types._do:
-      return this.parseDoStatement(node);
-    case _tokentype.types._for:
-      return this.parseForStatement(node);
-    case _tokentype.types._function:
-      if (!declaration && this.options.ecmaVersion >= 6) this.unexpected();
-      return this.parseFunctionStatement(node);
-    case _tokentype.types._class:
-      if (!declaration) this.unexpected();
-      return this.parseClass(node, true);
-    case _tokentype.types._if:
-      return this.parseIfStatement(node);
-    case _tokentype.types._return:
-      return this.parseReturnStatement(node);
-    case _tokentype.types._switch:
-      return this.parseSwitchStatement(node);
-    case _tokentype.types._throw:
-      return this.parseThrowStatement(node);
-    case _tokentype.types._try:
-      return this.parseTryStatement(node);
-    case _tokentype.types._let:case _tokentype.types._const:
-      if (!declaration) this.unexpected(); // NOTE: falls through to _var
-    case _tokentype.types._var:
-      return this.parseVarStatement(node, starttype);
-    case _tokentype.types._while:
-      return this.parseWhileStatement(node);
-    case _tokentype.types._with:
-      return this.parseWithStatement(node);
-    case _tokentype.types.braceL:
-      return this.parseBlock();
-    case _tokentype.types.semi:
-      return this.parseEmptyStatement(node);
-    case _tokentype.types._export:
-    case _tokentype.types._import:
-      if (!this.options.allowImportExportEverywhere) {
-        if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
-        if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
-      }
-      return starttype === _tokentype.types._import ? this.parseImport(node) : this.parseExport(node);
+  case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
+  case types._debugger: return this.parseDebuggerStatement(node)
+  case types._do: return this.parseDoStatement(node)
+  case types._for: return this.parseForStatement(node)
+  case types._function:
+    if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); }
+    return this.parseFunctionStatement(node, false)
+  case types._class:
+    if (!declaration) { this.unexpected(); }
+    return this.parseClass(node, true)
+  case types._if: return this.parseIfStatement(node)
+  case types._return: return this.parseReturnStatement(node)
+  case types._switch: return this.parseSwitchStatement(node)
+  case types._throw: return this.parseThrowStatement(node)
+  case types._try: return this.parseTryStatement(node)
+  case types._const: case types._var:
+    kind = kind || this.value;
+    if (!declaration && kind != "var") { this.unexpected(); }
+    return this.parseVarStatement(node, kind)
+  case types._while: return this.parseWhileStatement(node)
+  case types._with: return this.parseWithStatement(node)
+  case types.braceL: return this.parseBlock()
+  case types.semi: return this.parseEmptyStatement(node)
+  case types._export:
+  case types._import:
+    if (!this.options.allowImportExportEverywhere) {
+      if (!topLevel)
+        { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
+      if (!this.inModule)
+        { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
+    }
+    return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)
 
     // If the statement does not start with a statement keyword or a
     // brace, it's an ExpressionStatement or LabeledStatement. We
     // simply start parsing an expression, and afterwards, if the
     // next token is a colon and the expression was a simple
     // Identifier node, we switch to interpreting it as a label.
-    default:
-      var maybeName = this.value,
-          expr = this.parseExpression();
-      if (starttype === _tokentype.types.name && expr.type === "Identifier" && this.eat(_tokentype.types.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr);
-  }
-};
-
-pp.parseBreakContinueStatement = function (node, keyword) {
+  default:
+    if (this.isAsyncFunction() && declaration) {
+      this.next();
+      return this.parseFunctionStatement(node, true)
+    }
+
+    var maybeName = this.value, expr = this.parseExpression();
+    if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon))
+      { return this.parseLabeledStatement(node, maybeName, expr) }
+    else { return this.parseExpressionStatement(node, expr) }
+  }
+};
+
+pp$1.parseBreakContinueStatement = function(node, keyword) {
+  var this$1 = this;
+
   var isBreak = keyword == "break";
   this.next();
-  if (this.eat(_tokentype.types.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== _tokentype.types.name) this.unexpected();else {
+  if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }
+  else if (this.type !== types.name) { this.unexpected(); }
+  else {
     node.label = this.parseIdent();
     this.semicolon();
   }
 
   // Verify that there is an actual destination to break or
   // continue to.
-  for (var i = 0; i < this.labels.length; ++i) {
-    var lab = this.labels[i];
+  var i = 0;
+  for (; i < this.labels.length; ++i) {
+    var lab = this$1.labels[i];
     if (node.label == null || lab.name === node.label.name) {
-      if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
-      if (node.label && isBreak) break;
-    }
-  }
-  if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
-  return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
-};
-
-pp.parseDebuggerStatement = function (node) {
+      if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
+      if (node.label && isBreak) { break }
+    }
+  }
+  if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
+  return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
+};
+
+pp$1.parseDebuggerStatement = function(node) {
   this.next();
   this.semicolon();
-  return this.finishNode(node, "DebuggerStatement");
-};
-
-pp.parseDoStatement = function (node) {
+  return this.finishNode(node, "DebuggerStatement")
+};
+
+pp$1.parseDoStatement = function(node) {
   this.next();
   this.labels.push(loopLabel);
   node.body = this.parseStatement(false);
   this.labels.pop();
-  this.expect(_tokentype.types._while);
+  this.expect(types._while);
   node.test = this.parseParenExpression();
-  if (this.options.ecmaVersion >= 6) this.eat(_tokentype.types.semi);else this.semicolon();
-  return this.finishNode(node, "DoWhileStatement");
+  if (this.options.ecmaVersion >= 6)
+    { this.eat(types.semi); }
+  else
+    { this.semicolon(); }
+  return this.finishNode(node, "DoWhileStatement")
 };
 
 // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
 // loop is non-trivial. Basically, we have to parse the init `var`
 // statement or expression, disallowing the `in` operator (see
 // the second parameter to `parseExpression`), and then check
 // whether the next token is `in` or `of`. When there is no init
 // part (semicolon immediately after the opening parenthesis), it
 // is a regular `for` loop.
 
-pp.parseForStatement = function (node) {
+pp$1.parseForStatement = function(node) {
   this.next();
   this.labels.push(loopLabel);
-  this.expect(_tokentype.types.parenL);
-  if (this.type === _tokentype.types.semi) return this.parseFor(node, null);
-  if (this.type === _tokentype.types._var || this.type === _tokentype.types._let || this.type === _tokentype.types._const) {
-    var _init = this.startNode(),
-        varKind = this.type;
+  this.enterLexicalScope();
+  this.expect(types.parenL);
+  if (this.type === types.semi) { return this.parseFor(node, null) }
+  var isLet = this.isLet();
+  if (this.type === types._var || this.type === types._const || isLet) {
+    var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
     this.next();
-    this.parseVar(_init, true, varKind);
-    this.finishNode(_init, "VariableDeclaration");
-    if ((this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== _tokentype.types._var && _init.declarations[0].init)) return this.parseForIn(node, _init);
-    return this.parseFor(node, _init);
-  }
-  var refDestructuringErrors = { shorthandAssign: 0, trailingComma: 0 };
+    this.parseVar(init$1, true, kind);
+    this.finishNode(init$1, "VariableDeclaration");
+    if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 &&
+        !(kind !== "var" && init$1.declarations[0].init))
+      { return this.parseForIn(node, init$1) }
+    return this.parseFor(node, init$1)
+  }
+  var refDestructuringErrors = new DestructuringErrors;
   var init = this.parseExpression(true, refDestructuringErrors);
-  if (this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
-    this.checkPatternErrors(refDestructuringErrors, true);
+  if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
     this.toAssignable(init);
     this.checkLVal(init);
-    return this.parseForIn(node, init);
+    this.checkPatternErrors(refDestructuringErrors, true);
+    return this.parseForIn(node, init)
   } else {
     this.checkExpressionErrors(refDestructuringErrors, true);
   }
-  return this.parseFor(node, init);
-};
-
-pp.parseFunctionStatement = function (node) {
+  return this.parseFor(node, init)
+};
+
+pp$1.parseFunctionStatement = function(node, isAsync) {
   this.next();
-  return this.parseFunction(node, true);
-};
-
-pp.parseIfStatement = function (node) {
+  return this.parseFunction(node, true, false, isAsync)
+};
+
+pp$1.isFunction = function() {
+  return this.type === types._function || this.isAsyncFunction()
+};
+
+pp$1.parseIfStatement = function(node) {
   this.next();
   node.test = this.parseParenExpression();
-  node.consequent = this.parseStatement(false);
-  node.alternate = this.eat(_tokentype.types._else) ? this.parseStatement(false) : null;
-  return this.finishNode(node, "IfStatement");
-};
-
-pp.parseReturnStatement = function (node) {
-  if (!this.inFunction && !this.options.allowReturnOutsideFunction) this.raise(this.start, "'return' outside of function");
+  // allow function declarations in branches, but only in non-strict mode
+  node.consequent = this.parseStatement(!this.strict && this.isFunction());
+  node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.isFunction()) : null;
+  return this.finishNode(node, "IfStatement")
+};
+
+pp$1.parseReturnStatement = function(node) {
+  if (!this.inFunction && !this.options.allowReturnOutsideFunction)
+    { this.raise(this.start, "'return' outside of function"); }
   this.next();
 
   // In `return` (and `break`/`continue`), the keywords with
   // optional arguments, we eagerly look for a semicolon or the
   // possibility to insert one.
 
-  if (this.eat(_tokentype.types.semi) || this.insertSemicolon()) node.argument = null;else {
-    node.argument = this.parseExpression();this.semicolon();
-  }
-  return this.finishNode(node, "ReturnStatement");
-};
-
-pp.parseSwitchStatement = function (node) {
+  if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }
+  else { node.argument = this.parseExpression(); this.semicolon(); }
+  return this.finishNode(node, "ReturnStatement")
+};
+
+pp$1.parseSwitchStatement = function(node) {
+  var this$1 = this;
+
   this.next();
   node.discriminant = this.parseParenExpression();
   node.cases = [];
-  this.expect(_tokentype.types.braceL);
+  this.expect(types.braceL);
   this.labels.push(switchLabel);
+  this.enterLexicalScope();
 
   // Statements under must be grouped (by label) in SwitchCase
   // nodes. `cur` is used to keep the node that we are currently
   // adding statements to.
 
-  for (var cur, sawDefault = false; this.type != _tokentype.types.braceR;) {
-    if (this.type === _tokentype.types._case || this.type === _tokentype.types._default) {
-      var isCase = this.type === _tokentype.types._case;
-      if (cur) this.finishNode(cur, "SwitchCase");
-      node.cases.push(cur = this.startNode());
+  var cur;
+  for (var sawDefault = false; this.type != types.braceR;) {
+    if (this$1.type === types._case || this$1.type === types._default) {
+      var isCase = this$1.type === types._case;
+      if (cur) { this$1.finishNode(cur, "SwitchCase"); }
+      node.cases.push(cur = this$1.startNode());
       cur.consequent = [];
-      this.next();
+      this$1.next();
       if (isCase) {
-        cur.test = this.parseExpression();
+        cur.test = this$1.parseExpression();
       } else {
-        if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
+        if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); }
         sawDefault = true;
         cur.test = null;
       }
-      this.expect(_tokentype.types.colon);
+      this$1.expect(types.colon);
     } else {
-      if (!cur) this.unexpected();
-      cur.consequent.push(this.parseStatement(true));
-    }
-  }
-  if (cur) this.finishNode(cur, "SwitchCase");
+      if (!cur) { this$1.unexpected(); }
+      cur.consequent.push(this$1.parseStatement(true));
+    }
+  }
+  this.exitLexicalScope();
+  if (cur) { this.finishNode(cur, "SwitchCase"); }
   this.next(); // Closing brace
   this.labels.pop();
-  return this.finishNode(node, "SwitchStatement");
-};
-
-pp.parseThrowStatement = function (node) {
+  return this.finishNode(node, "SwitchStatement")
+};
+
+pp$1.parseThrowStatement = function(node) {
   this.next();
-  if (_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) this.raise(this.lastTokEnd, "Illegal newline after throw");
+  if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
+    { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
   node.argument = this.parseExpression();
   this.semicolon();
-  return this.finishNode(node, "ThrowStatement");
+  return this.finishNode(node, "ThrowStatement")
 };
 
 // Reused empty array added for node fields that are always empty.
 
 var empty = [];
 
-pp.parseTryStatement = function (node) {
+pp$1.parseTryStatement = function(node) {
   this.next();
   node.block = this.parseBlock();
   node.handler = null;
-  if (this.type === _tokentype.types._catch) {
+  if (this.type === types._catch) {
     var clause = this.startNode();
     this.next();
-    this.expect(_tokentype.types.parenL);
+    this.expect(types.parenL);
     clause.param = this.parseBindingAtom();
-    this.checkLVal(clause.param, true);
-    this.expect(_tokentype.types.parenR);
-    clause.body = this.parseBlock();
+    this.enterLexicalScope();
+    this.checkLVal(clause.param, "let");
+    this.expect(types.parenR);
+    clause.body = this.parseBlock(false);
+    this.exitLexicalScope();
     node.handler = this.finishNode(clause, "CatchClause");
   }
-  node.finalizer = this.eat(_tokentype.types._finally) ? this.parseBlock() : null;
-  if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
-  return this.finishNode(node, "TryStatement");
-};
-
-pp.parseVarStatement = function (node, kind) {
+  node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
+  if (!node.handler && !node.finalizer)
+    { this.raise(node.start, "Missing catch or finally clause"); }
+  return this.finishNode(node, "TryStatement")
+};
+
+pp$1.parseVarStatement = function(node, kind) {
   this.next();
   this.parseVar(node, false, kind);
   this.semicolon();
-  return this.finishNode(node, "VariableDeclaration");
-};
-
-pp.parseWhileStatement = function (node) {
+  return this.finishNode(node, "VariableDeclaration")
+};
+
+pp$1.parseWhileStatement = function(node) {
   this.next();
   node.test = this.parseParenExpression();
   this.labels.push(loopLabel);
   node.body = this.parseStatement(false);
   this.labels.pop();
-  return this.finishNode(node, "WhileStatement");
-};
-
-pp.parseWithStatement = function (node) {
-  if (this.strict) this.raise(this.start, "'with' in strict mode");
+  return this.finishNode(node, "WhileStatement")
+};
+
+pp$1.parseWithStatement = function(node) {
+  if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
   this.next();
   node.object = this.parseParenExpression();
   node.body = this.parseStatement(false);
-  return this.finishNode(node, "WithStatement");
-};
-
-pp.parseEmptyStatement = function (node) {
+  return this.finishNode(node, "WithStatement")
+};
+
+pp$1.parseEmptyStatement = function(node) {
   this.next();
-  return this.finishNode(node, "EmptyStatement");
-};
-
-pp.parseLabeledStatement = function (node, maybeName, expr) {
-  for (var i = 0; i < this.labels.length; ++i) {
-    if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared");
-  }var kind = this.type.isLoop ? "loop" : this.type === _tokentype.types._switch ? "switch" : null;
+  return this.finishNode(node, "EmptyStatement")
+};
+
+pp$1.parseLabeledStatement = function(node, maybeName, expr) {
+  var this$1 = this;
+
+  for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1)
+    {
+    var label = list[i$1];
+
+    if (label.name === maybeName)
+      { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared");
+  } }
+  var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null;
   for (var i = this.labels.length - 1; i >= 0; i--) {
-    var label = this.labels[i];
-    if (label.statementStart == node.start) {
-      label.statementStart = this.start;
-      label.kind = kind;
-    } else break;
-  }
-  this.labels.push({ name: maybeName, kind: kind, statementStart: this.start });
+    var label$1 = this$1.labels[i];
+    if (label$1.statementStart == node.start) {
+      label$1.statementStart = this$1.start;
+      label$1.kind = kind;
+    } else { break }
+  }
+  this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
   node.body = this.parseStatement(true);
+  if (node.body.type == "ClassDeclaration" ||
+      node.body.type == "VariableDeclaration" && node.body.kind != "var" ||
+      node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator))
+    { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); }
   this.labels.pop();
   node.label = expr;
-  return this.finishNode(node, "LabeledStatement");
-};
-
-pp.parseExpressionStatement = function (node, expr) {
+  return this.finishNode(node, "LabeledStatement")
+};
+
+pp$1.parseExpressionStatement = function(node, expr) {
   node.expression = expr;
   this.semicolon();
-  return this.finishNode(node, "ExpressionStatement");
+  return this.finishNode(node, "ExpressionStatement")
 };
 
 // Parse a semicolon-enclosed block of statements, handling `"use
 // strict"` declarations when `allowStrict` is true (used for
 // function bodies).
 
-pp.parseBlock = function (allowStrict) {
-  var node = this.startNode(),
-      first = true,
-      oldStrict = undefined;
+pp$1.parseBlock = function(createNewLexicalScope) {
+  var this$1 = this;
+  if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
+
+  var node = this.startNode();
   node.body = [];
-  this.expect(_tokentype.types.braceL);
-  while (!this.eat(_tokentype.types.braceR)) {
-    var stmt = this.parseStatement(true);
+  this.expect(types.braceL);
+  if (createNewLexicalScope) {
+    this.enterLexicalScope();
+  }
+  while (!this.eat(types.braceR)) {
+    var stmt = this$1.parseStatement(true);
     node.body.push(stmt);
-    if (first && allowStrict && this.isUseStrict(stmt)) {
-      oldStrict = this.strict;
-      this.setStrict(this.strict = true);
-    }
-    first = false;
-  }
-  if (oldStrict === false) this.setStrict(false);
-  return this.finishNode(node, "BlockStatement");
+  }
+  if (createNewLexicalScope) {
+    this.exitLexicalScope();
+  }
+  return this.finishNode(node, "BlockStatement")
 };
 
 // Parse a regular `for` loop. The disambiguation code in
 // `parseStatement` will already have parsed the init statement or
 // expression.
 
-pp.parseFor = function (node, init) {
+pp$1.parseFor = function(node, init) {
   node.init = init;
-  this.expect(_tokentype.types.semi);
-  node.test = this.type === _tokentype.types.semi ? null : this.parseExpression();
-  this.expect(_tokentype.types.semi);
-  node.update = this.type === _tokentype.types.parenR ? null : this.parseExpression();
-  this.expect(_tokentype.types.parenR);
+  this.expect(types.semi);
+  node.test = this.type === types.semi ? null : this.parseExpression();
+  this.expect(types.semi);
+  node.update = this.type === types.parenR ? null : this.parseExpression();
+  this.expect(types.parenR);
+  this.exitLexicalScope();
   node.body = this.parseStatement(false);
   this.labels.pop();
-  return this.finishNode(node, "ForStatement");
+  return this.finishNode(node, "ForStatement")
 };
 
 // Parse a `for`/`in` and `for`/`of` loop, which are almost
 // same from parser's perspective.
 
-pp.parseForIn = function (node, init) {
-  var type = this.type === _tokentype.types._in ? "ForInStatement" : "ForOfStatement";
+pp$1.parseForIn = function(node, init) {
+  var type = this.type === types._in ? "ForInStatement" : "ForOfStatement";
   this.next();
   node.left = init;
   node.right = this.parseExpression();
-  this.expect(_tokentype.types.parenR);
+  this.expect(types.parenR);
+  this.exitLexicalScope();
   node.body = this.parseStatement(false);
   this.labels.pop();
-  return this.finishNode(node, type);
+  return this.finishNode(node, type)
 };
 
 // Parse a list of variable declarations.
 
-pp.parseVar = function (node, isFor, kind) {
+pp$1.parseVar = function(node, isFor, kind) {
+  var this$1 = this;
+
   node.declarations = [];
-  node.kind = kind.keyword;
+  node.kind = kind;
   for (;;) {
-    var decl = this.startNode();
-    this.parseVarId(decl);
-    if (this.eat(_tokentype.types.eq)) {
-      decl.init = this.parseMaybeAssign(isFor);
-    } else if (kind === _tokentype.types._const && !(this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
-      this.unexpected();
-    } else if (decl.id.type != "Identifier" && !(isFor && (this.type === _tokentype.types._in || this.isContextual("of")))) {
-      this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
+    var decl = this$1.startNode();
+    this$1.parseVarId(decl, kind);
+    if (this$1.eat(types.eq)) {
+      decl.init = this$1.parseMaybeAssign(isFor);
+    } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) {
+      this$1.unexpected();
+    } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) {
+      this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value");
     } else {
       decl.init = null;
     }
-    node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
-    if (!this.eat(_tokentype.types.comma)) break;
-  }
-  return node;
-};
-
-pp.parseVarId = function (decl) {
-  decl.id = this.parseBindingAtom();
-  this.checkLVal(decl.id, true);
+    node.declarations.push(this$1.finishNode(decl, "VariableDeclarator"));
+    if (!this$1.eat(types.comma)) { break }
+  }
+  return node
+};
+
+pp$1.parseVarId = function(decl, kind) {
+  decl.id = this.parseBindingAtom(kind);
+  this.checkLVal(decl.id, kind, false);
 };
 
 // Parse a function declaration or literal (depending on the
 // `isStatement` parameter).
 
-pp.parseFunction = function (node, isStatement, allowExpressionBody) {
+pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {
   this.initFunction(node);
-  if (this.options.ecmaVersion >= 6) node.generator = this.eat(_tokentype.types.star);
-  if (isStatement || this.type === _tokentype.types.name) node.id = this.parseIdent();
+  if (this.options.ecmaVersion >= 6 && !isAsync)
+    { node.generator = this.eat(types.star); }
+  if (this.options.ecmaVersion >= 8)
+    { node.async = !!isAsync; }
+
+  if (isStatement) {
+    node.id = isStatement === "nullableID" && this.type != types.name ? null : this.parseIdent();
+    if (node.id) {
+      this.checkLVal(node.id, "var");
+    }
+  }
+
+  var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
+      oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
+  this.inGenerator = node.generator;
+  this.inAsync = node.async;
+  this.yieldPos = 0;
+  this.awaitPos = 0;
+  this.inFunction = true;
+  this.enterFunctionScope();
+
+  if (!isStatement)
+    { node.id = this.type == types.name ? this.parseIdent() : null; }
+
   this.parseFunctionParams(node);
   this.parseFunctionBody(node, allowExpressionBody);
-  return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
-};
-
-pp.parseFunctionParams = function (node) {
-  this.expect(_tokentype.types.parenL);
-  node.params = this.parseBindingList(_tokentype.types.parenR, false, false, true);
+
+  this.inGenerator = oldInGen;
+  this.inAsync = oldInAsync;
+  this.yieldPos = oldYieldPos;
+  this.awaitPos = oldAwaitPos;
+  this.inFunction = oldInFunc;
+  return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
+};
+
+pp$1.parseFunctionParams = function(node) {
+  this.expect(types.parenL);
+  node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
+  this.checkYieldAwaitInDefaultParams();
 };
 
 // Parse a class declaration or literal (depending on the
 // `isStatement` parameter).
 
-pp.parseClass = function (node, isStatement) {
+pp$1.parseClass = function(node, isStatement) {
+  var this$1 = this;
+
   this.next();
+
   this.parseClassId(node, isStatement);
   this.parseClassSuper(node);
   var classBody = this.startNode();
   var hadConstructor = false;
   classBody.body = [];
-  this.expect(_tokentype.types.braceL);
-  while (!this.eat(_tokentype.types.braceR)) {
-    if (this.eat(_tokentype.types.semi)) continue;
-    var method = this.startNode();
-    var isGenerator = this.eat(_tokentype.types.star);
-    var isMaybeStatic = this.type === _tokentype.types.name && this.value === "static";
-    this.parsePropertyName(method);
-    method["static"] = isMaybeStatic && this.type !== _tokentype.types.parenL;
-    if (method["static"]) {
-      if (isGenerator) this.unexpected();
-      isGenerator = this.eat(_tokentype.types.star);
-      this.parsePropertyName(method);
+  this.expect(types.braceL);
+  while (!this.eat(types.braceR)) {
+    if (this$1.eat(types.semi)) { continue }
+    var method = this$1.startNode();
+    var isGenerator = this$1.eat(types.star);
+    var isAsync = false;
+    var isMaybeStatic = this$1.type === types.name && this$1.value === "static";
+    this$1.parsePropertyName(method);
+    method.static = isMaybeStatic && this$1.type !== types.parenL;
+    if (method.static) {
+      if (isGenerator) { this$1.unexpected(); }
+      isGenerator = this$1.eat(types.star);
+      this$1.parsePropertyName(method);
+    }
+    if (this$1.options.ecmaVersion >= 8 && !isGenerator && !method.computed &&
+        method.key.type === "Identifier" && method.key.name === "async" && this$1.type !== types.parenL &&
+        !this$1.canInsertSemicolon()) {
+      isAsync = true;
+      this$1.parsePropertyName(method);
     }
     method.kind = "method";
     var isGetSet = false;
     if (!method.computed) {
       var key = method.key;
-
-      if (!isGenerator && key.type === "Identifier" && this.type !== _tokentype.types.parenL && (key.name === "get" || key.name === "set")) {
+      if (!isGenerator && !isAsync && key.type === "Identifier" && this$1.type !== types.parenL && (key.name === "get" || key.name === "set")) {
         isGetSet = true;
         method.kind = key.name;
-        key = this.parsePropertyName(method);
+        key = this$1.parsePropertyName(method);
       }
-      if (!method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) {
-        if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class");
-        if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier");
-        if (isGenerator) this.raise(key.start, "Constructor can't be a generator");
+      if (!method.static && (key.type === "Identifier" && key.name === "constructor" ||
+          key.type === "Literal" && key.value === "constructor")) {
+        if (hadConstructor) { this$1.raise(key.start, "Duplicate constructor in the same class"); }
+        if (isGetSet) { this$1.raise(key.start, "Constructor can't have get/set modifier"); }
+        if (isGenerator) { this$1.raise(key.start, "Constructor can't be a generator"); }
+        if (isAsync) { this$1.raise(key.start, "Constructor can't be an async method"); }
         method.kind = "constructor";
         hadConstructor = true;
       }
     }
-    this.parseClassMethod(classBody, method, isGenerator);
+    this$1.parseClassMethod(classBody, method, isGenerator, isAsync);
     if (isGetSet) {
       var paramCount = method.kind === "get" ? 0 : 1;
       if (method.value.params.length !== paramCount) {
         var start = method.value.start;
-        if (method.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param");
+        if (method.kind === "get")
+          { this$1.raiseRecoverable(start, "getter should have no params"); }
+        else
+          { this$1.raiseRecoverable(start, "setter should have exactly one param"); }
+      } else {
+        if (method.kind === "set" && method.value.params[0].type === "RestElement")
+          { this$1.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
       }
     }
   }
   node.body = this.finishNode(classBody, "ClassBody");
-  return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
-};
-
-pp.parseClassMethod = function (classBody, method, isGenerator) {
-  method.value = this.parseMethod(isGenerator);
+  return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
+};
+
+pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {
+  method.value = this.parseMethod(isGenerator, isAsync);
   classBody.body.push(this.finishNode(method, "MethodDefinition"));
 };
 
-pp.parseClassId = function (node, isStatement) {
-  node.id = this.type === _tokentype.types.name ? this.parseIdent() : isStatement ? this.unexpected() : null;
-};
-
-pp.parseClassSuper = function (node) {
-  node.superClass = this.eat(_tokentype.types._extends) ? this.parseExprSubscripts() : null;
+pp$1.parseClassId = function(node, isStatement) {
+  node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null;
+};
+
+pp$1.parseClassSuper = function(node) {
+  node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
 };
 
 // Parses module export declaration.
 
-pp.parseExport = function (node) {
+pp$1.parseExport = function(node, exports) {
+  var this$1 = this;
+
   this.next();
   // export * from '...'
-  if (this.eat(_tokentype.types.star)) {
+  if (this.eat(types.star)) {
     this.expectContextual("from");
-    node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected();
+    node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
     this.semicolon();
-    return this.finishNode(node, "ExportAllDeclaration");
-  }
-  if (this.eat(_tokentype.types._default)) {
-    // export default ...
-    var expr = this.parseMaybeAssign();
-    var needsSemi = true;
-    if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
-      needsSemi = false;
-      if (expr.id) {
-        expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
-      }
-    }
-    node.declaration = expr;
-    if (needsSemi) this.semicolon();
-    return this.finishNode(node, "ExportDefaultDeclaration");
+    return this.finishNode(node, "ExportAllDeclaration")
+  }
+  if (this.eat(types._default)) { // export default ...
+    this.checkExport(exports, "default", this.lastTokStart);
+    var isAsync;
+    if (this.type === types._function || (isAsync = this.isAsyncFunction())) {
+      var fNode = this.startNode();
+      this.next();
+      if (isAsync) { this.next(); }
+      node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync);
+    } else if (this.type === types._class) {
+      var cNode = this.startNode();
+      node.declaration = this.parseClass(cNode, "nullableID");
+    } else {
+      node.declaration = this.parseMaybeAssign();
+      this.semicolon();
+    }
+    return this.finishNode(node, "ExportDefaultDeclaration")
   }
   // export var|const|let|function|class ...
   if (this.shouldParseExportStatement()) {
     node.declaration = this.parseStatement(true);
+    if (node.declaration.type === "VariableDeclaration")
+      { this.checkVariableExport(exports, node.declaration.declarations); }
+    else
+      { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }
     node.specifiers = [];
     node.source = null;
-  } else {
-    // export { x, y as z } [from '...']
+  } else { // export { x, y as z } [from '...']
     node.declaration = null;
-    node.specifiers = this.parseExportSpecifiers();
+    node.specifiers = this.parseExportSpecifiers(exports);
     if (this.eatContextual("from")) {
-      node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected();
+      node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
     } else {
       // check for keywords used as local names
-      for (var i = 0; i < node.specifiers.length; i++) {
-        if (this.keywords.test(node.specifiers[i].local.name) || this.reservedWords.test(node.specifiers[i].local.name)) {
-          this.unexpected(node.specifiers[i].local.start);
-        }
+      for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
+        var spec = list[i];
+
+        this$1.checkUnreserved(spec.local);
       }
 
       node.source = null;
     }
     this.semicolon();
   }
-  return this.finishNode(node, "ExportNamedDeclaration");
-};
-
-pp.shouldParseExportStatement = function () {
-  return this.type.keyword;
+  return this.finishNode(node, "ExportNamedDeclaration")
+};
+
+pp$1.checkExport = function(exports, name, pos) {
+  if (!exports) { return }
+  if (has(exports, name))
+    { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
+  exports[name] = true;
+};
+
+pp$1.checkPatternExport = function(exports, pat) {
+  var this$1 = this;
+
+  var type = pat.type;
+  if (type == "Identifier")
+    { this.checkExport(exports, pat.name, pat.start); }
+  else if (type == "ObjectPattern")
+    { for (var i = 0, list = pat.properties; i < list.length; i += 1)
+      {
+        var prop = list[i];
+
+        this$1.checkPatternExport(exports, prop.value);
+      } }
+  else if (type == "ArrayPattern")
+    { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
+      var elt = list$1[i$1];
+
+        if (elt) { this$1.checkPatternExport(exports, elt); }
+    } }
+  else if (type == "AssignmentPattern")
+    { this.checkPatternExport(exports, pat.left); }
+  else if (type == "ParenthesizedExpression")
+    { this.checkPatternExport(exports, pat.expression); }
+};
+
+pp$1.checkVariableExport = function(exports, decls) {
+  var this$1 = this;
+
+  if (!exports) { return }
+  for (var i = 0, list = decls; i < list.length; i += 1)
+    {
+    var decl = list[i];
+
+    this$1.checkPatternExport(exports, decl.id);
+  }
+};
+
+pp$1.shouldParseExportStatement = function() {
+  return this.type.keyword === "var" ||
+    this.type.keyword === "const" ||
+    this.type.keyword === "class" ||
+    this.type.keyword === "function" ||
+    this.isLet() ||
+    this.isAsyncFunction()
 };
 
 // Parses a comma-separated list of module exports.
 
-pp.parseExportSpecifiers = function () {
-  var nodes = [],
-      first = true;
+pp$1.parseExportSpecifiers = function(exports) {
+  var this$1 = this;
+
+  var nodes = [], first = true;
   // export { x, y as z } [from '...']
-  this.expect(_tokentype.types.braceL);
-  while (!this.eat(_tokentype.types.braceR)) {
+  this.expect(types.braceL);
+  while (!this.eat(types.braceR)) {
     if (!first) {
-      this.expect(_tokentype.types.comma);
-      if (this.afterTrailingComma(_tokentype.types.braceR)) break;
-    } else first = false;
-
-    var node = this.startNode();
-    node.local = this.parseIdent(this.type === _tokentype.types._default);
-    node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
-    nodes.push(this.finishNode(node, "ExportSpecifier"));
-  }
-  return nodes;
+      this$1.expect(types.comma);
+      if (this$1.afterTrailingComma(types.braceR)) { break }
+    } else { first = false; }
+
+    var node = this$1.startNode();
+    node.local = this$1.parseIdent(true);
+    node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local;
+    this$1.checkExport(exports, node.exported.name, node.exported.start);
+    nodes.push(this$1.finishNode(node, "ExportSpecifier"));
+  }
+  return nodes
 };
 
 // Parses import declaration.
 
-pp.parseImport = function (node) {
+pp$1.parseImport = function(node) {
   this.next();
   // import '...'
-  if (this.type === _tokentype.types.string) {
+  if (this.type === types.string) {
     node.specifiers = empty;
     node.source = this.parseExprAtom();
   } else {
     node.specifiers = this.parseImportSpecifiers();
     this.expectContextual("from");
-    node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected();
+    node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
   }
   this.semicolon();
-  return this.finishNode(node, "ImportDeclaration");
+  return this.finishNode(node, "ImportDeclaration")
 };
 
 // Parses a comma-separated list of module imports.
 
-pp.parseImportSpecifiers = function () {
-  var nodes = [],
-      first = true;
-  if (this.type === _tokentype.types.name) {
+pp$1.parseImportSpecifiers = function() {
+  var this$1 = this;
+
+  var nodes = [], first = true;
+  if (this.type === types.name) {
     // import defaultObj, { x, y as z } from '...'
     var node = this.startNode();
     node.local = this.parseIdent();
-    this.checkLVal(node.local, true);
+    this.checkLVal(node.local, "let");
     nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
-    if (!this.eat(_tokentype.types.comma)) return nodes;
-  }
-  if (this.type === _tokentype.types.star) {
-    var node = this.startNode();
+    if (!this.eat(types.comma)) { return nodes }
+  }
+  if (this.type === types.star) {
+    var node$1 = this.startNode();
     this.next();
     this.expectContextual("as");
-    node.local = this.parseIdent();
-    this.checkLVal(node.local, true);
-    nodes.push(this.finishNode(node, "ImportNamespaceSpecifier"));
-    return nodes;
-  }
-  this.expect(_tokentype.types.braceL);
-  while (!this.eat(_tokentype.types.braceR)) {
+    node$1.local = this.parseIdent();
+    this.checkLVal(node$1.local, "let");
+    nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
+    return nodes
+  }
+  this.expect(types.braceL);
+  while (!this.eat(types.braceR)) {
     if (!first) {
-      this.expect(_tokentype.types.comma);
-      if (this.afterTrailingComma(_tokentype.types.braceR)) break;
-    } else first = false;
-
-    var node = this.startNode();
-    node.imported = this.parseIdent(true);
-    node.local = this.eatContextual("as") ? this.parseIdent() : node.imported;
-    this.checkLVal(node.local, true);
-    nodes.push(this.finishNode(node, "ImportSpecifier"));
-  }
-  return nodes;
-};
-
-},{"./state":10,"./tokentype":14,"./whitespace":16}],12:[function(_dereq_,module,exports){
+      this$1.expect(types.comma);
+      if (this$1.afterTrailingComma(types.braceR)) { break }
+    } else { first = false; }
+
+    var node$2 = this$1.startNode();
+    node$2.imported = this$1.parseIdent(true);
+    if (this$1.eatContextual("as")) {
+      node$2.local = this$1.parseIdent();
+    } else {
+      this$1.checkUnreserved(node$2.imported);
+      node$2.local = node$2.imported;
+    }
+    this$1.checkLVal(node$2.local, "let");
+    nodes.push(this$1.finishNode(node$2, "ImportSpecifier"));
+  }
+  return nodes
+};
+
+// Set `ExpressionStatement#directive` property for directive prologues.
+pp$1.adaptDirectivePrologue = function(statements) {
+  for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
+    statements[i].directive = statements[i].expression.raw.slice(1, -1);
+  }
+};
+pp$1.isDirectiveCandidate = function(statement) {
+  return (
+    statement.type === "ExpressionStatement" &&
+    statement.expression.type === "Literal" &&
+    typeof statement.expression.value === "string" &&
+    // Reject parenthesized strings.
+    (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
+  )
+};
+
+var pp$2 = Parser.prototype;
+
+// Convert existing expression atom to assignable pattern
+// if possible.
+
+pp$2.toAssignable = function(node, isBinding) {
+  var this$1 = this;
+
+  if (this.options.ecmaVersion >= 6 && node) {
+    switch (node.type) {
+    case "Identifier":
+      if (this.inAsync && node.name === "await")
+        { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); }
+      break
+
+    case "ObjectPattern":
+    case "ArrayPattern":
+      break
+
+    case "ObjectExpression":
+      node.type = "ObjectPattern";
+      for (var i = 0, list = node.properties; i < list.length; i += 1) {
+        var prop = list[i];
+
+      if (prop.kind !== "init") { this$1.raise(prop.key.start, "Object pattern can't contain getter or setter"); }
+        this$1.toAssignable(prop.value, isBinding);
+      }
+      break
+
+    case "ArrayExpression":
+      node.type = "ArrayPattern";
+      this.toAssignableList(node.elements, isBinding);
+      break
+
+    case "AssignmentExpression":
+      if (node.operator === "=") {
+        node.type = "AssignmentPattern";
+        delete node.operator;
+        this.toAssignable(node.left, isBinding);
+        // falls through to AssignmentPattern
+      } else {
+        this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
+        break
+      }
+
+    case "AssignmentPattern":
+      break
+
+    case "ParenthesizedExpression":
+      this.toAssignable(node.expression, isBinding);
+      break
+
+    case "MemberExpression":
+      if (!isBinding) { break }
+
+    default:
+      this.raise(node.start, "Assigning to rvalue");
+    }
+  }
+  return node
+};
+
+// Convert list of expression atoms to binding list.
+
+pp$2.toAssignableList = function(exprList, isBinding) {
+  var this$1 = this;
+
+  var end = exprList.length;
+  if (end) {
+    var last = exprList[end - 1];
+    if (last && last.type == "RestElement") {
+      --end;
+    } else if (last && last.type == "SpreadElement") {
+      last.type = "RestElement";
+      var arg = last.argument;
+      this.toAssignable(arg, isBinding);
+      --end;
+    }
+
+    if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
+      { this.unexpected(last.argument.start); }
+  }
+  for (var i = 0; i < end; i++) {
+    var elt = exprList[i];
+    if (elt) { this$1.toAssignable(elt, isBinding); }
+  }
+  return exprList
+};
+
+// Parses spread element.
+
+pp$2.parseSpread = function(refDestructuringErrors) {
+  var node = this.startNode();
+  this.next();
+  node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
+  return this.finishNode(node, "SpreadElement")
+};
+
+pp$2.parseRestBinding = function() {
+  var node = this.startNode();
+  this.next();
+
+  // RestElement inside of a function parameter must be an identifier
+  if (this.options.ecmaVersion === 6 && this.type !== types.name)
+    { this.unexpected(); }
+
+  node.argument = this.parseBindingAtom();
+
+  return this.finishNode(node, "RestElement")
+};
+
+// Parses lvalue (assignable) atom.
+
+pp$2.parseBindingAtom = function() {
+  if (this.options.ecmaVersion >= 6) {
+    switch (this.type) {
+    case types.bracketL:
+      var node = this.startNode();
+      this.next();
+      node.elements = this.parseBindingList(types.bracketR, true, true);
+      return this.finishNode(node, "ArrayPattern")
+
+    case types.braceL:
+      return this.parseObj(true)
+    }
+  }
+  return this.parseIdent()
+};
+
+pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
+  var this$1 = this;
+
+  var elts = [], first = true;
+  while (!this.eat(close)) {
+    if (first) { first = false; }
+    else { this$1.expect(types.comma); }
+    if (allowEmpty && this$1.type === types.comma) {
+      elts.push(null);
+    } else if (allowTrailingComma && this$1.afterTrailingComma(close)) {
+      break
+    } else if (this$1.type === types.ellipsis) {
+      var rest = this$1.parseRestBinding();
+      this$1.parseBindingListItem(rest);
+      elts.push(rest);
+      if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); }
+      this$1.expect(close);
+      break
+    } else {
+      var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc);
+      this$1.parseBindingListItem(elem);
+      elts.push(elem);
+    }
+  }
+  return elts
+};
+
+pp$2.parseBindingListItem = function(param) {
+  return param
+};
+
+// Parses assignment pattern around given atom if possible.
+
+pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
+  left = left || this.parseBindingAtom();
+  if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }
+  var node = this.startNodeAt(startPos, startLoc);
+  node.left = left;
+  node.right = this.parseMaybeAssign();
+  return this.finishNode(node, "AssignmentPattern")
+};
+
+// Verify that a node is an lval — something that can be assigned
+// to.
+// bindingType can be either:
+// 'var' indicating that the lval creates a 'var' binding
+// 'let' indicating that the lval creates a lexical ('let' or 'const') binding
+// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references
+
+pp$2.checkLVal = function(expr, bindingType, checkClashes) {
+  var this$1 = this;
+
+  switch (expr.type) {
+  case "Identifier":
+    if (this.strict && this.reservedWordsStrictBind.test(expr.name))
+      { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
+    if (checkClashes) {
+      if (has(checkClashes, expr.name))
+        { this.raiseRecoverable(expr.start, "Argument name clash"); }
+      checkClashes[expr.name] = true;
+    }
+    if (bindingType && bindingType !== "none") {
+      if (
+        bindingType === "var" && !this.canDeclareVarName(expr.name) ||
+        bindingType !== "var" && !this.canDeclareLexicalName(expr.name)
+      ) {
+        this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared"));
+      }
+      if (bindingType === "var") {
+        this.declareVarName(expr.name);
+      } else {
+        this.declareLexicalName(expr.name);
+      }
+    }
+    break
+
+  case "MemberExpression":
+    if (bindingType) { this.raiseRecoverable(expr.start, (bindingType ? "Binding" : "Assigning to") + " member expression"); }
+    break
+
+  case "ObjectPattern":
+    for (var i = 0, list = expr.properties; i < list.length; i += 1)
+      {
+    var prop = list[i];
+
+    this$1.checkLVal(prop.value, bindingType, checkClashes);
+  }
+    break
+
+  case "ArrayPattern":
+    for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
+      var elem = list$1[i$1];
+
+    if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); }
+    }
+    break
+
+  case "AssignmentPattern":
+    this.checkLVal(expr.left, bindingType, checkClashes);
+    break
+
+  case "RestElement":
+    this.checkLVal(expr.argument, bindingType, checkClashes);
+    break
+
+  case "ParenthesizedExpression":
+    this.checkLVal(expr.expression, bindingType, checkClashes);
+    break
+
+  default:
+    this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue");
+  }
+};
+
+// A recursive descent parser operates by defining functions for all
+// syntactic elements, and recursively calling those, each function
+// advancing the input stream and returning an AST node. Precedence
+// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
+// instead of `(!x)[1]` is handled by the fact that the parser
+// function that parses unary prefix operators is called first, and
+// in turn calls the function that parses `[]` subscripts — that
+// way, it'll receive the node for `x[1]` already parsed, and wraps
+// *that* in the unary operator node.
+//
+// Acorn uses an [operator precedence parser][opp] to handle binary
+// operator precedence, because it is much more compact than using
+// the technique outlined above, which uses different, nesting
+// functions to specify precedence, for all of the ten binary
+// precedence levels that JavaScript defines.
+//
+// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
+
+var pp$3 = Parser.prototype;
+
+// Check if property name clashes with already added.
+// Object/class getters and setters are not allowed to clash —
+// either with each other or with an init property — and in
+// strict mode, init properties are also not allowed to be repeated.
+
+pp$3.checkPropClash = function(prop, propHash) {
+  if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
+    { return }
+  var key = prop.key;
+  var name;
+  switch (key.type) {
+  case "Identifier": name = key.name; break
+  case "Literal": name = String(key.value); break
+  default: return
+  }
+  var kind = prop.kind;
+  if (this.options.ecmaVersion >= 6) {
+    if (name === "__proto__" && kind === "init") {
+      if (propHash.proto) { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); }
+      propHash.proto = true;
+    }
+    return
+  }
+  name = "$" + name;
+  var other = propHash[name];
+  if (other) {
+    var redefinition;
+    if (kind === "init") {
+      redefinition = this.strict && other.init || other.get || other.set;
+    } else {
+      redefinition = other.init || other[kind];
+    }
+    if (redefinition)
+      { this.raiseRecoverable(key.start, "Redefinition of property"); }
+  } else {
+    other = propHash[name] = {
+      init: false,
+      get: false,
+      set: false
+    };
+  }
+  other[kind] = true;
+};
+
+// ### Expression parsing
+
+// These nest, from the most general expression type at the top to
+// 'atomic', nondivisible expression types at the bottom. Most of
+// the functions will simply let the function(s) below them parse,
+// and, *if* the syntactic construct they handle is present, wrap
+// the AST node that the inner parser gave them in another node.
+
+// Parse a full expression. The optional arguments are used to
+// forbid the `in` operator (in for loops initalization expressions)
+// and provide reference for storing '=' operator inside shorthand
+// property assignment in contexts where both object expression
+// and object pattern might appear (so it's possible to raise
+// delayed syntax error at correct position).
+
+pp$3.parseExpression = function(noIn, refDestructuringErrors) {
+  var this$1 = this;
+
+  var startPos = this.start, startLoc = this.startLoc;
+  var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
+  if (this.type === types.comma) {
+    var node = this.startNodeAt(startPos, startLoc);
+    node.expressions = [expr];
+    while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); }
+    return this.finishNode(node, "SequenceExpression")
+  }
+  return expr
+};
+
+// Parse an assignment expression. This includes applications of
+// operators like `+=`.
+
+pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
+  if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() }
+
+  var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;
+  if (refDestructuringErrors) {
+    oldParenAssign = refDestructuringErrors.parenthesizedAssign;
+    oldTrailingComma = refDestructuringErrors.trailingComma;
+    refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
+  } else {
+    refDestructuringErrors = new DestructuringErrors;
+    ownDestructuringErrors = true;
+  }
+
+  var startPos = this.start, startLoc = this.startLoc;
+  if (this.type == types.parenL || this.type == types.name)
+    { this.potentialArrowAt = this.start; }
+  var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
+  if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
+  if (this.type.isAssign) {
+    this.checkPatternErrors(refDestructuringErrors, true);
+    if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }
+    var node = this.startNodeAt(startPos, startLoc);
+    node.operator = this.value;
+    node.left = this.type === types.eq ? this.toAssignable(left) : left;
+    refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly
+    this.checkLVal(left);
+    this.next();
+    node.right = this.parseMaybeAssign(noIn);
+    return this.finishNode(node, "AssignmentExpression")
+  } else {
+    if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
+  }
+  if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
+  if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
+  return left
+};
+
+// Parse a ternary conditional (`?:`) operator.
+
+pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
+  var startPos = this.start, startLoc = this.startLoc;
+  var expr = this.parseExprOps(noIn, refDestructuringErrors);
+  if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
+  if (this.eat(types.question)) {
+    var node = this.startNodeAt(startPos, startLoc);
+    node.test = expr;
+    node.consequent = this.parseMaybeAssign();
+    this.expect(types.colon);
+    node.alternate = this.parseMaybeAssign(noIn);
+    return this.finishNode(node, "ConditionalExpression")
+  }
+  return expr
+};
+
+// Start the precedence parser.
+
+pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
+  var startPos = this.start, startLoc = this.startLoc;
+  var expr = this.parseMaybeUnary(refDestructuringErrors, false);
+  if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
+  return expr.start == startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
+};
+
+// Parse binary operators with the operator precedence parsing
+// algorithm. `left` is the left-hand side of the operator.
+// `minPrec` provides context that allows the function to stop and
+// defer further parser to one of its callers when it encounters an
+// operator that has a lower precedence than the set it is parsing.
+
+pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
+  var prec = this.type.binop;
+  if (prec != null && (!noIn || this.type !== types._in)) {
+    if (prec > minPrec) {
+      var logical = this.type === types.logicalOR || this.type === types.logicalAND;
+      var op = this.value;
+      this.next();
+      var startPos = this.start, startLoc = this.startLoc;
+      var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
+      var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical);
+      return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
+    }
+  }
+  return left
+};
+
+pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
+  var node = this.startNodeAt(startPos, startLoc);
+  node.left = left;
+  node.operator = op;
+  node.right = right;
+  return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
+};
+
+// Parse unary operators, both prefix and postfix.
+
+pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
+  var this$1 = this;
+
+  var startPos = this.start, startLoc = this.startLoc, expr;
+  if (this.inAsync && this.isContextual("await")) {
+    expr = this.parseAwait();
+    sawUnary = true;
+  } else if (this.type.prefix) {
+    var node = this.startNode(), update = this.type === types.incDec;
+    node.operator = this.value;
+    node.prefix = true;
+    this.next();
+    node.argument = this.parseMaybeUnary(null, true);
+    this.checkExpressionErrors(refDestructuringErrors, true);
+    if (update) { this.checkLVal(node.argument); }
+    else if (this.strict && node.operator === "delete" &&
+             node.argument.type === "Identifier")
+      { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
+    else { sawUnary = true; }
+    expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
+  } else {
+    expr = this.parseExprSubscripts(refDestructuringErrors);
+    if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
+    while (this.type.postfix && !this.canInsertSemicolon()) {
+      var node$1 = this$1.startNodeAt(startPos, startLoc);
+      node$1.operator = this$1.value;
+      node$1.prefix = false;
+      node$1.argument = expr;
+      this$1.checkLVal(expr);
+      this$1.next();
+      expr = this$1.finishNode(node$1, "UpdateExpression");
+    }
+  }
+
+  if (!sawUnary && this.eat(types.starstar))
+    { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
+  else
+    { return expr }
+};
+
+// Parse call, dot, and `[]`-subscript expressions.
+
+pp$3.parseExprSubscripts = function(refDestructuringErrors) {
+  var startPos = this.start, startLoc = this.startLoc;
+  var expr = this.parseExprAtom(refDestructuringErrors);
+  var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")";
+  if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr }
+  var result = this.parseSubscripts(expr, startPos, startLoc);
+  if (refDestructuringErrors && result.type === "MemberExpression") {
+    if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
+    if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
+  }
+  return result
+};
+
+pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
+  var this$1 = this;
+
+  var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
+      this.lastTokEnd == base.end && !this.canInsertSemicolon();
+  for (var computed = (void 0);;) {
+    if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) {
+      var node = this$1.startNodeAt(startPos, startLoc);
+      node.object = base;
+      node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true);
+      node.computed = !!computed;
+      if (computed) { this$1.expect(types.bracketR); }
+      base = this$1.finishNode(node, "MemberExpression");
+    } else if (!noCalls && this$1.eat(types.parenL)) {
+      var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos;
+      this$1.yieldPos = 0;
+      this$1.awaitPos = 0;
+      var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors);
+      if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) {
+        this$1.checkPatternErrors(refDestructuringErrors, false);
+        this$1.checkYieldAwaitInDefaultParams();
+        this$1.yieldPos = oldYieldPos;
+        this$1.awaitPos = oldAwaitPos;
+        return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true)
+      }
+      this$1.checkExpressionErrors(refDestructuringErrors, true);
+      this$1.yieldPos = oldYieldPos || this$1.yieldPos;
+      this$1.awaitPos = oldAwaitPos || this$1.awaitPos;
+      var node$1 = this$1.startNodeAt(startPos, startLoc);
+      node$1.callee = base;
+      node$1.arguments = exprList;
+      base = this$1.finishNode(node$1, "CallExpression");
+    } else if (this$1.type === types.backQuote) {
+      var node$2 = this$1.startNodeAt(startPos, startLoc);
+      node$2.tag = base;
+      node$2.quasi = this$1.parseTemplate({isTagged: true});
+      base = this$1.finishNode(node$2, "TaggedTemplateExpression");
+    } else {
+      return base
+    }
+  }
+};
+
+// Parse an atomic expression — either a single token that is an
+// expression, an expression started by a keyword like `function` or
+// `new`, or an expression wrapped in punctuation like `()`, `[]`,
+// or `{}`.
+
+pp$3.parseExprAtom = function(refDestructuringErrors) {
+  var node, canBeArrow = this.potentialArrowAt == this.start;
+  switch (this.type) {
+  case types._super:
+    if (!this.inFunction)
+      { this.raise(this.start, "'super' outside of function or class"); }
+    node = this.startNode();
+    this.next();
+    // The `super` keyword can appear at below:
+    // SuperProperty:
+    //     super [ Expression ]
+    //     super . IdentifierName
+    // SuperCall:
+    //     super Arguments
+    if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)
+      { this.unexpected(); }
+    return this.finishNode(node, "Super")
+
+  case types._this:
+    node = this.startNode();
+    this.next();
+    return this.finishNode(node, "ThisExpression")
+
+  case types.name:
+    var startPos = this.start, startLoc = this.startLoc;
+    var id = this.parseIdent(this.type !== types.name);
+    if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function))
+      { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) }
+    if (canBeArrow && !this.canInsertSemicolon()) {
+      if (this.eat(types.arrow))
+        { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
+      if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name) {
+        id = this.parseIdent();
+        if (this.canInsertSemicolon() || !this.eat(types.arrow))
+          { this.unexpected(); }
+        return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
+      }
+    }
+    return id
+
+  case types.regexp:
+    var value = this.value;
+    node = this.parseLiteral(value.value);
+    node.regex = {pattern: value.pattern, flags: value.flags};
+    return node
+
+  case types.num: case types.string:
+    return this.parseLiteral(this.value)
+
+  case types._null: case types._true: case types._false:
+    node = this.startNode();
+    node.value = this.type === types._null ? null : this.type === types._true;
+    node.raw = this.type.keyword;
+    this.next();
+    return this.finishNode(node, "Literal")
+
+  case types.parenL:
+    var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);
+    if (refDestructuringErrors) {
+      if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
+        { refDestructuringErrors.parenthesizedAssign = start; }
+      if (refDestructuringErrors.parenthesizedBind < 0)
+        { refDestructuringErrors.parenthesizedBind = start; }
+    }
+    return expr
+
+  case types.bracketL:
+    node = this.startNode();
+    this.next();
+    node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);
+    return this.finishNode(node, "ArrayExpression")
+
+  case types.braceL:
+    return this.parseObj(false, refDestructuringErrors)
+
+  case types._function:
+    node = this.startNode();
+    this.next();
+    return this.parseFunction(node, false)
+
+  case types._class:
+    return this.parseClass(this.startNode(), false)
+
+  case types._new:
+    return this.parseNew()
+
+  case types.backQuote:
+    return this.parseTemplate()
+
+  default:
+    this.unexpected();
+  }
+};
+
+pp$3.parseLiteral = function(value) {
+  var node = this.startNode();
+  node.value = value;
+  node.raw = this.input.slice(this.start, this.end);
+  this.next();
+  return this.finishNode(node, "Literal")
+};
+
+pp$3.parseParenExpression = function() {
+  this.expect(types.parenL);
+  var val = this.parseExpression();
+  this.expect(types.parenR);
+  return val
+};
+
+pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
+  var this$1 = this;
+
+  var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
+  if (this.options.ecmaVersion >= 6) {
+    this.next();
+
+    var innerStartPos = this.start, innerStartLoc = this.startLoc;
+    var exprList = [], first = true, lastIsComma = false;
+    var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart;
+    this.yieldPos = 0;
+    this.awaitPos = 0;
+    while (this.type !== types.parenR) {
+      first ? first = false : this$1.expect(types.comma);
+      if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) {
+        lastIsComma = true;
+        break
+      } else if (this$1.type === types.ellipsis) {
+        spreadStart = this$1.start;
+        exprList.push(this$1.parseParenItem(this$1.parseRestBinding()));
+        if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); }
+        break
+      } else {
+        if (this$1.type === types.parenL && !innerParenStart) {
+          innerParenStart = this$1.start;
+        }
+        exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem));
+      }
+    }
+    var innerEndPos = this.start, innerEndLoc = this.startLoc;
+    this.expect(types.parenR);
+
+    if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
+      this.checkPatternErrors(refDestructuringErrors, false);
+      this.checkYieldAwaitInDefaultParams();
+      if (innerParenStart) { this.unexpected(innerParenStart); }
+      this.yieldPos = oldYieldPos;
+      this.awaitPos = oldAwaitPos;
+      return this.parseParenArrowList(startPos, startLoc, exprList)
+    }
+
+    if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
+    if (spreadStart) { this.unexpected(spreadStart); }
+    this.checkExpressionErrors(refDestructuringErrors, true);
+    this.yieldPos = oldYieldPos || this.yieldPos;
+    this.awaitPos = oldAwaitPos || this.awaitPos;
+
+    if (exprList.length > 1) {
+      val = this.startNodeAt(innerStartPos, innerStartLoc);
+      val.expressions = exprList;
+      this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
+    } else {
+      val = exprList[0];
+    }
+  } else {
+    val = this.parseParenExpression();
+  }
+
+  if (this.options.preserveParens) {
+    var par = this.startNodeAt(startPos, startLoc);
+    par.expression = val;
+    return this.finishNode(par, "ParenthesizedExpression")
+  } else {
+    return val
+  }
+};
+
+pp$3.parseParenItem = function(item) {
+  return item
+};
+
+pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
+  return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
+};
+
+// New's precedence is slightly tricky. It must allow its argument to
+// be a `[]` or dot subscript expression, but not a call — at least,
+// not without wrapping it in parentheses. Thus, it uses the noCalls
+// argument to parseSubscripts to prevent it from consuming the
+// argument list.
+
+var empty$1 = [];
+
+pp$3.parseNew = function() {
+  var node = this.startNode();
+  var meta = this.parseIdent(true);
+  if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {
+    node.meta = meta;
+    node.property = this.parseIdent(true);
+    if (node.property.name !== "target")
+      { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); }
+    if (!this.inFunction)
+      { this.raiseRecoverable(node.start, "new.target can only be used in functions"); }
+    return this.finishNode(node, "MetaProperty")
+  }
+  var startPos = this.start, startLoc = this.startLoc;
+  node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
+  if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }
+  else { node.arguments = empty$1; }
+  return this.finishNode(node, "NewExpression")
+};
+
+// Parse template expression.
+
+pp$3.parseTemplateElement = function(ref) {
+  var isTagged = ref.isTagged;
+
+  var elem = this.startNode();
+  if (this.type === types.invalidTemplate) {
+    if (!isTagged) {
+      this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
+    }
+    elem.value = {
+      raw: this.value,
+      cooked: null
+    };
+  } else {
+    elem.value = {
+      raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
+      cooked: this.value
+    };
+  }
+  this.next();
+  elem.tail = this.type === types.backQuote;
+  return this.finishNode(elem, "TemplateElement")
+};
+
+pp$3.parseTemplate = function(ref) {
+  var this$1 = this;
+  if ( ref === void 0 ) ref = {};
+  var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
+
+  var node = this.startNode();
+  this.next();
+  node.expressions = [];
+  var curElt = this.parseTemplateElement({isTagged: isTagged});
+  node.quasis = [curElt];
+  while (!curElt.tail) {
+    this$1.expect(types.dollarBraceL);
+    node.expressions.push(this$1.parseExpression());
+    this$1.expect(types.braceR);
+    node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged}));
+  }
+  this.next();
+  return this.finishNode(node, "TemplateLiteral")
+};
+
+pp$3.isAsyncProp = function(prop) {
+  return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
+    (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword) &&
+    !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
+};
+
+// Parse an object literal or binding pattern.
+
+pp$3.parseObj = function(isPattern, refDestructuringErrors) {
+  var this$1 = this;
+
+  var node = this.startNode(), first = true, propHash = {};
+  node.properties = [];
+  this.next();
+  while (!this.eat(types.braceR)) {
+    if (!first) {
+      this$1.expect(types.comma);
+      if (this$1.afterTrailingComma(types.braceR)) { break }
+    } else { first = false; }
+
+    var prop = this$1.parseProperty(isPattern, refDestructuringErrors);
+    this$1.checkPropClash(prop, propHash);
+    node.properties.push(prop);
+  }
+  return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
+};
+
+pp$3.parseProperty = function(isPattern, refDestructuringErrors) {
+  var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
+  if (this.options.ecmaVersion >= 6) {
+    prop.method = false;
+    prop.shorthand = false;
+    if (isPattern || refDestructuringErrors) {
+      startPos = this.start;
+      startLoc = this.startLoc;
+    }
+    if (!isPattern)
+      { isGenerator = this.eat(types.star); }
+  }
+  this.parsePropertyName(prop);
+  if (!isPattern && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
+    isAsync = true;
+    this.parsePropertyName(prop, refDestructuringErrors);
+  } else {
+    isAsync = false;
+  }
+  this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors);
+  return this.finishNode(prop, "Property")
+};
+
+pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) {
+  if ((isGenerator || isAsync) && this.type === types.colon)
+    { this.unexpected(); }
+
+  if (this.eat(types.colon)) {
+    prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
+    prop.kind = "init";
+  } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {
+    if (isPattern) { this.unexpected(); }
+    prop.kind = "init";
+    prop.method = true;
+    prop.value = this.parseMethod(isGenerator, isAsync);
+  } else if (!isPattern &&
+             this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
+             (prop.key.name === "get" || prop.key.name === "set") &&
+             (this.type != types.comma && this.type != types.braceR)) {
+    if (isGenerator || isAsync) { this.unexpected(); }
+    prop.kind = prop.key.name;
+    this.parsePropertyName(prop);
+    prop.value = this.parseMethod(false);
+    var paramCount = prop.kind === "get" ? 0 : 1;
+    if (prop.value.params.length !== paramCount) {
+      var start = prop.value.start;
+      if (prop.kind === "get")
+        { this.raiseRecoverable(start, "getter should have no params"); }
+      else
+        { this.raiseRecoverable(start, "setter should have exactly one param"); }
+    } else {
+      if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
+        { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
+    }
+  } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
+    this.checkUnreserved(prop.key);
+    prop.kind = "init";
+    if (isPattern) {
+      prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
+    } else if (this.type === types.eq && refDestructuringErrors) {
+      if (refDestructuringErrors.shorthandAssign < 0)
+        { refDestructuringErrors.shorthandAssign = this.start; }
+      prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
+    } else {
+      prop.value = prop.key;
+    }
+    prop.shorthand = true;
+  } else { this.unexpected(); }
+};
+
+pp$3.parsePropertyName = function(prop) {
+  if (this.options.ecmaVersion >= 6) {
+    if (this.eat(types.bracketL)) {
+      prop.computed = true;
+      prop.key = this.parseMaybeAssign();
+      this.expect(types.bracketR);
+      return prop.key
+    } else {
+      prop.computed = false;
+    }
+  }
+  return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true)
+};
+
+// Initialize empty function node.
+
+pp$3.initFunction = function(node) {
+  node.id = null;
+  if (this.options.ecmaVersion >= 6) {
+    node.generator = false;
+    node.expression = false;
+  }
+  if (this.options.ecmaVersion >= 8)
+    { node.async = false; }
+};
+
+// Parse object or class method.
+
+pp$3.parseMethod = function(isGenerator, isAsync) {
+  var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,
+      oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
+
+  this.initFunction(node);
+  if (this.options.ecmaVersion >= 6)
+    { node.generator = isGenerator; }
+  if (this.options.ecmaVersion >= 8)
+    { node.async = !!isAsync; }
+
+  this.inGenerator = node.generator;
+  this.inAsync = node.async;
+  this.yieldPos = 0;
+  this.awaitPos = 0;
+  this.inFunction = true;
+  this.enterFunctionScope();
+
+  this.expect(types.parenL);
+  node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
+  this.checkYieldAwaitInDefaultParams();
+  this.parseFunctionBody(node, false);
+
+  this.inGenerator = oldInGen;
+  this.inAsync = oldInAsync;
+  this.yieldPos = oldYieldPos;
+  this.awaitPos = oldAwaitPos;
+  this.inFunction = oldInFunc;
+  return this.finishNode(node, "FunctionExpression")
+};
+
+// Parse arrow function expression with given parameters.
+
+pp$3.parseArrowExpression = function(node, params, isAsync) {
+  var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
+      oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
+
+  this.enterFunctionScope();
+  this.initFunction(node);
+  if (this.options.ecmaVersion >= 8)
+    { node.async = !!isAsync; }
+
+  this.inGenerator = false;
+  this.inAsync = node.async;
+  this.yieldPos = 0;
+  this.awaitPos = 0;
+  this.inFunction = true;
+
+  node.params = this.toAssignableList(params, true);
+  this.parseFunctionBody(node, true);
+
+  this.inGenerator = oldInGen;
+  this.inAsync = oldInAsync;
+  this.yieldPos = oldYieldPos;
+  this.awaitPos = oldAwaitPos;
+  this.inFunction = oldInFunc;
+  return this.finishNode(node, "ArrowFunctionExpression")
+};
+
+// Parse function body and check parameters.
+
+pp$3.parseFunctionBody = function(node, isArrowFunction) {
+  var isExpression = isArrowFunction && this.type !== types.braceL;
+  var oldStrict = this.strict, useStrict = false;
+
+  if (isExpression) {
+    node.body = this.parseMaybeAssign();
+    node.expression = true;
+    this.checkParams(node, false);
+  } else {
+    var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
+    if (!oldStrict || nonSimple) {
+      useStrict = this.strictDirective(this.end);
+      // If this is a strict mode function, verify that argument names
+      // are not repeated, and it does not try to bind the words `eval`
+      // or `arguments`.
+      if (useStrict && nonSimple)
+        { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
+    }
+    // Start a new scope with regard to labels and the `inFunction`
+    // flag (restore them to their old value afterwards).
+    var oldLabels = this.labels;
+    this.labels = [];
+    if (useStrict) { this.strict = true; }
+
+    // Add the params to varDeclaredNames to ensure that an error is thrown
+    // if a let/const declaration in the function clashes with one of the params.
+    this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params));
+    node.body = this.parseBlock(false);
+    node.expression = false;
+    this.adaptDirectivePrologue(node.body.body);
+    this.labels = oldLabels;
+  }
+  this.exitFunctionScope();
+
+  if (this.strict && node.id) {
+    // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
+    this.checkLVal(node.id, "none");
+  }
+  this.strict = oldStrict;
+};
+
+pp$3.isSimpleParamList = function(params) {
+  for (var i = 0, list = params; i < list.length; i += 1)
+    {
+    var param = list[i];
+
+    if (param.type !== "Identifier") { return false
+  } }
+  return true
+};
+
+// Checks function params for various disallowed patterns such as using "eval"
+// or "arguments" and duplicate parameters.
+
+pp$3.checkParams = function(node, allowDuplicates) {
+  var this$1 = this;
+
+  var nameHash = {};
+  for (var i = 0, list = node.params; i < list.length; i += 1)
+    {
+    var param = list[i];
+
+    this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash);
+  }
+};
+
+// Parses a comma-separated list of expressions, and returns them as
+// an array. `close` is the token type that ends the list, and
+// `allowEmpty` can be turned on to allow subsequent commas with
+// nothing in between them to be parsed as `null` (which is needed
+// for array literals).
+
+pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
+  var this$1 = this;
+
+  var elts = [], first = true;
+  while (!this.eat(close)) {
+    if (!first) {
+      this$1.expect(types.comma);
+      if (allowTrailingComma && this$1.afterTrailingComma(close)) { break }
+    } else { first = false; }
+
+    var elt = (void 0);
+    if (allowEmpty && this$1.type === types.comma)
+      { elt = null; }
+    else if (this$1.type === types.ellipsis) {
+      elt = this$1.parseSpread(refDestructuringErrors);
+      if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0)
+        { refDestructuringErrors.trailingComma = this$1.start; }
+    } else {
+      elt = this$1.parseMaybeAssign(false, refDestructuringErrors);
+    }
+    elts.push(elt);
+  }
+  return elts
+};
+
+pp$3.checkUnreserved = function(ref) {
+  var start = ref.start;
+  var end = ref.end;
+  var name = ref.name;
+
+  if (this.inGenerator && name === "yield")
+    { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); }
+  if (this.inAsync && name === "await")
+    { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); }
+  if (this.isKeyword(name))
+    { this.raise(start, ("Unexpected keyword '" + name + "'")); }
+  if (this.options.ecmaVersion < 6 &&
+    this.input.slice(start, end).indexOf("\\") != -1) { return }
+  var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
+  if (re.test(name))
+    { this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); }
+};
+
+// Parse the next token as an identifier. If `liberal` is true (used
+// when parsing properties), it will also convert keywords into
+// identifiers.
+
+pp$3.parseIdent = function(liberal, isBinding) {
+  var node = this.startNode();
+  if (liberal && this.options.allowReserved == "never") { liberal = false; }
+  if (this.type === types.name) {
+    node.name = this.value;
+  } else if (this.type.keyword) {
+    node.name = this.type.keyword;
+
+    // To fix https://github.com/ternjs/acorn/issues/575
+    // `class` and `function` keywords push new context into this.context.
+    // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
+    // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
+    if ((node.name === "class" || node.name === "function") &&
+        (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
+      this.context.pop();
+    }
+  } else {
+    this.unexpected();
+  }
+  this.next();
+  this.finishNode(node, "Identifier");
+  if (!liberal) { this.checkUnreserved(node); }
+  return node
+};
+
+// Parses yield expression inside generator.
+
+pp$3.parseYield = function() {
+  if (!this.yieldPos) { this.yieldPos = this.start; }
+
+  var node = this.startNode();
+  this.next();
+  if (this.type == types.semi || this.canInsertSemicolon() || (this.type != types.star && !this.type.startsExpr)) {
+    node.delegate = false;
+    node.argument = null;
+  } else {
+    node.delegate = this.eat(types.star);
+    node.argument = this.parseMaybeAssign();
+  }
+  return this.finishNode(node, "YieldExpression")
+};
+
+pp$3.parseAwait = function() {
+  if (!this.awaitPos) { this.awaitPos = this.start; }
+
+  var node = this.startNode();
+  this.next();
+  node.argument = this.parseMaybeUnary(null, true);
+  return this.finishNode(node, "AwaitExpression")
+};
+
+var pp$4 = Parser.prototype;
+
+// This function is used to raise exceptions on parse errors. It
+// takes an offset integer (into the current `input`) to indicate
+// the location of the error, attaches the position to the end
+// of the error message, and then raises a `SyntaxError` with that
+// message.
+
+pp$4.raise = function(pos, message) {
+  var loc = getLineInfo(this.input, pos);
+  message += " (" + loc.line + ":" + loc.column + ")";
+  var err = new SyntaxError(message);
+  err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
+  throw err
+};
+
+pp$4.raiseRecoverable = pp$4.raise;
+
+pp$4.curPosition = function() {
+  if (this.options.locations) {
+    return new Position(this.curLine, this.pos - this.lineStart)
+  }
+};
+
+var pp$5 = Parser.prototype;
+
+// Object.assign polyfill
+var assign = Object.assign || function(target) {
+  var sources = [], len = arguments.length - 1;
+  while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];
+
+  for (var i = 0, list = sources; i < list.length; i += 1) {
+    var source = list[i];
+
+    for (var key in source) {
+      if (has(source, key)) {
+        target[key] = source[key];
+      }
+    }
+  }
+  return target
+};
+
+// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
+
+pp$5.enterFunctionScope = function() {
+  // var: a hash of var-declared names in the current lexical scope
+  // lexical: a hash of lexically-declared names in the current lexical scope
+  // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope)
+  // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope)
+  this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}});
+};
+
+pp$5.exitFunctionScope = function() {
+  this.scopeStack.pop();
+};
+
+pp$5.enterLexicalScope = function() {
+  var parentScope = this.scopeStack[this.scopeStack.length - 1];
+  var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}};
+
+  this.scopeStack.push(childScope);
+  assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical);
+};
+
+pp$5.exitLexicalScope = function() {
+  var childScope = this.scopeStack.pop();
+  var parentScope = this.scopeStack[this.scopeStack.length - 1];
+
+  assign(parentScope.childVar, childScope.var, childScope.childVar);
+};
+
+/**
+ * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const`
+ * in the current lexical scope or any of the parent lexical scopes in this function.
+ */
+pp$5.canDeclareVarName = function(name) {
+  var currentScope = this.scopeStack[this.scopeStack.length - 1];
+
+  return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name)
+};
+
+/**
+ * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const`
+ * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in
+ * any child lexical scopes in this function.
+ */
+pp$5.canDeclareLexicalName = function(name) {
+  var currentScope = this.scopeStack[this.scopeStack.length - 1];
+
+  return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name)
+};
+
+pp$5.declareVarName = function(name) {
+  this.scopeStack[this.scopeStack.length - 1].var[name] = true;
+};
+
+pp$5.declareLexicalName = function(name) {
+  this.scopeStack[this.scopeStack.length - 1].lexical[name] = true;
+};
+
+var Node = function Node(parser, pos, loc) {
+  this.type = "";
+  this.start = pos;
+  this.end = 0;
+  if (parser.options.locations)
+    { this.loc = new SourceLocation(parser, loc); }
+  if (parser.options.directSourceFile)
+    { this.sourceFile = parser.options.directSourceFile; }
+  if (parser.options.ranges)
+    { this.range = [pos, 0]; }
+};
+
+// Start an AST node, attaching a start offset.
+
+var pp$6 = Parser.prototype;
+
+pp$6.startNode = function() {
+  return new Node(this, this.start, this.startLoc)
+};
+
+pp$6.startNodeAt = function(pos, loc) {
+  return new Node(this, pos, loc)
+};
+
+// Finish an AST node, adding `type` and `end` properties.
+
+function finishNodeAt(node, type, pos, loc) {
+  node.type = type;
+  node.end = pos;
+  if (this.options.locations)
+    { node.loc.end = loc; }
+  if (this.options.ranges)
+    { node.range[1] = pos; }
+  return node
+}
+
+pp$6.finishNode = function(node, type) {
+  return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
+};
+
+// Finish node at given position
+
+pp$6.finishNodeAt = function(node, type, pos, loc) {
+  return finishNodeAt.call(this, node, type, pos, loc)
+};
+
 // The algorithm used to determine whether a regexp can appear at a
 // given point in the program is loosely based on sweet.js' approach.
 // See https://github.com/mozilla/sweet.js/wiki/design
 
-"use strict";
-
-exports.__esModule = true;
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var _state = _dereq_("./state");
-
-var _tokentype = _dereq_("./tokentype");
-
-var _whitespace = _dereq_("./whitespace");
-
-var TokContext = function TokContext(token, isExpr, preserveSpace, override) {
-  _classCallCheck(this, TokContext);
-
+var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
   this.token = token;
   this.isExpr = !!isExpr;
   this.preserveSpace = !!preserveSpace;
   this.override = override;
-};
-
-exports.TokContext = TokContext;
-var types = {
+  this.generator = !!generator;
+};
+
+var types$1 = {
   b_stat: new TokContext("{", false),
   b_expr: new TokContext("{", true),
-  b_tmpl: new TokContext("${", true),
+  b_tmpl: new TokContext("${", false),
   p_stat: new TokContext("(", false),
   p_expr: new TokContext("(", true),
-  q_tmpl: new TokContext("`", true, true, function (p) {
-    return p.readTmplToken();
-  }),
-  f_expr: new TokContext("function", true)
-};
-
-exports.types = types;
-var pp = _state.Parser.prototype;
-
-pp.initialContext = function () {
-  return [types.b_stat];
-};
-
-pp.braceIsBlock = function (prevType) {
-  if (prevType === _tokentype.types.colon) {
-    var _parent = this.curContext();
-    if (_parent === types.b_stat || _parent === types.b_expr) return !_parent.isExpr;
-  }
-  if (prevType === _tokentype.types._return) return _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
-  if (prevType === _tokentype.types._else || prevType === _tokentype.types.semi || prevType === _tokentype.types.eof || prevType === _tokentype.types.parenR) return true;
-  if (prevType == _tokentype.types.braceL) return this.curContext() === types.b_stat;
-  return !this.exprAllowed;
-};
-
-pp.updateContext = function (prevType) {
-  var update = undefined,
-      type = this.type;
-  if (type.keyword && prevType == _tokentype.types.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr;
+  q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
+  f_stat: new TokContext("function", false),
+  f_expr: new TokContext("function", true),
+  f_expr_gen: new TokContext("function", true, false, null, true),
+  f_gen: new TokContext("function", false, false, null, true)
+};
+
+var pp$7 = Parser.prototype;
+
+pp$7.initialContext = function() {
+  return [types$1.b_stat]
+};
+
+pp$7.braceIsBlock = function(prevType) {
+  var parent = this.curContext();
+  if (parent === types$1.f_expr || parent === types$1.f_stat)
+    { return true }
+  if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))
+    { return !parent.isExpr }
+
+  // The check for `tt.name && exprAllowed` detects whether we are
+  // after a `yield` or `of` construct. See the `updateContext` for
+  // `tt.name`.
+  if (prevType === types._return || prevType == types.name && this.exprAllowed)
+    { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
+  if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType == types.arrow)
+    { return true }
+  if (prevType == types.braceL)
+    { return parent === types$1.b_stat }
+  if (prevType == types._var || prevType == types.name)
+    { return false }
+  return !this.exprAllowed
+};
+
+pp$7.inGeneratorContext = function() {
+  var this$1 = this;
+
+  for (var i = this.context.length - 1; i >= 1; i--) {
+    var context = this$1.context[i];
+    if (context.token === "function")
+      { return context.generator }
+  }
+  return false
+};
+
+pp$7.updateContext = function(prevType) {
+  var update, type = this.type;
+  if (type.keyword && prevType == types.dot)
+    { this.exprAllowed = false; }
+  else if (update = type.updateContext)
+    { update.call(this, prevType); }
+  else
+    { this.exprAllowed = type.beforeExpr; }
 };
 
 // Token-specific context update code
 
-_tokentype.types.parenR.updateContext = _tokentype.types.braceR.updateContext = function () {
+types.parenR.updateContext = types.braceR.updateContext = function() {
   if (this.context.length == 1) {
     this.exprAllowed = true;
-    return;
+    return
   }
   var out = this.context.pop();
-  if (out === types.b_stat && this.curContext() === types.f_expr) {
-    this.context.pop();
-    this.exprAllowed = false;
-  } else if (out === types.b_tmpl) {
-    this.exprAllowed = true;
-  } else {
-    this.exprAllowed = !out.isExpr;
-  }
-};
-
-_tokentype.types.braceL.updateContext = function (prevType) {
-  this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
+  if (out === types$1.b_stat && this.curContext().token === "function") {
+    out = this.context.pop();
+  }
+  this.exprAllowed = !out.isExpr;
+};
+
+types.braceL.updateContext = function(prevType) {
+  this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);
   this.exprAllowed = true;
 };
 
-_tokentype.types.dollarBraceL.updateContext = function () {
-  this.context.push(types.b_tmpl);
+types.dollarBraceL.updateContext = function() {
+  this.context.push(types$1.b_tmpl);
   this.exprAllowed = true;
 };
 
-_tokentype.types.parenL.updateContext = function (prevType) {
-  var statementParens = prevType === _tokentype.types._if || prevType === _tokentype.types._for || prevType === _tokentype.types._with || prevType === _tokentype.types._while;
-  this.context.push(statementParens ? types.p_stat : types.p_expr);
+types.parenL.updateContext = function(prevType) {
+  var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
+  this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);
   this.exprAllowed = true;
 };
 
-_tokentype.types.incDec.updateContext = function () {
+types.incDec.updateContext = function() {
   // tokExprAllowed stays unchanged
 };
 
-_tokentype.types._function.updateContext = function () {
-  if (this.curContext() !== types.b_stat) this.context.push(types.f_expr);
+types._function.updateContext = types._class.updateContext = function(prevType) {
+  if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&
+      !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))
+    { this.context.push(types$1.f_expr); }
+  else
+    { this.context.push(types$1.f_stat); }
   this.exprAllowed = false;
 };
 
-_tokentype.types.backQuote.updateContext = function () {
-  if (this.curContext() === types.q_tmpl) this.context.pop();else this.context.push(types.q_tmpl);
+types.backQuote.updateContext = function() {
+  if (this.curContext() === types$1.q_tmpl)
+    { this.context.pop(); }
+  else
+    { this.context.push(types$1.q_tmpl); }
   this.exprAllowed = false;
 };
 
-},{"./state":10,"./tokentype":14,"./whitespace":16}],13:[function(_dereq_,module,exports){
-"use strict";
-
-exports.__esModule = true;
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var _identifier = _dereq_("./identifier");
-
-var _tokentype = _dereq_("./tokentype");
-
-var _state = _dereq_("./state");
-
-var _locutil = _dereq_("./locutil");
-
-var _whitespace = _dereq_("./whitespace");
+types.star.updateContext = function(prevType) {
+  if (prevType == types._function) {
+    var index = this.context.length - 1;
+    if (this.context[index] === types$1.f_expr)
+      { this.context[index] = types$1.f_expr_gen; }
+    else
+      { this.context[index] = types$1.f_gen; }
+  }
+  this.exprAllowed = true;
+};
+
+types.name.updateContext = function(prevType) {
+  var allowed = false;
+  if (this.options.ecmaVersion >= 6) {
+    if (this.value == "of" && !this.exprAllowed ||
+        this.value == "yield" && this.inGeneratorContext())
+      { allowed = true; }
+  }
+  this.exprAllowed = allowed;
+};
 
 // Object type used to represent tokens. Note that normally, tokens
 // simply exist as properties on the parser object. This is only
 // used for the onToken callback and the external tokenizer.
 
 var Token = function Token(p) {
-  _classCallCheck(this, Token);
-
   this.type = p.type;
   this.value = p.value;
   this.start = p.start;
   this.end = p.end;
-  if (p.options.locations) this.loc = new _locutil.SourceLocation(p, p.startLoc, p.endLoc);
-  if (p.options.ranges) this.range = [p.start, p.end];
-}
+  if (p.options.locations)
+    { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
+  if (p.options.ranges)
+    { this.range = [p.start, p.end]; }
+};
 
 // ## Tokenizer
 
-;
-
-exports.Token = Token;
-var pp = _state.Parser.prototype;
+var pp$8 = Parser.prototype;
 
 // Are we running under Rhino?
 var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]";
 
 // Move to the next token
 
-pp.next = function () {
-  if (this.options.onToken) this.options.onToken(new Token(this));
+pp$8.next = function() {
+  if (this.options.onToken)
+    { this.options.onToken(new Token(this)); }
 
   this.lastTokEnd = this.end;
   this.lastTokStart = this.start;
   this.lastTokEndLoc = this.endLoc;
   this.lastTokStartLoc = this.startLoc;
   this.nextToken();
 };
 
-pp.getToken = function () {
+pp$8.getToken = function() {
   this.next();
-  return new Token(this);
+  return new Token(this)
 };
 
 // If we're in an ES6 environment, make parsers iterable
-if (typeof Symbol !== "undefined") pp[Symbol.iterator] = function () {
-  var self = this;
-  return { next: function next() {
-      var token = self.getToken();
-      return {
-        done: token.type === _tokentype.types.eof,
-        value: token
-      };
-    } };
-};
+if (typeof Symbol !== "undefined")
+  { pp$8[Symbol.iterator] = function() {
+    var this$1 = this;
+
+    return {
+      next: function () {
+        var token = this$1.getToken();
+        return {
+          done: token.type === types.eof,
+          value: token
+        }
+      }
+    }
+  }; }
 
 // Toggle strict mode. Re-reads the next number or string to please
 // pedantic tests (`"use strict"; 010;` should fail).
 
-pp.setStrict = function (strict) {
-  this.strict = strict;
-  if (this.type !== _tokentype.types.num && this.type !== _tokentype.types.string) return;
-  this.pos = this.start;
-  if (this.options.locations) {
-    while (this.pos < this.lineStart) {
-      this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
-      --this.curLine;
-    }
-  }
-  this.nextToken();
-};
-
-pp.curContext = function () {
-  return this.context[this.context.length - 1];
+pp$8.curContext = function() {
+  return this.context[this.context.length - 1]
 };
 
 // Read a single token, updating the parser object's token-related
 // properties.
 
-pp.nextToken = function () {
+pp$8.nextToken = function() {
   var curContext = this.curContext();
-  if (!curContext || !curContext.preserveSpace) this.skipSpace();
+  if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
 
   this.start = this.pos;
-  if (this.options.locations) this.startLoc = this.curPosition();
-  if (this.pos >= this.input.length) return this.finishToken(_tokentype.types.eof);
-
-  if (curContext.override) return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());
-};
-
-pp.readToken = function (code) {
+  if (this.options.locations) { this.startLoc = this.curPosition(); }
+  if (this.pos >= this.input.length) { return this.finishToken(types.eof) }
+
+  if (curContext.override) { return curContext.override(this) }
+  else { this.readToken(this.fullCharCodeAtPos()); }
+};
+
+pp$8.readToken = function(code) {
   // Identifier or keyword. '\uXXXX' sequences are allowed in
   // identifiers, so '\' also dispatches to that.
-  if (_identifier.isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) return this.readWord();
-
-  return this.getTokenFromCode(code);
-};
-
-pp.fullCharCodeAtPos = function () {
+  if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
+    { return this.readWord() }
+
+  return this.getTokenFromCode(code)
+};
+
+pp$8.fullCharCodeAtPos = function() {
   var code = this.input.charCodeAt(this.pos);
-  if (code <= 0xd7ff || code >= 0xe000) return code;
+  if (code <= 0xd7ff || code >= 0xe000) { return code }
   var next = this.input.charCodeAt(this.pos + 1);
-  return (code << 10) + next - 0x35fdc00;
-};
-
-pp.skipBlockComment = function () {
+  return (code << 10) + next - 0x35fdc00
+};
+
+pp$8.skipBlockComment = function() {
+  var this$1 = this;
+
   var startLoc = this.options.onComment && this.curPosition();
-  var start = this.pos,
-      end = this.input.indexOf("*/", this.pos += 2);
-  if (end === -1) this.raise(this.pos - 2, "Unterminated comment");
+  var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
+  if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
   this.pos = end + 2;
   if (this.options.locations) {
-    _whitespace.lineBreakG.lastIndex = start;
-    var match = undefined;
-    while ((match = _whitespace.lineBreakG.exec(this.input)) && match.index < this.pos) {
-      ++this.curLine;
-      this.lineStart = match.index + match[0].length;
-    }
-  }
-  if (this.options.onComment) this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.curPosition());
-};
-
-pp.skipLineComment = function (startSkip) {
+    lineBreakG.lastIndex = start;
+    var match;
+    while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
+      ++this$1.curLine;
+      this$1.lineStart = match.index + match[0].length;
+    }
+  }
+  if (this.options.onComment)
+    { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
+                           startLoc, this.curPosition()); }
+};
+
+pp$8.skipLineComment = function(startSkip) {
+  var this$1 = this;
+
   var start = this.pos;
   var startLoc = this.options.onComment && this.curPosition();
   var ch = this.input.charCodeAt(this.pos += startSkip);
-  while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
-    ++this.pos;
-    ch = this.input.charCodeAt(this.pos);
-  }
-  if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.curPosition());
+  while (this.pos < this.input.length && !isNewLine(ch)) {
+    ch = this$1.input.charCodeAt(++this$1.pos);
+  }
+  if (this.options.onComment)
+    { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
+                           startLoc, this.curPosition()); }
 };
 
 // Called at the start of the parse and after every token. Skips
 // whitespace and comments, and.
 
-pp.skipSpace = function () {
+pp$8.skipSpace = function() {
+  var this$1 = this;
+
   loop: while (this.pos < this.input.length) {
-    var ch = this.input.charCodeAt(this.pos);
+    var ch = this$1.input.charCodeAt(this$1.pos);
     switch (ch) {
-      case 32:case 160:
-        // ' '
-        ++this.pos;
-        break;
-      case 13:
-        if (this.input.charCodeAt(this.pos + 1) === 10) {
-          ++this.pos;
-        }
-      case 10:case 8232:case 8233:
-        ++this.pos;
-        if (this.options.locations) {
-          ++this.curLine;
-          this.lineStart = this.pos;
-        }
-        break;
+    case 32: case 160: // ' '
+      ++this$1.pos;
+      break
+    case 13:
+      if (this$1.input.charCodeAt(this$1.pos + 1) === 10) {
+        ++this$1.pos;
+      }
+    case 10: case 8232: case 8233:
+      ++this$1.pos;
+      if (this$1.options.locations) {
+        ++this$1.curLine;
+        this$1.lineStart = this$1.pos;
+      }
+      break
+    case 47: // '/'
+      switch (this$1.input.charCodeAt(this$1.pos + 1)) {
+      case 42: // '*'
+        this$1.skipBlockComment();
+        break
       case 47:
-        // '/'
-        switch (this.input.charCodeAt(this.pos + 1)) {
-          case 42:
-            // '*'
-            this.skipBlockComment();
-            break;
-          case 47:
-            this.skipLineComment(2);
-            break;
-          default:
-            break loop;
-        }
-        break;
+        this$1.skipLineComment(2);
+        break
       default:
-        if (ch > 8 && ch < 14 || ch >= 5760 && _whitespace.nonASCIIwhitespace.test(String.fromCharCode(ch))) {
-          ++this.pos;
-        } else {
-          break loop;
-        }
+        break loop
+      }
+      break
+    default:
+      if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
+        ++this$1.pos;
+      } else {
+        break loop
+      }
     }
   }
 };
 
 // Called at the end of every token. Sets `end`, `val`, and
 // maintains `context` and `exprAllowed`, and skips the space after
 // the token, so that the next one's `start` will point at the
 // right position.
 
-pp.finishToken = function (type, val) {
+pp$8.finishToken = function(type, val) {
   this.end = this.pos;
-  if (this.options.locations) this.endLoc = this.curPosition();
+  if (this.options.locations) { this.endLoc = this.curPosition(); }
   var prevType = this.type;
   this.type = type;
   this.value = val;
 
   this.updateContext(prevType);
 };
 
 // ### Token reading
 
 // This is the function that is called to fetch the next token. It
 // is somewhat obscure, because it works in character codes rather
 // than characters, and because operator parsing has been inlined
 // into it.
 //
 // All in the name of speed.
 //
-pp.readToken_dot = function () {
+pp$8.readToken_dot = function() {
   var next = this.input.charCodeAt(this.pos + 1);
-  if (next >= 48 && next <= 57) return this.readNumber(true);
+  if (next >= 48 && next <= 57) { return this.readNumber(true) }
   var next2 = this.input.charCodeAt(this.pos + 2);
-  if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
-    // 46 = dot '.'
+  if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
     this.pos += 3;
-    return this.finishToken(_tokentype.types.ellipsis);
+    return this.finishToken(types.ellipsis)
   } else {
     ++this.pos;
-    return this.finishToken(_tokentype.types.dot);
-  }
-};
-
-pp.readToken_slash = function () {
-  // '/'
+    return this.finishToken(types.dot)
+  }
+};
+
+pp$8.readToken_slash = function() { // '/'
   var next = this.input.charCodeAt(this.pos + 1);
-  if (this.exprAllowed) {
-    ++this.pos;return this.readRegexp();
-  }
-  if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
-  return this.finishOp(_tokentype.types.slash, 1);
-};
-
-pp.readToken_mult_modulo = function (code) {
-  // '%*'
+  if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
+  if (next === 61) { return this.finishOp(types.assign, 2) }
+  return this.finishOp(types.slash, 1)
+};
+
+pp$8.readToken_mult_modulo_exp = function(code) { // '%*'
   var next = this.input.charCodeAt(this.pos + 1);
-  if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
-  return this.finishOp(code === 42 ? _tokentype.types.star : _tokentype.types.modulo, 1);
-};
-
-pp.readToken_pipe_amp = function (code) {
-  // '|&'
+  var size = 1;
+  var tokentype = code === 42 ? types.star : types.modulo;
+
+  // exponentiation operator ** and **=
+  if (this.options.ecmaVersion >= 7 && code == 42 && next === 42) {
+    ++size;
+    tokentype = types.starstar;
+    next = this.input.charCodeAt(this.pos + 2);
+  }
+
+  if (next === 61) { return this.finishOp(types.assign, size + 1) }
+  return this.finishOp(tokentype, size)
+};
+
+pp$8.readToken_pipe_amp = function(code) { // '|&'
   var next = this.input.charCodeAt(this.pos + 1);
-  if (next === code) return this.finishOp(code === 124 ? _tokentype.types.logicalOR : _tokentype.types.logicalAND, 2);
-  if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
-  return this.finishOp(code === 124 ? _tokentype.types.bitwiseOR : _tokentype.types.bitwiseAND, 1);
-};
-
-pp.readToken_caret = function () {
-  // '^'
+  if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }
+  if (next === 61) { return this.finishOp(types.assign, 2) }
+  return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)
+};
+
+pp$8.readToken_caret = function() { // '^'
   var next = this.input.charCodeAt(this.pos + 1);
-  if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
-  return this.finishOp(_tokentype.types.bitwiseXOR, 1);
-};
-
-pp.readToken_plus_min = function (code) {
-  // '+-'
+  if (next === 61) { return this.finishOp(types.assign, 2) }
+  return this.finishOp(types.bitwiseXOR, 1)
+};
+
+pp$8.readToken_plus_min = function(code) { // '+-'
   var next = this.input.charCodeAt(this.pos + 1);
   if (next === code) {
-    if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
+    if (next == 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 62 &&
+        (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
       // A `-->` line comment
       this.skipLineComment(3);
       this.skipSpace();
-      return this.nextToken();
-    }
-    return this.finishOp(_tokentype.types.incDec, 2);
-  }
-  if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
-  return this.finishOp(_tokentype.types.plusMin, 1);
-};
-
-pp.readToken_lt_gt = function (code) {
-  // '<>'
+      return this.nextToken()
+    }
+    return this.finishOp(types.incDec, 2)
+  }
+  if (next === 61) { return this.finishOp(types.assign, 2) }
+  return this.finishOp(types.plusMin, 1)
+};
+
+pp$8.readToken_lt_gt = function(code) { // '<>'
   var next = this.input.charCodeAt(this.pos + 1);
   var size = 1;
   if (next === code) {
     size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
-    if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(_tokentype.types.assign, size + 1);
-    return this.finishOp(_tokentype.types.bitShift, size);
-  }
-  if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) {
-    if (this.inModule) this.unexpected();
+    if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
+    return this.finishOp(types.bitShift, size)
+  }
+  if (next == 33 && code == 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 45 &&
+      this.input.charCodeAt(this.pos + 3) == 45) {
     // `<!--`, an XML-style comment that should be interpreted as a line comment
     this.skipLineComment(4);
     this.skipSpace();
-    return this.nextToken();
-  }
-  if (next === 61) size = this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2;
-  return this.finishOp(_tokentype.types.relational, size);
-};
-
-pp.readToken_eq_excl = function (code) {
-  // '=!'
+    return this.nextToken()
+  }
+  if (next === 61) { size = 2; }
+  return this.finishOp(types.relational, size)
+};
+
+pp$8.readToken_eq_excl = function(code) { // '=!'
   var next = this.input.charCodeAt(this.pos + 1);
-  if (next === 61) return this.finishOp(_tokentype.types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2);
-  if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
-    // '=>'
+  if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
+  if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
     this.pos += 2;
-    return this.finishToken(_tokentype.types.arrow);
-  }
-  return this.finishOp(code === 61 ? _tokentype.types.eq : _tokentype.types.prefix, 1);
-};
-
-pp.getTokenFromCode = function (code) {
+    return this.finishToken(types.arrow)
+  }
+  return this.finishOp(code === 61 ? types.eq : types.prefix, 1)
+};
+
+pp$8.getTokenFromCode = function(code) {
   switch (code) {
     // The interpretation of a dot depends on whether it is followed
     // by a digit or another two dots.
-    case 46:
-      // '.'
-      return this.readToken_dot();
+  case 46: // '.'
+    return this.readToken_dot()
 
     // Punctuation tokens.
-    case 40:
-      ++this.pos;return this.finishToken(_tokentype.types.parenL);
-    case 41:
-      ++this.pos;return this.finishToken(_tokentype.types.parenR);
-    case 59:
-      ++this.pos;return this.finishToken(_tokentype.types.semi);
-    case 44:
-      ++this.pos;return this.finishToken(_tokentype.types.comma);
-    case 91:
-      ++this.pos;return this.finishToken(_tokentype.types.bracketL);
-    case 93:
-      ++this.pos;return this.finishToken(_tokentype.types.bracketR);
-    case 123:
-      ++this.pos;return this.finishToken(_tokentype.types.braceL);
-    case 125:
-      ++this.pos;return this.finishToken(_tokentype.types.braceR);
-    case 58:
-      ++this.pos;return this.finishToken(_tokentype.types.colon);
-    case 63:
-      ++this.pos;return this.finishToken(_tokentype.types.question);
-
-    case 96:
-      // '`'
-      if (this.options.ecmaVersion < 6) break;
-      ++this.pos;
-      return this.finishToken(_tokentype.types.backQuote);
-
-    case 48:
-      // '0'
-      var next = this.input.charCodeAt(this.pos + 1);
-      if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
-      if (this.options.ecmaVersion >= 6) {
-        if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
-        if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
-      }
+  case 40: ++this.pos; return this.finishToken(types.parenL)
+  case 41: ++this.pos; return this.finishToken(types.parenR)
+  case 59: ++this.pos; return this.finishToken(types.semi)
+  case 44: ++this.pos; return this.finishToken(types.comma)
+  case 91: ++this.pos; return this.finishToken(types.bracketL)
+  case 93: ++this.pos; return this.finishToken(types.bracketR)
+  case 123: ++this.pos; return this.finishToken(types.braceL)
+  case 125: ++this.pos; return this.finishToken(types.braceR)
+  case 58: ++this.pos; return this.finishToken(types.colon)
+  case 63: ++this.pos; return this.finishToken(types.question)
+
+  case 96: // '`'
+    if (this.options.ecmaVersion < 6) { break }
+    ++this.pos;
+    return this.finishToken(types.backQuote)
+
+  case 48: // '0'
+    var next = this.input.charCodeAt(this.pos + 1);
+    if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
+    if (this.options.ecmaVersion >= 6) {
+      if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
+      if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
+    }
     // Anything else beginning with a digit is an integer, octal
     // number, or float.
-    case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
-      // 1-9
-      return this.readNumber(false);
+  case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
+    return this.readNumber(false)
 
     // Quotes produce strings.
-    case 34:case 39:
-      // '"', "'"
-      return this.readString(code);
+  case 34: case 39: // '"', "'"
+    return this.readString(code)
 
     // Operators are parsed inline in tiny state machines. '=' (61) is
     // often referred to. `finishOp` simply skips the amount of
     // characters it is given as second argument, and returns a token
     // of the type given by its first argument.
 
-    case 47:
-      // '/'
-      return this.readToken_slash();
-
-    case 37:case 42:
-      // '%*'
-      return this.readToken_mult_modulo(code);
-
-    case 124:case 38:
-      // '|&'
-      return this.readToken_pipe_amp(code);
-
-    case 94:
-      // '^'
-      return this.readToken_caret();
-
-    case 43:case 45:
-      // '+-'
-      return this.readToken_plus_min(code);
-
-    case 60:case 62:
-      // '<>'
-      return this.readToken_lt_gt(code);
-
-    case 61:case 33:
-      // '=!'
-      return this.readToken_eq_excl(code);
-
-    case 126:
-      // '~'
-      return this.finishOp(_tokentype.types.prefix, 1);
+  case 47: // '/'
+    return this.readToken_slash()
+
+  case 37: case 42: // '%*'
+    return this.readToken_mult_modulo_exp(code)
+
+  case 124: case 38: // '|&'
+    return this.readToken_pipe_amp(code)
+
+  case 94: // '^'
+    return this.readToken_caret()
+
+  case 43: case 45: // '+-'
+    return this.readToken_plus_min(code)
+
+  case 60: case 62: // '<>'
+    return this.readToken_lt_gt(code)
+
+  case 61: case 33: // '=!'
+    return this.readToken_eq_excl(code)
+
+  case 126: // '~'
+    return this.finishOp(types.prefix, 1)
   }
 
   this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
 };
 
-pp.finishOp = function (type, size) {
+pp$8.finishOp = function(type, size) {
   var str = this.input.slice(this.pos, this.pos + size);
   this.pos += size;
-  return this.finishToken(type, str);
+  return this.finishToken(type, str)
 };
 
 // Parse a regular expression. Some context-awareness is necessary,
 // since a '/' inside a '[]' set does not end the expression.
 
 function tryCreateRegexp(src, flags, throwErrorAt, parser) {
   try {
-    return new RegExp(src, flags);
+    return new RegExp(src, flags)
   } catch (e) {
     if (throwErrorAt !== undefined) {
-      if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message);
-      throw e;
+      if (e instanceof SyntaxError) { parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message); }
+      throw e
     }
   }
 }
 
-var regexpUnicodeSupport = !!tryCreateRegexp("￿", "u");
-
-pp.readRegexp = function () {
-  var _this = this;
-
-  var escaped = undefined,
-      inClass = undefined,
-      start = this.pos;
+var regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u");
+
+pp$8.readRegexp = function() {
+  var this$1 = this;
+
+  var escaped, inClass, start = this.pos;
   for (;;) {
-    if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
-    var ch = this.input.charAt(this.pos);
-    if (_whitespace.lineBreak.test(ch)) this.raise(start, "Unterminated regular expression");
+    if (this$1.pos >= this$1.input.length) { this$1.raise(start, "Unterminated regular expression"); }
+    var ch = this$1.input.charAt(this$1.pos);
+    if (lineBreak.test(ch)) { this$1.raise(start, "Unterminated regular expression"); }
     if (!escaped) {
-      if (ch === "[") inClass = true;else if (ch === "]" && inClass) inClass = false;else if (ch === "/" && !inClass) break;
+      if (ch === "[") { inClass = true; }
+      else if (ch === "]" && inClass) { inClass = false; }
+      else if (ch === "/" && !inClass) { break }
       escaped = ch === "\\";
-    } else escaped = false;
-    ++this.pos;
+    } else { escaped = false; }
+    ++this$1.pos;
   }
   var content = this.input.slice(start, this.pos);
   ++this.pos;
   // Need to use `readWord1` because '\uXXXX' sequences are allowed
   // here (don't ask).
   var mods = this.readWord1();
-  var tmp = content;
+  var tmp = content, tmpFlags = "";
   if (mods) {
-    var validFlags = /^[gmsiy]*$/;
-    if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
-    if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
-    if (mods.indexOf('u') >= 0 && !regexpUnicodeSupport) {
-      // Replace each astral symbol and every Unicode escape sequence that
-      // possibly represents an astral symbol or a paired surrogate with a
-      // single ASCII symbol to avoid throwing on regular expressions that
-      // are only valid in combination with the `/u` flag.
-      // Note: replacing with the ASCII symbol `x` might cause false
-      // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
-      // perfectly valid pattern that is equivalent to `[a-b]`, but it would
-      // be replaced by `[x-b]` which throws an error.
-      tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) {
-        code = Number("0x" + code);
-        if (code > 0x10FFFF) _this.raise(start + offset + 3, "Code point out of bounds");
-        return "x";
-      });
-      tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
+    var validFlags = /^[gim]*$/;
+    if (this.options.ecmaVersion >= 6) { validFlags = /^[gimuy]*$/; }
+    if (!validFlags.test(mods)) { this.raise(start, "Invalid regular expression flag"); }
+    if (mods.indexOf("u") >= 0) {
+      if (regexpUnicodeSupport) {
+        tmpFlags = "u";
+      } else {
+        // Replace each astral symbol and every Unicode escape sequence that
+        // possibly represents an astral symbol or a paired surrogate with a
+        // single ASCII symbol to avoid throwing on regular expressions that
+        // are only valid in combination with the `/u` flag.
+        // Note: replacing with the ASCII symbol `x` might cause false
+        // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
+        // perfectly valid pattern that is equivalent to `[a-b]`, but it would
+        // be replaced by `[x-b]` which throws an error.
+        tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) {
+          code = Number("0x" + code);
+          if (code > 0x10FFFF) { this$1.raise(start + offset + 3, "Code point out of bounds"); }
+          return "x"
+        });
+        tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
+        tmpFlags = tmpFlags.replace("u", "");
+      }
     }
   }
   // Detect invalid regular expressions.
   var value = null;
   // Rhino's regular expression parser is flaky and throws uncatchable exceptions,
   // so don't do detection if we are running under Rhino
   if (!isRhino) {
-    tryCreateRegexp(tmp, undefined, start, this);
+    tryCreateRegexp(tmp, tmpFlags, start, this);
     // Get a regular expression object for this pattern-flag pair, or `null` in
     // case the current environment doesn't support the flags it uses.
     value = tryCreateRegexp(content, mods);
   }
-  return this.finishToken(_tokentype.types.regexp, { pattern: content, flags: mods, value: value });
+  return this.finishToken(types.regexp, {pattern: content, flags: mods, value: value})
 };
 
 // Read an integer in the given radix. Return null if zero digits
 // were read, the integer value otherwise. When `len` is given, this
 // will return `null` unless the integer has exactly `len` digits.
 
-pp.readInt = function (radix, len) {
-  var start = this.pos,
-      total = 0;
+pp$8.readInt = function(radix, len) {
+  var this$1 = this;
+
+  var start = this.pos, total = 0;
   for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
-    var code = this.input.charCodeAt(this.pos),
-        val = undefined;
-    if (code >= 97) val = code - 97 + 10; // a
-    else if (code >= 65) val = code - 65 + 10; // A
-      else if (code >= 48 && code <= 57) val = code - 48; // 0-9
-        else val = Infinity;
-    if (val >= radix) break;
-    ++this.pos;
+    var code = this$1.input.charCodeAt(this$1.pos), val = (void 0);
+    if (code >= 97) { val = code - 97 + 10; } // a
+    else if (code >= 65) { val = code - 65 + 10; } // A
+    else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
+    else { val = Infinity; }
+    if (val >= radix) { break }
+    ++this$1.pos;
     total = total * radix + val;
   }
-  if (this.pos === start || len != null && this.pos - start !== len) return null;
-
-  return total;
-};
-
-pp.readRadixNumber = function (radix) {
+  if (this.pos === start || len != null && this.pos - start !== len) { return null }
+
+  return total
+};
+
+pp$8.readRadixNumber = function(radix) {
   this.pos += 2; // 0x
   var val = this.readInt(radix);
-  if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix);
-  if (_identifier.isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
-  return this.finishToken(_tokentype.types.num, val);
+  if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
+  if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
+  return this.finishToken(types.num, val)
 };
 
 // Read an integer, octal integer, or floating-point number.
 
-pp.readNumber = function (startsWithDot) {
-  var start = this.pos,
-      isFloat = false,
-      octal = this.input.charCodeAt(this.pos) === 48;
-  if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
+pp$8.readNumber = function(startsWithDot) {
+  var start = this.pos, isFloat = false, octal = this.input.charCodeAt(this.pos) === 48;
+  if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); }
+  if (octal && this.pos == start + 1) { octal = false; }
   var next = this.input.charCodeAt(this.pos);
-  if (next === 46) {
-    // '.'
+  if (next === 46 && !octal) { // '.'
     ++this.pos;
     this.readInt(10);
     isFloat = true;
     next = this.input.charCodeAt(this.pos);
   }
-  if (next === 69 || next === 101) {
-    // 'eE'
+  if ((next === 69 || next === 101) && !octal) { // 'eE'
     next = this.input.charCodeAt(++this.pos);
-    if (next === 43 || next === 45) ++this.pos; // '+-'
-    if (this.readInt(10) === null) this.raise(start, "Invalid number");
+    if (next === 43 || next === 45) { ++this.pos; } // '+-'
+    if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
     isFloat = true;
   }
-  if (_identifier.isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
-
-  var str = this.input.slice(start, this.pos),
-      val = undefined;
-  if (isFloat) val = parseFloat(str);else if (!octal || str.length === 1) val = parseInt(str, 10);else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number");else val = parseInt(str, 8);
-  return this.finishToken(_tokentype.types.num, val);
+  if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
+
+  var str = this.input.slice(start, this.pos), val;
+  if (isFloat) { val = parseFloat(str); }
+  else if (!octal || str.length === 1) { val = parseInt(str, 10); }
+  else if (this.strict) { this.raise(start, "Invalid number"); }
+  else if (/[89]/.test(str)) { val = parseInt(str, 10); }
+  else { val = parseInt(str, 8); }
+  return this.finishToken(types.num, val)
 };
 
 // Read a string value, interpreting backslash-escapes.
 
-pp.readCodePoint = function () {
-  var ch = this.input.charCodeAt(this.pos),
-      code = undefined;
-
-  if (ch === 123) {
-    if (this.options.ecmaVersion < 6) this.unexpected();
+pp$8.readCodePoint = function() {
+  var ch = this.input.charCodeAt(this.pos), code;
+
+  if (ch === 123) { // '{'
+    if (this.options.ecmaVersion < 6) { this.unexpected(); }
     var codePos = ++this.pos;
-    code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos);
+    code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
     ++this.pos;
-    if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds");
+    if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
   } else {
     code = this.readHexChar(4);
   }
-  return code;
+  return code
 };
 
 function codePointToString(code) {
   // UTF-16 Decoding
-  if (code <= 0xFFFF) return String.fromCharCode(code);
+  if (code <= 0xFFFF) { return String.fromCharCode(code) }
   code -= 0x10000;
-  return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00);
+  return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
 }
 
-pp.readString = function (quote) {
-  var out = "",
-      chunkStart = ++this.pos;
+pp$8.readString = function(quote) {
+  var this$1 = this;
+
+  var out = "", chunkStart = ++this.pos;
   for (;;) {
-    if (this.pos >= this.input.length) this.raise(this.start, "Unterminated string constant");
-    var ch = this.input.charCodeAt(this.pos);
-    if (ch === quote) break;
-    if (ch === 92) {
-      // '\'
-      out += this.input.slice(chunkStart, this.pos);
-      out += this.readEscapedChar(false);
-      chunkStart = this.pos;
+    if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated string constant"); }
+    var ch = this$1.input.charCodeAt(this$1.pos);
+    if (ch === quote) { break }
+    if (ch === 92) { // '\'
+      out += this$1.input.slice(chunkStart, this$1.pos);
+      out += this$1.readEscapedChar(false);
+      chunkStart = this$1.pos;
     } else {
-      if (_whitespace.isNewLine(ch)) this.raise(this.start, "Unterminated string constant");
-      ++this.pos;
+      if (isNewLine(ch)) { this$1.raise(this$1.start, "Unterminated string constant"); }
+      ++this$1.pos;
     }
   }
   out += this.input.slice(chunkStart, this.pos++);
-  return this.finishToken(_tokentype.types.string, out);
+  return this.finishToken(types.string, out)
 };
 
 // Reads template string tokens.
 
-pp.readTmplToken = function () {
-  var out = "",
-      chunkStart = this.pos;
+var INVALID_TEMPLATE_ESCAPE_ERROR = {};
+
+pp$8.tryReadTemplateToken = function() {
+  this.inTemplateElement = true;
+  try {
+    this.readTmplToken();
+  } catch (err) {
+    if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
+      this.readInvalidTemplateToken();
+    } else {
+      throw err
+    }
+  }
+
+  this.inTemplateElement = false;
+};
+
+pp$8.invalidStringToken = function(position, message) {
+  if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
+    throw INVALID_TEMPLATE_ESCAPE_ERROR
+  } else {
+    this.raise(position, message);
+  }
+};
+
+pp$8.readTmplToken = function() {
+  var this$1 = this;
+
+  var out = "", chunkStart = this.pos;
   for (;;) {
-    if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
-    var ch = this.input.charCodeAt(this.pos);
-    if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
-      // '`', '${'
-      if (this.pos === this.start && this.type === _tokentype.types.template) {
+    if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated template"); }
+    var ch = this$1.input.charCodeAt(this$1.pos);
+    if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) { // '`', '${'
+      if (this$1.pos === this$1.start && (this$1.type === types.template || this$1.type === types.invalidTemplate)) {
         if (ch === 36) {
-          this.pos += 2;
-          return this.finishToken(_tokentype.types.dollarBraceL);
+          this$1.pos += 2;
+          return this$1.finishToken(types.dollarBraceL)
         } else {
-          ++this.pos;
-          return this.finishToken(_tokentype.types.backQuote);
+          ++this$1.pos;
+          return this$1.finishToken(types.backQuote)
         }
       }
-      out += this.input.slice(chunkStart, this.pos);
-      return this.finishToken(_tokentype.types.template, out);
-    }
-    if (ch === 92) {
-      // '\'
-      out += this.input.slice(chunkStart, this.pos);
-      out += this.readEscapedChar(true);
-      chunkStart = this.pos;
-    } else if (_whitespace.isNewLine(ch)) {
-      out += this.input.slice(chunkStart, this.pos);
-      ++this.pos;
+      out += this$1.input.slice(chunkStart, this$1.pos);
+      return this$1.finishToken(types.template, out)
+    }
+    if (ch === 92) { // '\'
+      out += this$1.input.slice(chunkStart, this$1.pos);
+      out += this$1.readEscapedChar(true);
+      chunkStart = this$1.pos;
+    } else if (isNewLine(ch)) {
+      out += this$1.input.slice(chunkStart, this$1.pos);
+      ++this$1.pos;
       switch (ch) {
-        case 13:
-          if (this.input.charCodeAt(this.pos) === 10) ++this.pos;
-        case 10:
-          out += "\n";
-          break;
-        default:
-          out += String.fromCharCode(ch);
-          break;
+      case 13:
+        if (this$1.input.charCodeAt(this$1.pos) === 10) { ++this$1.pos; }
+      case 10:
+        out += "\n";
+        break
+      default:
+        out += String.fromCharCode(ch);
+        break
+      }
+      if (this$1.options.locations) {
+        ++this$1.curLine;
+        this$1.lineStart = this$1.pos;
       }
-      if (this.options.locations) {
-        ++this.curLine;
-        this.lineStart = this.pos;
+      chunkStart = this$1.pos;
+    } else {
+      ++this$1.pos;
+    }
+  }
+};
+
+// Reads a template token to search for the end, without validating any escape sequences
+pp$8.readInvalidTemplateToken = function() {
+  var this$1 = this;
+
+  for (; this.pos < this.input.length; this.pos++) {
+    switch (this$1.input[this$1.pos]) {
+    case "\\":
+      ++this$1.pos;
+      break
+
+    case "$":
+      if (this$1.input[this$1.pos + 1] !== "{") {
+        break
       }
-      chunkStart = this.pos;
-    } else {
-      ++this.pos;
-    }
-  }
+    // falls through
+
+    case "`":
+      return this$1.finishToken(types.invalidTemplate, this$1.input.slice(this$1.start, this$1.pos))
+
+    // no default
+    }
+  }
+  this.raise(this.start, "Unterminated template");
 };
 
 // Used to read escaped characters
 
-pp.readEscapedChar = function (inTemplate) {
+pp$8.readEscapedChar = function(inTemplate) {
   var ch = this.input.charCodeAt(++this.pos);
   ++this.pos;
   switch (ch) {
-    case 110:
-      return "\n"; // 'n' -> '\n'
-    case 114:
-      return "\r"; // 'r' -> '\r'
-    case 120:
-      return String.fromCharCode(this.readHexChar(2)); // 'x'
-    case 117:
-      return codePointToString(this.readCodePoint()); // 'u'
-    case 116:
-      return "\t"; // 't' -> '\t'
-    case 98:
-      return "\b"; // 'b' -> '\b'
-    case 118:
-      return "\u000b"; // 'v' -> '\u000b'
-    case 102:
-      return "\f"; // 'f' -> '\f'
-    case 13:
-      if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
-    case 10:
-      // ' \n'
-      if (this.options.locations) {
-        this.lineStart = this.pos;++this.curLine;
+  case 110: return "\n" // 'n' -> '\n'
+  case 114: return "\r" // 'r' -> '\r'
+  case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
+  case 117: return codePointToString(this.readCodePoint()) // 'u'
+  case 116: return "\t" // 't' -> '\t'
+  case 98: return "\b" // 'b' -> '\b'
+  case 118: return "\u000b" // 'v' -> '\u000b'
+  case 102: return "\f" // 'f' -> '\f'
+  case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
+  case 10: // ' \n'
+    if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
+    return ""
+  default:
+    if (ch >= 48 && ch <= 55) {
+      var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
+      var octal = parseInt(octalStr, 8);
+      if (octal > 255) {
+        octalStr = octalStr.slice(0, -1);
+        octal = parseInt(octalStr, 8);
       }
-      return "";
-    default:
-      if (ch >= 48 && ch <= 55) {
-        var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
-        var octal = parseInt(octalStr, 8);
-        if (octal > 255) {
-          octalStr = octalStr.slice(0, -1);
-          octal = parseInt(octalStr, 8);
-        }
-        if (octal > 0 && (this.strict || inTemplate)) {
-          this.raise(this.pos - 2, "Octal literal in strict mode");
-        }
-        this.pos += octalStr.length - 1;
-        return String.fromCharCode(octal);
+      if (octalStr !== "0" && (this.strict || inTemplate)) {
+        this.invalidStringToken(this.pos - 2, "Octal literal in strict mode");
       }
-      return String.fromCharCode(ch);
+      this.pos += octalStr.length - 1;
+      return String.fromCharCode(octal)
+    }
+    return String.fromCharCode(ch)
   }
 };
 
 // Used to read character escape sequences ('\x', '\u', '\U').
 
-pp.readHexChar = function (len) {
+pp$8.readHexChar = function(len) {
   var codePos = this.pos;
   var n = this.readInt(16, len);
-  if (n === null) this.raise(codePos, "Bad character escape sequence");
-  return n;
+  if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
+  return n
 };
 
 // Read an identifier, and return it as a string. Sets `this.containsEsc`
 // to whether the word contained a '\u' escape.
 //
 // Incrementally adds only escaped chars, adding other chunks as-is
 // as a micro-optimization.
 
-pp.readWord1 = function () {
+pp$8.readWord1 = function() {
+  var this$1 = this;
+
   this.containsEsc = false;
-  var word = "",
-      first = true,
-      chunkStart = this.pos;
+  var word = "", first = true, chunkStart = this.pos;
   var astral = this.options.ecmaVersion >= 6;
   while (this.pos < this.input.length) {
-    var ch = this.fullCharCodeAtPos();
-    if (_identifier.isIdentifierChar(ch, astral)) {
-      this.pos += ch <= 0xffff ? 1 : 2;
-    } else if (ch === 92) {
-      // "\"
-      this.containsEsc = true;
-      word += this.input.slice(chunkStart, this.pos);
-      var escStart = this.pos;
-      if (this.input.charCodeAt(++this.pos) != 117) // "u"
-        this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX");
-      ++this.pos;
-      var esc = this.readCodePoint();
-      if (!(first ? _identifier.isIdentifierStart : _identifier.isIdentifierChar)(esc, astral)) this.raise(escStart, "Invalid Unicode escape");
+    var ch = this$1.fullCharCodeAtPos();
+    if (isIdentifierChar(ch, astral)) {
+      this$1.pos += ch <= 0xffff ? 1 : 2;
+    } else if (ch === 92) { // "\"
+      this$1.containsEsc = true;
+      word += this$1.input.slice(chunkStart, this$1.pos);
+      var escStart = this$1.pos;
+      if (this$1.input.charCodeAt(++this$1.pos) != 117) // "u"
+        { this$1.invalidStringToken(this$1.pos, "Expecting Unicode escape sequence \\uXXXX"); }
+      ++this$1.pos;
+      var esc = this$1.readCodePoint();
+      if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
+        { this$1.invalidStringToken(escStart, "Invalid Unicode escape"); }
       word += codePointToString(esc);
-      chunkStart = this.pos;
+      chunkStart = this$1.pos;
     } else {
-      break;
+      break
     }
     first = false;
   }
-  return word + this.input.slice(chunkStart, this.pos);
+  return word + this.input.slice(chunkStart, this.pos)
 };
 
 // Read an identifier or keyword token. Will check for reserved
 // words when necessary.
 
-pp.readWord = function () {
+pp$8.readWord = function() {
   var word = this.readWord1();
-  var type = _tokentype.types.name;
-  if ((this.options.ecmaVersion >= 6 || !this.containsEsc) && this.keywords.test(word)) type = _tokentype.keywords[word];
-  return this.finishToken(type, word);
-};
-
-},{"./identifier":2,"./locutil":5,"./state":10,"./tokentype":14,"./whitespace":16}],14:[function(_dereq_,module,exports){
-// ## Token types
-
-// The assignment of fine-grained, information-carrying type objects
-// allows the tokenizer to store the information it has about a
-// token in a way that is very cheap for the parser to look up.
-
-// All token type variables start with an underscore, to make them
-// easy to recognize.
-
-// The `beforeExpr` property is used to disambiguate between regular
-// expressions and divisions. It is set on all token types that can
-// be followed by an expression (thus, a slash after them would be a
-// regular expression).
+  var type = types.name;
+  if (this.keywords.test(word)) {
+    if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword " + word); }
+    type = keywords$1[word];
+  }
+  return this.finishToken(type, word)
+};
+
+// Acorn is a tiny, fast JavaScript parser written in JavaScript.
 //
-// The `startsExpr` property is used to check if the token ends a
-// `yield` expression. It is set on all token types that either can
-// directly start an expression (like a quotation mark) or can
-// continue an expression (like the body of a string).
+// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
+// various contributors and released under an MIT license.
+//
+// Git repositories for Acorn are available at
+//
+//     http://marijnhaverbeke.nl/git/acorn
+//     https://github.com/ternjs/acorn.git
 //
-// `isLoop` marks a keyword as starting a loop, which is important
-// to know when parsing a label, in order to allow or disallow
-// continue jumps to that label.
-
-"use strict";
-
-exports.__esModule = true;
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var TokenType = function TokenType(label) {
-  var conf = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
-  _classCallCheck(this, TokenType);
-
-  this.label = label;
-  this.keyword = conf.keyword;
-  this.beforeExpr = !!conf.beforeExpr;
-  this.startsExpr = !!conf.startsExpr;
-  this.isLoop = !!conf.isLoop;
-  this.isAssign = !!conf.isAssign;
-  this.prefix = !!conf.prefix;
-  this.postfix = !!conf.postfix;
-  this.binop = conf.binop || null;
-  this.updateContext = null;
-};
-
-exports.TokenType = TokenType;
-
-function binop(name, prec) {
-  return new TokenType(name, { beforeExpr: true, binop: prec });
+// Please use the [github bug tracker][ghbt] to report issues.
+//
+// [ghbt]: https://github.com/ternjs/acorn/issues
+//
+// This file defines the main parser interface. The library also comes
+// with a [error-tolerant parser][dammit] and an
+// [abstract syntax tree walker][walk], defined in other files.
+//
+// [dammit]: acorn_loose.js
+// [walk]: util/walk.js
+
+var version = "5.2.1";
+
+// The main exported interface (under `self.acorn` when in the
+// browser) is a `parse` function that takes a code string and
+// returns an abstract syntax tree as specified by [Mozilla parser
+// API][api].
+//
+// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
+
+function parse(input, options) {
+  return new Parser(options, input).parse()
 }
-var beforeExpr = { beforeExpr: true },
-    startsExpr = { startsExpr: true };
-
-var types = {
-  num: new TokenType("num", startsExpr),
-  regexp: new TokenType("regexp", startsExpr),
-  string: new TokenType("string", startsExpr),
-  name: new TokenType("name", startsExpr),
-  eof: new TokenType("eof"),
-
-  // Punctuation token types.
-  bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }),
-  bracketR: new TokenType("]"),
-  braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }),
-  braceR: new TokenType("}"),
-  parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }),
-  parenR: new TokenType(")"),
-  comma: new TokenType(",", beforeExpr),
-  semi: new TokenType(";", beforeExpr),
-  colon: new TokenType(":", beforeExpr),
-  dot: new TokenType("."),
-  question: new TokenType("?", beforeExpr),
-  arrow: new TokenType("=>", beforeExpr),
-  template: new TokenType("template"),
-  ellipsis: new TokenType("...", beforeExpr),
-  backQuote: new TokenType("`", startsExpr),
-  dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }),
-
-  // Operators. These carry several kinds of properties to help the
-  // parser use them properly (the presence of these properties is
-  // what categorizes them as operators).
-  //
-  // `binop`, when present, specifies that this operator is a binary
-  // operator, and will refer to its precedence.
-  //
-  // `prefix` and `postfix` mark the operator as a prefix or postfix
-  // unary operator.
-  //
-  // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
-  // binary operators with a very low precedence, that should result
-  // in AssignmentExpression nodes.
-
-  eq: new TokenType("=", { beforeExpr: true, isAssign: true }),
-  assign: new TokenType("_=", { beforeExpr: true, isAssign: true }),
-  incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }),
-  prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }),
-  logicalOR: binop("||", 1),
-  logicalAND: binop("&&", 2),
-  bitwiseOR: binop("|", 3),
-  bitwiseXOR: binop("^", 4),
-  bitwiseAND: binop("&", 5),
-  equality: binop("==/!=", 6),
-  relational: binop("</>", 7),
-  bitShift: binop("<</>>", 8),
-  plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }),
-  modulo: binop("%", 10),
-  star: binop("*", 10),
-  slash: binop("/", 10)
-};
-
-exports.types = types;
-// Map keyword names to token types.
-
-var keywords = {};
-
-exports.keywords = keywords;
-// Succinct definitions of keyword token types
-function kw(name) {
-  var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
-  options.keyword = name;
-  keywords[name] = types["_" + name] = new TokenType(name, options);
+
+// This function tries to parse a single expression at a given
+// offset in a string. Useful for parsing mixed-language formats
+// that embed JavaScript expressions.
+
+function parseExpressionAt(input, pos, options) {
+  var p = new Parser(options, input, pos);
+  p.nextToken();
+  return p.parseExpression()
+}
+
+// Acorn is organized as a tokenizer and a recursive-descent parser.
+// The `tokenizer` export provides an interface to the tokenizer.
+
+function tokenizer(input, options) {
+  return new Parser(options, input)
+}
+
+// This is a terrible kludge to support the existing, pre-ES6
+// interface where the loose parser module retroactively adds exports
+// to this module.
+ // eslint-disable-line camelcase
+function addLooseExports(parse, Parser$$1, plugins$$1) {
+  exports.parse_dammit = parse; // eslint-disable-line camelcase
+  exports.LooseParser = Parser$$1;
+  exports.pluginsLoose = plugins$$1;
 }
 
-kw("break");
-kw("case", beforeExpr);
-kw("catch");
-kw("continue");
-kw("debugger");
-kw("default", beforeExpr);
-kw("do", { isLoop: true, beforeExpr: true });
-kw("else", beforeExpr);
-kw("finally");
-kw("for", { isLoop: true });
-kw("function", startsExpr);
-kw("if");
-kw("return", beforeExpr);
-kw("switch");
-kw("throw", beforeExpr);
-kw("try");
-kw("var");
-kw("let");
-kw("const");
-kw("while", { isLoop: true });
-kw("with");
-kw("new", { beforeExpr: true, startsExpr: true });
-kw("this", startsExpr);
-kw("super", startsExpr);
-kw("class");
-kw("extends", beforeExpr);
-kw("export");
-kw("import");
-kw("yield", { beforeExpr: true, startsExpr: true });
-kw("null", startsExpr);
-kw("true", startsExpr);
-kw("false", startsExpr);
-kw("in", { beforeExpr: true, binop: 7 });
-kw("instanceof", { beforeExpr: true, binop: 7 });
-kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true });
-kw("void", { beforeExpr: true, prefix: true, startsExpr: true });
-kw("delete", { beforeExpr: true, prefix: true, startsExpr: true });
-
-},{}],15:[function(_dereq_,module,exports){
-"use strict";
-
-exports.__esModule = true;
-exports.isArray = isArray;
-exports.has = has;
-
-function isArray(obj) {
-  return Object.prototype.toString.call(obj) === "[object Array]";
-}
-
-// Checks if an object has a property.
-
-function has(obj, propName) {
-  return Object.prototype.hasOwnProperty.call(obj, propName);
-}
-
-},{}],16:[function(_dereq_,module,exports){
-// Matches a whole line break (where CRLF is considered a single
-// line break). Used to count lines.
-
-"use strict";
-
-exports.__esModule = true;
+exports.version = version;
+exports.parse = parse;
+exports.parseExpressionAt = parseExpressionAt;
+exports.tokenizer = tokenizer;
+exports.addLooseExports = addLooseExports;
+exports.Parser = Parser;
+exports.plugins = plugins;
+exports.defaultOptions = defaultOptions;
+exports.Position = Position;
+exports.SourceLocation = SourceLocation;
+exports.getLineInfo = getLineInfo;
+exports.Node = Node;
+exports.TokenType = TokenType;
+exports.tokTypes = types;
+exports.keywordTypes = keywords$1;
+exports.TokContext = TokContext;
+exports.tokContexts = types$1;
+exports.isIdentifierChar = isIdentifierChar;
+exports.isIdentifierStart = isIdentifierStart;
+exports.Token = Token;
 exports.isNewLine = isNewLine;
-var lineBreak = /\r\n?|\n|\u2028|\u2029/;
 exports.lineBreak = lineBreak;
-var lineBreakG = new RegExp(lineBreak.source, "g");
-
 exports.lineBreakG = lineBreakG;
-
-function isNewLine(code) {
-  return code === 10 || code === 13 || code === 0x2028 || code == 0x2029;
-}
-
-var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
 exports.nonASCIIwhitespace = nonASCIIwhitespace;
 
-},{}]},{},[3])(3)
-});
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
+
 
 /***/ }),
 
 /***/ 802:
 /***/ (function(module, exports, __webpack_require__) {
 
 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
 /*
--- a/devtools/client/debugger/new/search-worker.js
+++ b/devtools/client/debugger/new/search-worker.js
@@ -461,17 +461,17 @@ module.exports = __webpack_require__(163
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFileURL = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = undefined;
+exports.isLoading = exports.isLoaded = exports.getMode = exports.getSourceLineCount = exports.getSourcePath = exports.getFileURL = exports.getFilenameFromURL = exports.getFilename = exports.getRawSourceURL = exports.getPrettySourceURL = exports.shouldPrettyPrint = exports.isThirdParty = exports.isPretty = exports.isJavaScript = exports.isMinified = undefined;
 
 var _devtoolsSourceMap = __webpack_require__(1360);
 
 var _utils = __webpack_require__(1366);
 
 var _path = __webpack_require__(1393);
 
 var _url = __webpack_require__(334);
@@ -651,16 +651,72 @@ function getSourcePath(source) {
 function getSourceLineCount(source) {
   if (source.isWasm) {
     const { binary } = source.text;
     return binary.length;
   }
   return source.text != undefined ? source.text.split("\n").length : 0;
 }
 
+// Used to detect minification for automatic pretty printing
+const SAMPLE_SIZE = 50;
+const INDENT_COUNT_THRESHOLD = 5;
+const CHARACTER_LIMIT = 250;
+const _minifiedCache = new Map();
+
+/**
+ *
+ * Checks if a source is minified based on some heuristics
+ * @param key
+ * @param text
+ * @return boolean
+ * @memberof utils/source
+ * @static
+ */
+
+function isMinified(key, text) {
+  if (!key || !text) {
+    return false;
+  }
+
+  if (_minifiedCache.has(key)) {
+    return _minifiedCache.get(key);
+  }
+
+  let lineEndIndex = 0;
+  let lineStartIndex = 0;
+  let lines = 0;
+  let indentCount = 0;
+  let overCharLimit = false;
+
+  // Strip comments.
+  text = text.replace(/\/\*[\S\s]*?\*\/|\/\/(.+|\n)/g, "");
+
+  while (lines++ < SAMPLE_SIZE) {
+    lineEndIndex = text.indexOf("\n", lineStartIndex);
+    if (lineEndIndex == -1) {
+      break;
+    }
+    if (/^\s+/.test(text.slice(lineStartIndex, lineEndIndex))) {
+      indentCount++;
+    }
+    // For files with no indents but are not minified.
+    if (lineEndIndex - lineStartIndex > CHARACTER_LIMIT) {
+      overCharLimit = true;
+      break;
+    }
+    lineStartIndex = lineEndIndex + 1;
+  }
+
+  const minified = indentCount / lines * 100 < INDENT_COUNT_THRESHOLD || overCharLimit;
+
+  _minifiedCache.set(key, minified);
+  return minified;
+}
+
 /**
  *
  * Returns Code Mirror mode for source content type
  * @param contentType
  * @return String
  * @memberof utils/source
  * @static
  */
@@ -671,16 +727,27 @@ function getMode(source, sourceMetaData)
   if (!text || isWasm) {
     return { name: "text" };
   }
 
   if (url && url.match(/\.jsx$/i) || sourceMetaData && sourceMetaData.isReactComponent) {
     return "jsx";
   }
 
+  const languageMimeMap = [{ ext: ".c", mode: "text/x-csrc" }, { ext: ".kt", mode: "text/x-kotlin" }, { ext: ".cpp", mode: "text/x-c++src" }, { ext: ".m", mode: "text/x-objectivec" }, { ext: ".rs", mode: "text/x-rustsrc" }];
+
+  // check for C and other non JS languages
+  if (url) {
+    const result = languageMimeMap.find(({ ext }) => url.endsWith(ext));
+
+    if (result !== undefined) {
+      return result.mode;
+    }
+  }
+
   // 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.
@@ -710,30 +777,35 @@ function getMode(source, sourceMetaData)
   }
 
   return { name: "text" };
 }
 
 function isLoaded(source) {
   return source.loadedState === "loaded";
 }
-
+function isLoading(source) {
+  return source.loadedState === "loading";
+}
+
+exports.isMinified = isMinified;
 exports.isJavaScript = isJavaScript;
 exports.isPretty = isPretty;
 exports.isThirdParty = isThirdParty;
 exports.shouldPrettyPrint = shouldPrettyPrint;
 exports.getPrettySourceURL = getPrettySourceURL;
 exports.getRawSourceURL = getRawSourceURL;
 exports.getFilename = getFilename;
 exports.getFilenameFromURL = getFilenameFromURL;
 exports.getFileURL = getFileURL;
 exports.getSourcePath = getSourcePath;
 exports.getSourceLineCount = getSourceLineCount;
 exports.getMode = getMode;
 exports.isLoaded = isLoaded;
+exports.isLoading = isLoading;
 
 /***/ }),
 
 /***/ 1360:
 /***/ (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
--- a/devtools/client/debugger/new/test/mochitest/.eslintrc
+++ b/devtools/client/debugger/new/test/mochitest/.eslintrc
@@ -50,17 +50,17 @@
     "createDebuggerContext": false,
     "initDebugger": false,
     "invokeInTab": false,
     "findSource": false,
     "findElement": false,
     "findElementWithSelector": false,
     "findAllElements": false,
     "openNewTabAndToolbox": false,
-    "selectSource": false,
+    "selectLocation": false,
     "stepOver": false,
     "stepIn": false,
     "stepOut": false,
     "resume": false,
     "reload": false,
     "navigate": false,
     "removeBreakpoint": false,
     "addBreakpoint": false,
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -6,16 +6,20 @@ support-files =
   head.js
   !/devtools/client/commandline/test/helpers.js
   !/devtools/client/framework/test/shared-head.js
   examples/sourcemaps/bundle.js
   examples/sourcemaps/bundle.js.map
   examples/sourcemaps2/main.min.js
   examples/sourcemaps2/main.js
   examples/sourcemaps2/main.js.map
+  examples/sourcemaps3/bundle.js
+  examples/sourcemaps3/bundle.js.map
+  examples/sourcemaps3/sorted.js
+  examples/sourcemaps3/test.js
   examples/wasm-sourcemaps/average.js
   examples/wasm-sourcemaps/average.wasm
   examples/wasm-sourcemaps/average.wasm.map
   examples/wasm-sourcemaps/average.c
   examples/wasm-sourcemaps/utils.js
   examples/sum/sum.js
   examples/sum/sum.min.js
   examples/sum/sum.min.js.map
@@ -31,16 +35,17 @@ support-files =
   examples/doc-exceptions.html
   examples/doc-iframes.html
   examples/doc-frames.html
   examples/doc-debugger-statements.html
   examples/doc-minified.html
   examples/doc-minified2.html
   examples/doc-sourcemaps.html
   examples/doc-sourcemaps2.html
+  examples/doc-sourcemaps3.html
   examples/doc-sourcemap-bogus.html
   examples/doc-sources.html
   examples/doc-return-values.html
   examples/doc-wasm-sourcemaps.html
   examples/asm.js
   examples/async.js
   examples/bogus-map.js
   examples/entry.js
@@ -70,29 +75,31 @@ support-files =
 [browser_dbg-breakpoints-cond.js]
 [browser_dbg-browser-content-toolbox.js]
 skip-if = !e10s # This test is only valid in e10s
 [browser_dbg-call-stack.js]
 [browser_dbg-scopes.js]
 [browser_dbg-chrome-create.js]
 [browser_dbg-chrome-debugging.js]
 [browser_dbg-console.js]
+[browser_dbg-console-link.js]
 [browser_dbg-content-script-sources.js]
 [browser_dbg-debugger-buttons.js]
 [browser_dbg-editor-gutter.js]
 [browser_dbg-editor-select.js]
 [browser_dbg-editor-highlight.js]
 [browser_dbg-expressions.js]
 [browser_dbg-expressions-error.js]
 [browser_dbg-iframes.js]
 [browser_dbg_keyboard_navigation.js]
 skip-if = true # regular failures during release in Bug 1415300
 [browser_dbg_keyboard-shortcuts.js]
 skip-if = os == "linux" # bug 1351952
 [browser_dbg-layout-changes.js]
+[browser_dbg-outline.js]
 [browser_dbg-pause-exceptions.js]
 [browser_dbg-navigation.js]
 [browser_dbg-minified.js]
 [browser_dbg-pretty-print.js]
 [browser_dbg-pretty-print-console.js]
 [browser_dbg-pretty-print-paused.js]
 [browser_dbg-preview.js]
 skip-if = true # regular failures during release in Bug 1415300
@@ -101,16 +108,17 @@ skip-if = true # regular failures during
 [browser_dbg-search-file.js]
 skip-if = os == "win" # Bug 1393121
 [browser_dbg-quick-open.js]
 skip-if = true # regular failures during release in Bug 1415300
 [browser_dbg-search-project.js]
 [browser_dbg-sourcemaps.js]
 [browser_dbg-sourcemaps-reloading.js]
 [browser_dbg-sourcemaps2.js]
+[browser_dbg-sourcemaps3.js]
 [browser_dbg-sourcemaps-bogus.js]
 [browser_dbg-sources.js]
 [browser_dbg-tabs.js]
 [browser_dbg-toggling-tools.js]
 skip-if = true # Bug 1414124
 [browser_dbg-wasm-sourcemaps.js]
 skip-if = true # regular failures during release in Bug 1415300
 [browser_dbg-reload.js]
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breaking.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breaking.js
@@ -8,17 +8,17 @@ add_task(async function() {
   const { selectors: { getSelectedSource }, getState } = dbg;
 
   // Make sure we can set a top-level breakpoint and it will be hit on
   // reload.
   await addBreakpoint(dbg, "scripts.html", 18);
   reload(dbg);
   await waitForPaused(dbg);
 
-  await waitForLoadedSource(dbg, "doc-scripts.html");
+  await waitForSelectedSource(dbg, "doc-scripts.html");
   assertPausedLocation(dbg);
   await resume(dbg);
 
   // Create an eval script that pauses itself.
   invokeInTab("doEval");
   await waitForPaused(dbg);
 
   await resume(dbg);
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-console-link.js
@@ -0,0 +1,24 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests opening the console first, clicking a link
+// opens the editor at the correct location.
+
+async function waitForLink(toolbox) {
+  const { hud } = toolbox.getPanel("webconsole");
+
+  return waitFor(() => hud.ui.outputNode.querySelector(".frame-link-source"));
+}
+
+add_task(async function() {
+  const toolbox = await initPane("doc-script-switching.html", "webconsole");
+  const node = await waitForLink(toolbox);
+  node.click();
+
+  await waitFor(() => toolbox.getPanel("jsdebugger"));
+  const dbg = createDebuggerContext(toolbox);
+  await waitForElement(dbg, ".CodeMirror-code > .highlight-line");
+  assertHighlightLocation(dbg, "script-switching-02", 14);
+});
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-content-script-sources.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-content-script-sources.js
@@ -1,11 +1,8 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
 "use strict";
 
 /* global ExtensionTestUtils, closeTab, openToolboxForTab, assertDebugLine,
           waitForSelectedSource */
 
 // Tests that the content scripts are listed in the source tree.
 
 async function selectContentScriptSources(dbg) {
@@ -27,35 +24,35 @@ async function installAndStartExtension(
     // This listener prevents the source from being garbage collected
     // and be missing from the scripts returned by `dbg.findScripts()`
     // in `ThreadActor._discoverSources`.
     window.onload = () => {};
   }
 
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
-      "content_scripts": [
+      content_scripts: [
         {
-          "js": ["content_script.js"],
-          "matches": ["http://example.com/*"],
-          "run_at": "document_start",
-        },
-      ],
+          js: ["content_script.js"],
+          matches: ["http://example.com/*"],
+          run_at: "document_start"
+        }
+      ]
     },
     files: {
-      "content_script.js": contentScript,
-    },
+      "content_script.js": contentScript
+    }
   });
 
   await extension.startup();
 
   return extension;
 }
 
-add_task(async function () {
+add_task(async function() {
   const extension = await installAndStartExtension();
 
   let dbg = await initDebugger("doc-content-script-sources.html");
   await selectContentScriptSources(dbg);
   await closeTab(dbg, "content_script.js");
 
   // Destroy the toolbox and repeat the test in a new toolbox
   // and ensures that the content script is still listed.
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-outline.js
@@ -0,0 +1,30 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests that the editor highlights the correct location when the
+// debugger pauses
+
+function getItems(dbg) {
+  return findAllElements(dbg, "outlineItems");
+}
+
+function getNthItem(dbg, index) {
+  return findElement(dbg, "outlineItem", index);
+}
+
+add_task(async function() {
+  const dbg = await initDebugger("doc-scripts.html");
+  const { selectors: { getSelectedSource }, getState } = dbg;
+
+  await selectSource(dbg, "simple1", 1);
+  await waitForLoadedSource(dbg, "simple1");
+
+  findElementWithSelector(dbg, ".outline-tab").click();
+  is(getItems(dbg).length, 5, "5 items in the list");
+
+  // click on an element
+  const item = getNthItem(dbg, 3);
+  is(item.innerText, "evaledFunc()", "got evaled func");
+  item.click();
+  assertHighlightLocation(dbg, "simple1", 15);
+});
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-console.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-console.js
@@ -1,20 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Tests that pretty-printing updates console messages.
 
-async function waitFor(condition) {
-  await BrowserTestUtils.waitForCondition(condition, "waitFor", 10, 500);
-  return condition();
-}
-
 add_task(async function() {
   const dbg = await initDebugger("doc-minified.html");
   invokeInTab("arithmetic");
 
   info("Switch to console and check message");
   const toolbox = dbg.toolbox;
   const console = await toolbox.selectTool("webconsole");
   const hud = console.hud;
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps3.js
@@ -0,0 +1,86 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests loading sourcemapped sources, setting breakpoints, and
+// inspecting restored scopes.
+
+function toggleNode(dbg, index) {
+  clickElement(dbg, "scopeNode", index);
+}
+
+function getLabel(dbg, index) {
+  return findElement(dbg, "scopeNode", index).innerText;
+}
+
+function hasScopeNode(dbg, index) {
+  return !!findElement(dbg, "scopeNode", index);
+}
+
+async function waitForScopeNode(dbg, index) {
+  const selector = getSelector("scopeNode", index);
+  return waitForElement(dbg, selector);
+}
+
+// This source map does not have source contents, so it's fetched separately
+add_task(async function() {
+  // NOTE: the CORS call makes the test run times inconsistent
+  requestLongerTimeout(2);
+
+  const dbg = await initDebugger("doc-sourcemaps3.html");
+  const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
+
+  toggleScopes(dbg);
+
+  await waitForSources(dbg, "bundle.js", "sorted.js", "test.js");
+
+  ok(true, "Original sources exist");
+  const sortedSrc = findSource(dbg, "sorted.js");
+
+  await selectSource(dbg, sortedSrc);
+
+  // Test that breakpoint is not off by a line.
+  await addBreakpoint(dbg, sortedSrc, 9);
+  is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
+  ok(
+    getBreakpoint(getState(), { sourceId: sortedSrc.id, line: 9, column: 4 }),
+    "Breakpoint has correct line"
+  );
+
+  invokeInTab("test");
+
+  await waitForPaused(dbg);
+  assertPausedLocation(dbg);
+
+  await waitForDispatch(dbg, "MAP_SCOPES");
+
+  is(getLabel(dbg, 1), "Block");
+  is(getLabel(dbg, 2), "<this>");
+  is(getLabel(dbg, 3), "na");
+  is(getLabel(dbg, 4), "nb");
+
+  is(getLabel(dbg, 5), "Block");
+  is(
+    hasScopeNode(dbg, 8) && !hasScopeNode(dbg, 9),
+    true,
+    "scope count before expand"
+  );
+  toggleNode(dbg, 5);
+
+  await waitForScopeNode(dbg, 9);
+
+  is(getLabel(dbg, 6), "ma");
+  is(getLabel(dbg, 7), "mb");
+
+  is(
+    hasScopeNode(dbg, 10) && !hasScopeNode(dbg, 11),
+    true,
+    "scope count before expand"
+  );
+  toggleNode(dbg, 8);
+
+  await waitForScopeNode(dbg, 11);
+
+  is(getLabel(dbg, 9), "a");
+  is(getLabel(dbg, 10), "arguments");
+  is(getLabel(dbg, 11), "b");
+});
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js
@@ -1,34 +1,14 @@
-// Return a promise with a reference to jsterm, opening the split
-// console if necessary.  This cleans up the split console pref so
-// it won't pollute other tests.
-function getSplitConsole(dbg) {
-  const { toolbox, win } = dbg;
-
-  registerCleanupFunction(() => {
-    Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
-  });
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-  if (!win) {
-    win = toolbox.win;
-  }
-
-  if (!toolbox.splitConsole) {
-    pressKey(dbg, "Escape");
-  }
+"use strict";
 
-  return new Promise(resolve => {
-    toolbox.getPanelWhenReady("webconsole").then(() => {
-      ok(toolbox.splitConsole, "Split console is shown.");
-      let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
-      resolve(jsterm);
-    });
-  });
-}
+// Tests that you can switch tools, without losing your editor position
 
 add_task(async function() {
   const dbg = await initDebugger("doc-scripts.html");
 
   await selectSource(dbg, "long");
   dbg.win.cm.scrollTo(0, 284);
 
   pressKey(dbg, "inspector");
--- a/devtools/client/debugger/new/test/mochitest/examples/doc-content-script-sources.html
+++ b/devtools/client/debugger/new/test/mochitest/examples/doc-content-script-sources.html
@@ -4,9 +4,9 @@
 <html>
   <head>
     <meta charset="utf-8"/>
     <title>Debugger test page</title>
   </head>
 
   <body>
   </body>
-</html>
+
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/doc-sourcemaps3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8">
+  </head>
+
+<body>
+
+  <script type="text/javascript" src="sourcemaps3/bundle.js"></script>
+  <button onclick="test()">Test</button>
+</body>
+
+</html>
--- a/devtools/client/debugger/new/test/mochitest/examples/script-switching-02.js
+++ b/devtools/client/debugger/new/test/mochitest/examples/script-switching-02.js
@@ -6,8 +6,9 @@ function secondCall() {
   debugger;
   function foo() {}
   if (x) {
     foo();
   }
 }
 
 var x = true;
+console.log("hi")
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/.babelrc
@@ -0,0 +1,1 @@
+ { "presets": [ "es2015" ] }
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/.gitignore
@@ -0,0 +1,2 @@
+node_modules/
+package-lock.json
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/bundle.js
@@ -0,0 +1,2 @@
+!function(n){function e(t){if(r[t])return r[t].exports;var o=r[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var r={};e.m=n,e.c=r,e.d=function(n,r,t){e.o(n,r)||Object.defineProperty(n,r,{configurable:!1,enumerable:!0,get:t})},e.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(r,"a",r),r},e.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},e.p="",e(e.s=0)}([function(n,e,r){"use strict";var t=r(1);window.test=function(){var n=["b (30)","a","b (5)","z"],e=(0,t.fancySort)(n);console.log(e)}},function(n,e,r){"use strict";function t(n,e){var r=/.(\d+)\W*$/.exec(n),t=/.(\d+)\W*$/.exec(e);if(null==r||null==t||r[1]==t[1])return n<e?-1:n>e?1:0;var o=+r[1],u=+t[1];return o<u?-1:o>u?1:0}function o(n,e,r){if(0==n.length)return{found:!1,index:0};for(var t=0,o=n.length-1;t<o;){var u=Math.floor((t+o)/2);r(n[u],e)<0?t=u+1:o=u}var c=r(n[t],e);return 0===c?{found:!0,index:t}:{found:!1,index:c<0?t+1:t}}function u(n){return n.reduce(function(n,e){var r=o(n,e,t),u=r.index;return n.splice(u,0,e),n},[])}Object.defineProperty(e,"__esModule",{value:!0}),e.fancySort=u}]);
+//# sourceMappingURL=bundle.js.map
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/bundle.js.map
@@ -0,0 +1,1 @@
+{"version":3,"sources":["webpack:///bundle.js","webpack:///webpack/bootstrap 87d8b22c3e8e915d4367","webpack:///./test.js","webpack:///./sorted.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","_sorted","window","test","result","fancySort","console","log","comparer","a","b","ma","exec","mb","na","nb","binaryLookup","ar","length","found","index","r","mid","Math","floor","input","reduce","_binaryLookup","splice","value"],"mappings":"CAAS,SAAUA,GCInB,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAI,EAAAJ,EACAK,GAAA,EACAH,WAUA,OANAJ,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,GAGAI,EAAAE,GAAA,EAGAF,EAAAD,QAvBA,GAAAD,KA4BAF,GAAAQ,EAAAT,EAGAC,EAAAS,EAAAP,EAGAF,EAAAU,EAAA,SAAAP,EAAAQ,EAAAC,GACAZ,EAAAa,EAAAV,EAAAQ,IACAG,OAAAC,eAAAZ,EAAAQ,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAZ,EAAAmB,EAAA,SAAAf,GACA,GAAAQ,GAAAR,KAAAgB,WACA,WAA2B,MAAAhB,GAAA,SAC3B,WAAiC,MAAAA,GAEjC,OADAJ,GAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAQ,EAAAC,GAAsD,MAAAR,QAAAS,UAAAC,eAAAjB,KAAAc,EAAAC,IAGtDtB,EAAAyB,EAAA,GAGAzB,IAAA0B,EAAA,KDMM,SAAUtB,EAAQD,EAASH,GAEjC,YErEA,IAAA2B,GAAA3B,EAAA,EAEA4B,QAAOC,KAAO,WACZ,GAAIA,IAAQ,SAAU,IAAK,QAAS,KAChCC,GAAS,EAAAH,EAAAI,WAAUF,EACvBG,SAAQC,IAAIH,KF6ER,SAAU1B,EAAQD,EAASH,GAEjC,YGpFA,SAASkC,GAASC,EAAGC,GACnB,GAAMC,GAAK,aAAaC,KAAKH,GACvBI,EAAK,aAAaD,KAAKF,EAC7B,IAAU,MAANC,GAAoB,MAANE,GAAcF,EAAG,IAAME,EAAG,GAC1C,MAAOJ,GAAIC,GAAK,EAAID,EAAIC,EAAI,EAAI,CAEhC,IAAMI,IAAMH,EAAG,GACbI,GAAMF,EAAG,EACX,OAAOC,GAAKC,GAAM,EAAID,EAAKC,EAAK,EAAI,EAIxC,QAASC,GAAaC,EAAItC,EAAG6B,GAC3B,GAAiB,GAAbS,EAAGC,OACL,OAASC,OAAO,EAAOC,MAAO,EAIhC,KAFA,GAAIxC,GAAI,EACNyC,EAAIJ,EAAGC,OAAS,EACXtC,EAAIyC,GAAG,CACZ,GAAMC,GAAMC,KAAKC,OAAO5C,EAAIyC,GAAK,EAC7Bb,GAASS,EAAGK,GAAM3C,GAAK,EACzBC,EAAI0C,EAAM,EAEVD,EAAIC,EAGR,GAAMlB,GAASI,EAASS,EAAGrC,GAAID,EAC/B,OAAe,KAAXyB,GACOe,OAAO,EAAMC,MAAOxC,IAG7BuC,OAAO,EACPC,MAAOhB,EAAS,EAAIxB,EAAI,EAAIA,GAIzB,QAASyB,GAAUoB,GACxB,MAAOA,GAAMC,OAAO,SAACT,EAAItC,GAAM,GAAAgD,GACXX,EAAaC,EAAItC,EAAG6B,GAA9BY,EADqBO,EACrBP,KAER,OADAH,GAAGW,OAAOR,EAAO,EAAGzC,GACbsC,OH+CX7B,OAAOC,eAAeZ,EAAS,cAC7BoD,OAAO,IAETpD,EGtDgB4B","file":"bundle.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _sorted = __webpack_require__(1);\n\nwindow.test = function () {\n  var test = [\"b (30)\", \"a\", \"b (5)\", \"z\"];\n  var result = (0, _sorted.fancySort)(test);\n  console.log(result);\n};\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.fancySort = fancySort;\nfunction comparer(a, b) {\n  var ma = /.(\\d+)\\W*$/.exec(a);\n  var mb = /.(\\d+)\\W*$/.exec(b);\n  if (ma == null || mb == null || ma[1] == mb[1]) {\n    return a < b ? -1 : a > b ? 1 : 0;\n  } else {\n    var na = +ma[1],\n        nb = +mb[1];\n    return na < nb ? -1 : na > nb ? 1 : 0;\n  }\n}\n\nfunction binaryLookup(ar, i, comparer) {\n  if (ar.length == 0) {\n    return { found: false, index: 0 };\n  }\n  var l = 0,\n      r = ar.length - 1;\n  while (l < r) {\n    var mid = Math.floor((l + r) / 2);\n    if (comparer(ar[mid], i) < 0) {\n      l = mid + 1;\n    } else {\n      r = mid;\n    }\n  }\n  var result = comparer(ar[l], i);\n  if (result === 0) {\n    return { found: true, index: l };\n  }\n  return {\n    found: false,\n    index: result < 0 ? l + 1 : l\n  };\n}\n\nfunction fancySort(input) {\n  return input.reduce(function (ar, i) {\n    var _binaryLookup = binaryLookup(ar, i, comparer),\n        index = _binaryLookup.index;\n\n    ar.splice(index, 0, i);\n    return ar;\n  }, []);\n}\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// bundle.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 87d8b22c3e8e915d4367","import { fancySort } from \"./sorted.js\";\n\nwindow.test = function() {\n  let test = [\"b (30)\", \"a\", \"b (5)\", \"z\"];\n  let result = fancySort(test);\n  console.log(result);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./test.js","function comparer(a, b) {\n  const ma = /.(\\d+)\\W*$/.exec(a);\n  const mb = /.(\\d+)\\W*$/.exec(b);\n  if (ma == null || mb == null || ma[1] == mb[1]) {\n    return a < b ? -1 : a > b ? 1 : 0;\n  } else {\n    const na = +ma[1],\n      nb = +mb[1];\n    return na < nb ? -1 : na > nb ? 1 : 0;\n  }\n}\n\nfunction binaryLookup(ar, i, comparer) {\n  if (ar.length == 0) {\n    return { found: false, index: 0 };\n  }\n  let l = 0,\n    r = ar.length - 1;\n  while (l < r) {\n    const mid = Math.floor((l + r) / 2);\n    if (comparer(ar[mid], i) < 0) {\n      l = mid + 1;\n    } else {\n      r = mid;\n    }\n  }\n  const result = comparer(ar[l], i);\n  if (result === 0) {\n    return { found: true, index: l };\n  }\n  return {\n    found: false,\n    index: result < 0 ? l + 1 : l\n  };\n}\n\nexport function fancySort(input) {\n  return input.reduce((ar, i) => {\n    const { index } = binaryLookup(ar, i, comparer);\n    ar.splice(index, 0, i);\n    return ar;\n  }, []);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./sorted.js"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/package.json
@@ -0,0 +1,19 @@
+{
+  "name": "sorted-es6",
+  "version": "1.0.0",
+  "description": "",
+  "main": "sorted.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "dependencies": {},
+  "devDependencies": {
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-preset-es2015": "^6.24.1",
+    "webpack": "^3.7.1"
+  }
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/sorted.js
@@ -0,0 +1,43 @@
+function comparer(a, b) {
+  const ma = /.(\d+)\W*$/.exec(a);
+  const mb = /.(\d+)\W*$/.exec(b);
+  if (ma == null || mb == null || ma[1] == mb[1]) {
+    return a < b ? -1 : a > b ? 1 : 0;
+  } else {
+    const na = +ma[1],
+      nb = +mb[1];
+    return na < nb ? -1 : na > nb ? 1 : 0;
+  }
+}
+
+function binaryLookup(ar, i, comparer) {
+  if (ar.length == 0) {
+    return { found: false, index: 0 };
+  }
+  let l = 0,
+    r = ar.length - 1;
+  while (l < r) {
+    const mid = Math.floor((l + r) / 2);
+    if (comparer(ar[mid], i) < 0) {
+      l = mid + 1;
+    } else {
+      r = mid;
+    }
+  }
+  const result = comparer(ar[l], i);
+  if (result === 0) {
+    return { found: true, index: l };
+  }
+  return {
+    found: false,
+    index: result < 0 ? l + 1 : l
+  };
+}
+
+export function fancySort(input) {
+  return input.reduce((ar, i) => {
+    const { index } = binaryLookup(ar, i, comparer);
+    ar.splice(index, 0, i);
+    return ar;
+  }, []);
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/test.js
@@ -0,0 +1,7 @@
+import { fancySort } from "./sorted.js";
+
+window.test = function() {
+  let test = ["b (30)", "a", "b (5)", "z"];
+  let result = fancySort(test);
+  console.log(result);
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/test/mochitest/examples/sourcemaps3/webpack.config.js
@@ -0,0 +1,31 @@
+const path = require("path");
+const webpack = require("webpack");
+
+module.exports = {
+  entry: "./test.js",
+  output: {
+    path: __dirname,
+    filename: "bundle.js"
+  },
+  devtool: "sourcemap",
+  module: {
+    loaders: [
+      {
+        test: /\.js$/,
+        exclude: /node_modules/,
+        loader: "babel-loader"
+      }
+    ]
+  },
+  plugins: [
+    new webpack.optimize.UglifyJsPlugin({
+      compress: {
+        warnings: false
+      },
+      sourceMap: true,
+      output: {
+        comments: false
+      }
+    })
+  ]
+};
--- a/devtools/client/debugger/new/test/mochitest/head.js
+++ b/devtools/client/debugger/new/test/mochitest/head.js
@@ -59,16 +59,21 @@ function log(msg, data) {
 function logThreadEvents(dbg, event) {
   const thread = dbg.toolbox.threadClient;
 
   thread.addListener(event, function onEvent(eventName, ...args) {
     info(`Thread event '${eventName}' fired.`);
   });
 }
 
+async function waitFor(condition) {
+  await BrowserTestUtils.waitForCondition(condition, "waitFor", 10, 500);
+  return condition();
+}
+
 // Wait until an action of `type` is dispatched. This is different
 // then `_afterDispatchDone` because it doesn't wait for async actions
 // to be done/errored. Use this if you want to listen for the "start"
 // action of an async operation (somewhat rare).
 function waitForNextDispatch(store, type) {
   return new Promise(resolve => {
     store.dispatch({
       // Normally we would use `services.WAIT_UNTIL`, but use the
@@ -332,21 +337,26 @@ function assertDebugLine(dbg, line) {
  * @param {Number} line
  * @static
  */
 function assertHighlightLocation(dbg, source, line) {
   const { selectors: { getSelectedSource, getPause }, getState } = dbg;
   source = findSource(dbg, source);
 
   // Check the selected source
-  is(getSelectedSource(getState()).get("url"), source.url);
+  is(
+    getSelectedSource(getState()).get("url"),
+    source.url,
+    "source url is correct"
+  );
 
   // Check the highlight line
   const lineEl = findElement(dbg, "highlightLine");
   ok(lineEl, "Line is highlighted");
+
   ok(isVisibleInEditor(dbg, lineEl), "Highlighted line is visible");
   ok(
     getCM(dbg)
       .lineInfo(line - 1)
       .wrapClass.includes("highlight-line"),
     "Line is highlighted"
   );
 }
@@ -486,22 +496,25 @@ function clearDebuggerPreferences() {
 /**
  * Intilializes the debugger.
  *
  * @memberof mochitest
  * @param {String} url
  * @return {Promise} dbg
  * @static
  */
-function initDebugger(url) {
-  return Task.spawn(function*() {
-    clearDebuggerPreferences();
-    const toolbox = yield openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
-    return createDebuggerContext(toolbox);
-  });
+async function initDebugger(url) {
+  clearDebuggerPreferences();
+  const toolbox = await openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
+  return createDebuggerContext(toolbox);
+}
+
+async function initPane(url, pane) {
+  clearDebuggerPreferences();
+  return openNewTabAndToolbox(EXAMPLE_URL + url, pane);
 }
 
 window.resumeTest = undefined;
 /**
  * Pause the test and let you interact with the debugger.
  * The test can be resumed by invoking `resumeTest` in the console.
  *
  * @memberof mochitest
@@ -573,17 +586,17 @@ function waitForLoadedSources(dbg) {
  * @param {String} url
  * @param {Number} line
  * @return {Promise}
  * @static
  */
 function selectSource(dbg, url, line) {
   info(`Selecting source: ${url}`);
   const source = findSource(dbg, url);
-  return dbg.actions.selectSource(source.id, { location: { line } });
+  return dbg.actions.selectLocation({ sourceId: source.id, line });
 }
 
 function closeTab(dbg, url) {
   info(`Closing tab: ${url}`);
   const source = findSource(dbg, url);
   return dbg.actions.closeTab(source.url);
 }
 
@@ -928,17 +941,19 @@ const selectors = {
   sourcesFooter: ".sources-panel .source-footer",
   editorFooter: ".editor-pane .source-footer",
   sourceNode: i => `.sources-list .tree-node:nth-child(${i})`,
   sourceNodes: ".sources-list .tree-node",
   sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`,
   resultItems: ".result-list .result-item",
   fileMatch: ".managed-tree .result",
   popup: ".popover",
-  tooltip: ".tooltip"
+  tooltip: ".tooltip",
+  outlineItem: i => `.outline-list__element:nth-child(${i})`,
+  outlineItems: ".outline-list__element"
 };
 
 function getSelector(elementName, ...args) {
   let selector = selectors[elementName];
   if (!selector) {
     throw new Error(`The selector ${elementName} is not defined`);
   }
 
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -297,22 +297,24 @@ devtools.jar:
     skin/images/firebug/command-screenshot.svg (themes/images/firebug/command-screenshot.svg)
     skin/images/firebug/command-measure.svg (themes/images/firebug/command-measure.svg)
     skin/images/firebug/command-rulers.svg (themes/images/firebug/command-rulers.svg)
     skin/images/firebug/command-noautohide.svg (themes/images/firebug/command-noautohide.svg)
 
     # Debugger
     skin/images/debugger/arrow.svg (themes/images/debugger/arrow.svg)
     skin/images/debugger/blackBox.svg (themes/images/debugger/blackBox.svg)
+    skin/images/debugger/close.svg (themes/images/debugger/close.svg)
     skin/images/debugger/domain.svg (themes/images/debugger/domain.svg)
     skin/images/debugger/file.svg (themes/images/debugger/file.svg)
     skin/images/debugger/folder.svg (themes/images/debugger/folder.svg)
     skin/images/debugger/pause-exceptions.svg (themes/images/debugger/pause-exceptions.svg)
     skin/images/debugger/pause.svg (themes/images/debugger/pause.svg)
     skin/images/debugger/prettyPrint.svg (themes/images/debugger/prettyPrint.svg)
+    skin/images/debugger/react.svg (themes/images/debugger/react.svg)
     skin/images/debugger/resume.svg (themes/images/debugger/resume.svg)
     skin/images/debugger/stepIn.svg (themes/images/debugger/stepIn.svg)
     skin/images/debugger/stepOut.svg (themes/images/debugger/stepOut.svg)
     skin/images/debugger/stepOver.svg (themes/images/debugger/stepOver.svg)
 
     # Netmonitor
     content/netmonitor/src/assets/styles/httpi.css (netmonitor/src/assets/styles/httpi.css)
     content/netmonitor/src/assets/styles/MdnLink.css (netmonitor/src/assets/styles/MdnLink.css)
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -62,16 +62,32 @@ stepOverTooltip=Step over %S
 # LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the
 # button that steps into a function call.
 stepInTooltip=Step in %S
 
 # LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the
 # button that steps out of a function call.
 stepOutTooltip=Step out %S
 
+# LOCALIZATION NOTE (pauseButtonItem): The label that is displayed for the dropdown pause
+# list item when the debugger is in a running state.
+pauseButtonItem=Pause on Next Statement
+
+# LOCALIZATION NOTE (ignoreExceptionsItem): The pause on exceptions button description
+# when the debugger will not pause on exceptions.
+ignoreExceptionsItem=Ignore exceptions
+
+# LOCALIZATION NOTE (pauseOnUncaughtExceptionsItem): The pause on exceptions dropdown
+# item shown when a user is adding a new breakpoint.
+pauseOnUncaughtExceptionsItem=Pause on uncaught exceptions
+
+# LOCALIZATION NOTE (pauseOnExceptionsItem): The pause on exceptions button description
+# when the debugger will pause on all exceptions.
+pauseOnExceptionsItem=Pause on all exceptions
+
 # LOCALIZATION NOTE (workersHeader): The text to display in the events
 # header.
 workersHeader=Workers
 
 # LOCALIZATION NOTE (noWorkersText): The text to display in the workers list
 # when there are no workers.
 noWorkersText=This page has no workers.
 
@@ -410,17 +426,17 @@ framework.disableGrouping=Disable framew
 framework.disableGrouping.accesskey=u
 
 # LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the
 # context menu to enable framework grouping.
 framework.enableGrouping=Enable framework grouping
 framework.enableGrouping.accesskey=u
 
 # LOCALIZATION NOTE (generated): Source Map term for a server source location
-generated=Generated
+generated=generated
 
 # LOCALIZATION NOTE (original): Source Map term for a debugger UI source location
 original=original
 
 # LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression
 # input element
 expressions.placeholder=Add watch expression
 expressions.label=Add watch expression
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -39,8 +39,11 @@ pref("devtools.debugger.file-search-rege
 pref("devtools.debugger.features.async-stepping", true);
 
 pref("devtools.debugger.features.project-text-search", true);
 pref("devtools.debugger.features.wasm", true);
 pref("devtools.debugger.features.shortcuts", true);
 pref("devtools.debugger.project-directory-root", "");
 pref("devtools.debugger.features.root", false);
 pref("devtools.debugger.features.column-breakpoints", false);
+pref("devtools.debugger.features.map-scopes", true);
+pref("devtools.debugger.features.breakpoints-dropdown", false);
+pref("devtools.debugger.features.remove-command-bar-options", false);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/themes/images/debugger/close.svg
@@ -0,0 +1,7 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg width="16px" height="16px" viewBox="0 0 6 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <path d="M1.35191454,5.27895256 L5.31214367,1.35518468 C5.50830675,1.16082764 5.50977084,0.844248536 5.3154138,0.648085456 C5.12105677,0.451922377 4.80447766,0.450458288 4.60831458,0.644815324 L0.648085456,4.56858321 C0.451922377,4.76294025 0.450458288,5.07951935 0.644815324,5.27568243 C0.83917236,5.47184551 1.15575146,5.4733096 1.35191454,5.27895256 L1.35191454,5.27895256 Z" id="Line" stroke="none" fill="#696969" fill-rule="evenodd"></path>
+  <path d="M5.31214367,4.56858321 L1.35191454,0.644815324 C1.15575146,0.450458288 0.83917236,0.451922377 0.644815324,0.648085456 C0.450458288,0.844248536 0.451922377,1.16082764 0.648085456,1.35518468 L4.60831458,5.27895256 C4.80447766,5.4733096 5.12105677,5.47184551 5.3154138,5.27568243 C5.50977084,5.07951935 5.50830675,4.76294025 5.31214367,4.56858321 L5.31214367,4.56858321 Z" id="Line-Copy-2" stroke="none" fill="#696969" fill-rule="evenodd"></path>
+</svg>
new file mode 100644
--- /dev/null
+++ b/devtools/client/themes/images/debugger/react.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34" height="32" viewBox="0 0 34 32">
+<path fill="#444444" d="M19.314 15.987c0 1.321-1.071 2.392-2.392 2.392s-2.392-1.071-2.392-2.392c0-1.321 1.071-2.392 2.392-2.392s2.392 1.071 2.392 2.392z"></path>
+<path fill="#444444" d="M16.922 24.783c1.878 1.826 3.729 2.906 5.221 2.906 0.489 0 0.952-0.103 1.337-0.334 1.337-0.772 1.826-2.701 1.363-5.453-0.077-0.489-0.18-0.977-0.309-1.492 0.514-0.154 0.977-0.309 1.44-0.463 2.598-1.003 4.038-2.392 4.038-3.909 0-1.543-1.44-2.932-4.038-3.909-0.463-0.18-0.926-0.334-1.44-0.463 0.129-0.514 0.232-1.003 0.309-1.492 0.437-2.803-0.051-4.758-1.389-5.53-0.386-0.231-0.849-0.334-1.337-0.334-1.466 0-3.344 1.080-5.221 2.906-1.852-1.826-3.704-2.906-5.195-2.906-0.489 0-0.952 0.103-1.337 0.334-1.337 0.772-1.826 2.701-1.363 5.453 0.077 0.489 0.18 0.977 0.309 1.492-0.514 0.154-0.977 0.309-1.44 0.463-2.598 1.003-4.038 2.392-4.038 3.909 0 1.543 1.44 2.932 4.038 3.909 0.463 0.18 0.926 0.334 1.44 0.463-0.129 0.514-0.232 1.003-0.309 1.492-0.437 2.752 0.051 4.707 1.363 5.453 0.386 0.232 0.849 0.334 1.337 0.334 1.492 0.051 3.344-1.029 5.221-2.829v0zM15.481 21.311c0.463 0.026 0.952 0.026 1.44 0.026s0.977 0 1.44-0.026c-0.463 0.617-0.952 1.183-1.44 1.723-0.489-0.54-0.977-1.106-1.44-1.723zM12.292 18.662c0.257 0.437 0.489 0.849 0.772 1.26-0.797-0.103-1.543-0.232-2.263-0.386 0.232-0.694 0.489-1.415 0.797-2.135 0.206 0.411 0.437 0.849 0.694 1.26zM10.8 12.463c0.72-0.154 1.466-0.283 2.263-0.386-0.257 0.412-0.514 0.823-0.772 1.26s-0.489 0.849-0.694 1.286c-0.334-0.746-0.592-1.466-0.797-2.161zM12.215 15.987c0.334-0.694 0.694-1.389 1.106-2.083 0.386-0.669 0.823-1.337 1.26-2.006 0.772-0.051 1.543-0.077 2.341-0.077 0.823 0 1.595 0.026 2.341 0.077 0.463 0.669 0.874 1.337 1.26 2.006 0.412 0.694 0.772 1.389 1.106 2.083-0.334 0.694-0.694 1.389-1.106 2.083-0.386 0.669-0.823 1.337-1.26 2.006-0.772 0.051-1.543 0.077-2.341 0.077-0.823 0-1.595-0.026-2.341-0.077-0.463-0.669-0.874-1.337-1.26-2.006-0.412-0.695-0.772-1.389-1.106-2.083v0zM22.272 14.598l-0.694-1.286c-0.257-0.437-0.489-0.849-0.772-1.26 0.797 0.103 1.543 0.232 2.263 0.386-0.231 0.72-0.489 1.44-0.797 2.161v0zM22.272 17.376c0.309 0.72 0.566 1.44 0.797 2.135-0.72 0.154-1.466 0.283-2.263 0.386 0.257-0.412 0.514-0.823 0.772-1.26 0.232-0.386 0.463-0.823 0.694-1.26v0zM22.863 26.301c-0.206 0.129-0.463 0.18-0.746 0.18-1.26 0-2.829-1.029-4.372-2.572 0.746-0.797 1.466-1.698 2.186-2.701 1.209-0.103 2.366-0.283 3.447-0.54 0.129 0.463 0.206 0.926 0.283 1.389 0.36 2.186 0.077 3.755-0.797 4.244zM24.201 12.746c2.881 0.823 4.604 2.083 4.604 3.241 0 1.003-1.183 2.006-3.266 2.804-0.412 0.154-0.874 0.309-1.337 0.437-0.334-1.055-0.746-2.135-1.26-3.241 0.514-1.106 0.952-2.186 1.26-3.241v0zM22.143 5.493c0.283 0 0.514 0.051 0.746 0.18 0.849 0.489 1.157 2.032 0.797 4.244-0.077 0.437-0.18 0.9-0.283 1.389-1.080-0.232-2.238-0.412-3.447-0.54-0.694-1.003-1.44-1.903-2.186-2.701 1.543-1.518 3.112-2.572 4.372-2.572zM18.362 10.663c-0.463-0.026-0.952-0.026-1.44-0.026s-0.977 0-1.44 0.026c0.463-0.617 0.952-1.183 1.44-1.723 0.489 0.54 0.977 1.132 1.44 1.723v0zM10.98 5.673c0.206-0.129 0.463-0.18 0.746-0.18 1.26 0 2.829 1.029 4.372 2.572-0.746 0.797-1.466 1.697-2.186 2.701-1.209 0.103-2.366 0.283-3.447 0.54-0.129-0.463-0.206-0.926-0.283-1.389-0.36-2.186-0.077-3.729 0.797-4.244v0zM9.643 19.228c-2.881-0.823-4.604-2.083-4.604-3.241 0-1.003 1.183-2.006 3.266-2.803 0.412-0.154 0.874-0.309 1.337-0.437 0.334 1.055 0.746 2.135 1.26 3.241-0.514 1.106-0.952 2.212-1.26 3.241zM10.183 22.057c0.077-0.437 0.18-0.9 0.283-1.389 1.080 0.232 2.238 0.412 3.447 0.54 0.694 1.003 1.44 1.903 2.186 2.701-1.543 1.517-3.112 2.572-4.372 2.572-0.283 0-0.514-0.051-0.746-0.18-0.875-0.489-1.157-2.058-0.797-4.244z"></path>
+</svg>